Skip to content

Commit

Permalink
fix sort implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
0x8890 committed Aug 20, 2015
1 parent 257255a commit 9a1f30c
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 41 deletions.
4 changes: 4 additions & 0 deletions doc/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog


##### 1.1.1 (2015-08-20)
- Fix: sorting implementation in built-in adapters.


##### 1.1.0 (2015-08-20)
- Feature: pass request meta-data to adapters. Thanks [@avens19](https://github.com/avens19)!
- Revert: do run `prepublish` on install.
Expand Down
34 changes: 21 additions & 13 deletions lib/adapter/adapters/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ export function applyOptions (count, fields, records, options) {
}
}

for (let field in options.sort)
records = records.sort(sortByField.bind(null,
fields[field], field, options.sort[field]))
if ('sort' in options)
records = records.sort(compare.bind(null, fields, options.sort))

if ('limit' in options || 'offset' in options)
records = records.slice(options.offset,
Expand Down Expand Up @@ -80,28 +79,37 @@ function matchByField (fields, match, record) {

const comparisons = new WeakMap([
[ Number, (a, b) => a - b ],
[ String, (a, b) => a.charCodeAt(0) - b.charCodeAt(0) ],
[ String, (a, b) => a < b ? -1 : a > b ? 1 : 0 ],
[ Boolean, (a, b) => a === b ? 0 : a ? 1 : -1 ],
[ Date, (a, b) => a.getTime() - b.getTime() ],
[ Buffer, (a, b) => a.length - b.length ],
[ Object, (a, b) => Object.keys(a).length - Object.keys(b).length ]
])


function sortByField (fieldDefinition, field, isAscending, a, b) {
[ a, b ] = [ a[field], b[field] ]
function compare (fields, sort, x, y) {
for (let field in sort) {
const a = x[field]
const b = y[field]
const isAscending = sort[field]
const fieldDefinition = fields[field]
const fieldIsArray = fieldDefinition[keys.isArray]
const fieldType = fieldDefinition[keys.type]

if (a === null || b === null) return 0
if (a === null) return isAscending ? -1 : 1
if (b === null) return isAscending ? 1 : -1

let result = 0
let result = 0

if (fieldDefinition[keys.isArray])
result = a.length - b.length
if (fieldIsArray) result = a.length - b.length
else if (fieldType) result = comparisons.get(fieldType)(a, b)

else if (keys.type in fieldDefinition)
result = comparisons.get(fieldDefinition[keys.type])(a, b)
if (result === 0) continue

return isAscending ? result : -result
return isAscending ? result : -result
}

return 0
}


Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "fortune",
"description": "High-level I/O for web applications.",
"version": "1.1.0",
"version": "1.1.1",
"license": "MIT",
"author": {
"email": "[email protected]",
Expand Down Expand Up @@ -33,7 +33,7 @@
"dependencies": {
"array-buffer": "^1.0.2",
"babel-runtime": "^5.8.20",
"chalk": "^1.1.0",
"chalk": "^1.1.1",
"clone": "^1.0.2",
"deep-equal": "^1.0.0",
"error-class": "^1.0.5",
Expand All @@ -44,11 +44,11 @@
},
"devDependencies": {
"babel": "^5.8.21",
"babelify": "^6.1.3",
"babelify": "^6.2.0",
"browserify": "^11.0.1",
"cssnext": "^1.8.3",
"docchi": "^0.10.5",
"eslint": "^1.1.0",
"docchi": "^0.11.0",
"eslint": "^1.2.0",
"highlight.js": "^8.7.0",
"html-minifier": "^0.7.2",
"http-server": "^0.8.0",
Expand Down
41 changes: 18 additions & 23 deletions test/unit/adapter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { fail, comment, run } from 'tapdance'
import Adapter from '../../lib/adapter'
import * as arrayProxy from '../../lib/common/array_proxy'
import { find, includes } from '../../lib/common/array_proxy'
import * as keys from '../../lib/common/keys'
import * as errors from '../../lib/common/errors'
import * as stderr from '../stderr'
Expand Down Expand Up @@ -78,7 +78,7 @@ export default function () {
'number type is correct')
deepEqual(records[0].junk, { things: [ 'a', 'b', 'c' ] },
'object value is correct')
ok(!arrayProxy.includes(Object.keys(records[0],
ok(!includes(Object.keys(records[0],
'__user_nemesis_inverse')), 'denormalized fields not enumerable')
}))
})
Expand Down Expand Up @@ -149,19 +149,19 @@ export default function () {
})

run(() => {
comment('find: limit')
comment('find: sort combination')
return test(adapter =>
adapter.find(type, null, { limit: 1, sort: { name: true } })
adapter.find(type, null, { sort: { age: true, name: true } })
.then(records => {
equal(records[0].name, 'bob', 'record is correct')
equal(records.length, 1, 'limit length is correct')
deepEqual(records.map(record => record.age), [ 36, 42 ],
'sort order is correct')
}))
})

run(() => {
comment('find: offset')
comment('find: offset + limit')
return test(adapter =>
adapter.find(type, null, { offset: 1, sort: { name: true } })
adapter.find(type, null, { offset: 1, limit: 1, sort: { name: true } })
.then(records => {
equal(records[0].name, 'john', 'record is correct')
equal(records.length, 1, 'offset length is correct')
Expand Down Expand Up @@ -245,6 +245,11 @@ export default function () {
id = records[0][keys.primary]
testIds(records, 'id type is correct')

equal(records[0].picture, null,
'missing singular value is null')
deepEqual(records[0].nicknames, [],
'missing array value is empty array')

return adapter.find(type, [ id ])
})
.then(records => {
Expand Down Expand Up @@ -289,7 +294,7 @@ export default function () {
return adapter.find(type)
})
.then(records => {
deepEqual(arrayProxy.find(records, record =>
deepEqual(find(records, record =>
record[keys.primary] === 2).nicknames, [ 'pepe' ], 'array updated')
equal(records.filter(record => record.name !== 'billy').length,
0, 'field updated on set')
Expand Down Expand Up @@ -326,7 +331,7 @@ export default function () {
})
.then(records => {
equal(records.filter(record =>
arrayProxy.includes(record.friends, 5)).length,
includes(record.friends, 5)).length,
records.length, 'value pushed')
}))
})
Expand Down Expand Up @@ -387,17 +392,7 @@ function runTest (a, options = {}, fn) {
return adapter.connect()
.then(() => adapter.delete(type))
.then(() => adapter.create(type, records))
.then(r => {
equal(r.length, records.length,
'number created is correct')
equal(
arrayProxy.find(r, record => record[keys.primary] === 1).picture, null,
'missing singular value is null')
deepEqual(
arrayProxy.find(r, record => record[keys.primary] === 1).nicknames, [],
'missing array value is empty array')
return fn(adapter)
})
.then(() => fn(adapter))
.then(() => adapter.delete(type,
records.map(record => record[keys.primary])))
.then(() => adapter.disconnect())
Expand All @@ -410,7 +405,7 @@ function runTest (a, options = {}, fn) {


function testIds (records, message) {
equal(arrayProxy.find(records.map(record =>
arrayProxy.includes([ 'string', 'number' ], typeof record[keys.primary])),
equal(find(records.map(record =>
includes([ 'string', 'number' ], typeof record[keys.primary])),
b => !b), undefined, message)
}

0 comments on commit 9a1f30c

Please sign in to comment.