Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Mode compatible with Node.js

Added travis CI integration
  • Loading branch information...
commit 915aaeb229178c4fa3cf527d26a935db0e3a1a1e 1 parent d94b14f
@davidgtonge authored
View
3  .npmignore
@@ -0,0 +1,3 @@
+.idea/
+.git/
+node_modules/
View
3  .travis.yml
@@ -0,0 +1,3 @@
+language: node_js
+node_js:
+ - 0.6
View
8 Cakefile
@@ -24,4 +24,10 @@ task 'uglify', 'Minify and obfuscate', ->
ast = pro.ast_squeeze ast # get an AST with compression optimizations
final_code = pro.gen_code ast # compressed code here
- fs.writeFile 'js/backbone-query.min.js', final_code
+ fs.writeFile 'js/backbone-query.min.js', final_code
+
+task "test", "Test the code", ->
+ path = require 'path'
+ reporter = require('nodeunit').reporters.default
+
+ reporter.run ["test/backbone-query-test.js"]
View
33 js/backbone-query.js
@@ -6,7 +6,7 @@ May be freely distributed according to MIT license.
*/
(function() {
- var and_iterator, array_intersection, get_cache, get_models, get_sorted_models, iterator, or_iterator, page_models, parse_query, process_query, sort_models, test_attr, test_query_value,
+ var array_intersection, get_cache, get_models, get_sorted_models, iterator, page_models, parse_query, process_query, sort_models, test_attr, test_query_value,
__indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
array_intersection = function(arrays) {
@@ -88,10 +88,10 @@ May be freely distributed according to MIT license.
}
};
- iterator = function(collection, query, andOr) {
+ iterator = function(collection, query, andOr, filterReject) {
var parsed_query;
parsed_query = parse_query(query);
- return collection.filter(function(model) {
+ return collection[filterReject](function(model) {
var attr, q, test, _i, _len;
for (_i = 0, _len = parsed_query.length; _i < _len; _i++) {
q = parsed_query[_i];
@@ -149,26 +149,18 @@ May be freely distributed according to MIT license.
});
};
- and_iterator = function(collection, query) {
- return iterator(collection, query, false);
- };
-
- or_iterator = function(collection, query) {
- return iterator(collection, query, true);
- };
-
process_query = {
$and: function(collection, query) {
- return and_iterator(collection, query);
+ return iterator(collection, query, false, "filter");
},
$or: function(collection, query) {
- return or_iterator(collection, query);
+ return iterator(collection, query, true, "filter");
},
$nor: function(collection, query) {
- return _.difference(collection.models, or_iterator(collection, query));
+ return iterator(collection, query, true, "reject");
},
$not: function(collection, query) {
- return _.difference(collection.models, and_iterator(collection, query));
+ return iterator(collection, query, false, "reject");
}
};
@@ -244,6 +236,13 @@ May be freely distributed according to MIT license.
return sliced_models;
};
+ if (typeof require !== 'undefined') {
+ if (typeof _ === "undefined" || _ === null) _ = require('underscore');
+ if (typeof Backbone === "undefined" || Backbone === null) {
+ Backbone = require('backbone');
+ }
+ }
+
Backbone.QueryCollection = Backbone.Collection.extend({
query: function(query, options) {
var models;
@@ -261,4 +260,8 @@ May be freely distributed according to MIT license.
}
});
+ if (typeof exports !== "undefined") {
+ exports.QueryCollection = Backbone.QueryCollection;
+ }
+
}).call(this);
View
22 package.json
@@ -0,0 +1,22 @@
+{
+ "name": "backbone-query"
+ , "description": "Lightweight Query API for Backbone Collections"
+ , "version": "0.1.1"
+ , "author": "Dave Tonge <dave@simplecreativity.co.uk> (https://github.com/davidgtonge)"
+ , "tags": ["backbone", "underscore", "mongo", "query"]
+ , "main": "./js/backbone-query"
+ , "repository": {
+ "type": "git"
+ , "url": "https://davidgtonge@github.com/davidgtonge/backbone_query.git"
+ }
+ , "dependencies": {
+ "backbone": ">=0.5.x"
+ , "underscore": ">=1.1.x"
+}
+ , "devDependencies": {
+ "qunit": "0.1.x"
+}
+ , "scripts": {
+ "test": "cake test"
+}
+}
View
50 src/backbone-query.coffee
@@ -40,27 +40,27 @@ parse_query = (raw_query) ->
# Tests query value, to ensure that it is of the correct type
test_query_value = (type, value) ->
switch type
- when "$in","$nin","$all", "$any" then _(value).isArray()
- when "$size" then _(value).isNumber()
- when "$regex" then _(value).isRegExp()
- when "$like" then _(value).isString()
- when "$between" then _(value).isArray() and (value.length is 2)
- when "$cb" then _(value).isFunction()
+ when "$in","$nin","$all", "$any" then _(value).isArray()
+ when "$size" then _(value).isNumber()
+ when "$regex" then _(value).isRegExp()
+ when "$like" then _(value).isString()
+ when "$between" then _(value).isArray() and (value.length is 2)
+ when "$cb" then _(value).isFunction()
else true
test_attr = (type, value) ->
switch type
- when "$like", "$regex" then _(value).isString()
- when "$contains", "$all", "$any" then _(value).isArray()
- when "$size" then _(value).isArray() or _(value).isString()
- when "$in", "$nin" then value?
+ when "$like", "$regex" then _(value).isString()
+ when "$contains", "$all", "$any" then _(value).isArray()
+ when "$size" then _(value).isArray() or _(value).isString()
+ when "$in", "$nin" then value?
else true
# The main iterator that actually applies the query
-iterator = (collection, query, andOr) ->
+iterator = (collection, query, andOr, filterReject) ->
parsed_query = parse_query query
- # The collections filter method is used to iterate through each model in the collection
- collection.filter (model) ->
+ # The collections filter or reject method is used to iterate through each model in the collection
+ collection[filterReject] (model) ->
# For each model in the collection, iterate through the supplied queries
for q in parsed_query
# Retrieve the attribute value from the model
@@ -94,15 +94,13 @@ iterator = (collection, query, andOr) ->
# For an "and" query, if all the queries are true, then we return true
not andOr
-and_iterator = (collection, query) -> iterator collection, query, false
-or_iterator = (collection, query) -> iterator collection, query, true
# A object with or, and, nor and not methods
process_query =
- $and: (collection, query) -> and_iterator collection, query
- $or: (collection, query) -> or_iterator collection, query
- $nor: (collection, query) -> _.difference collection.models, (or_iterator collection, query)
- $not: (collection, query) -> _.difference collection.models, (and_iterator collection, query)
+ $and: (collection, query) -> iterator collection, query, false, "filter"
+ $or: (collection, query) -> iterator collection, query, true, "filter"
+ $nor: (collection, query) -> iterator collection, query, true, "reject"
+ $not: (collection, query) -> iterator collection, query, false, "reject"
get_cache = (collection, query, options) ->
# Convert the query to a string to use as a key in the cache
@@ -123,7 +121,7 @@ get_models = (collection, query) ->
# Iterate through the query keys to check for any of the compound methods
compound_query = _(query).chain().keys().intersection(["$or", "$and", "$nor", "$not"]).value()
- (switch compound_query.length
+ switch compound_query.length
# If no compound methods are found then use the "and" iterator
when 0 then process_query.$and collection, query
@@ -138,7 +136,7 @@ get_models = (collection, query) ->
process_query[type] collection, query[type])
# A modified form of Underscores Intersection is used to find the models that appear in all the result sets
- array_intersection results)
+ array_intersection results
# Gets the results and optionally sorts them
get_sorted_models = (collection, query, options) ->
@@ -179,8 +177,9 @@ page_models = (models, options) ->
sliced_models
-
-
+unless typeof require is 'undefined'
+ _ ?= require 'underscore'
+ Backbone ?= require 'backbone'
Backbone.QueryCollection = Backbone.Collection.extend
@@ -201,4 +200,7 @@ Backbone.QueryCollection = Backbone.Collection.extend
# Helper method to reset the query cache
# Defined as a separate method to make it easy to bind to collection's change/add/remove events
- reset_query_cache: -> @_query_cache = {}
+ reset_query_cache: -> @_query_cache = {}
+
+unless typeof exports is "undefined"
+ exports.QueryCollection = Backbone.QueryCollection
View
20 test/backbone-query-test.coffee
@@ -1,7 +1,23 @@
-module "Backbone Query"
+if typeof require isnt "undefined"
+ {QueryCollection} = require "../js/backbone-query.js"
+else
+ QueryCollection = Backbone.QueryCollection
+
+# Helper functions that turn Qunit tests into nodeunit tests
+equals = []
+
+test ?= (name, test_cb) ->
+ exports[name] = (testObj) ->
+ equals = []
+ test_cb()
+ for result in equals
+ testObj.equal result[0], result[1]
+ testObj.done()
+
+equal ?= (real, expected) -> equals.push [real, expected]
create = ->
- new Backbone.QueryCollection [
+ new QueryCollection [
{title:"Home", colors:["red","yellow","blue"], likes:12, featured:true, content: "Dummy content about coffeescript"}
{title:"About", colors:["red"], likes:2, featured:true, content: "dummy content about javascript"}
{title:"Contact", colors:["red","blue"], likes:20, content: "Dummy content about PHP"}
View
35 test/backbone-query-test.js
@@ -1,10 +1,37 @@
(function() {
- var create;
-
- module("Backbone Query");
+ var QueryCollection, create, equals;
+
+ if (typeof require !== "undefined") {
+ QueryCollection = require("../js/backbone-query.js").QueryCollection;
+ } else {
+ QueryCollection = Backbone.QueryCollection;
+ }
+
+ equals = [];
+
+ if (typeof test === "undefined" || test === null) {
+ test = function(name, test_cb) {
+ return exports[name] = function(testObj) {
+ var result, _i, _len;
+ test_cb();
+ for (_i = 0, _len = equals.length; _i < _len; _i++) {
+ result = equals[_i];
+ testObj.equal(result[0], result[1]);
+ }
+ equals = [];
+ return testObj.done();
+ };
+ };
+ }
+
+ if (typeof equal === "undefined" || equal === null) {
+ equal = function(real, expected) {
+ return equals.push([real, expected]);
+ };
+ }
create = function() {
- return new Backbone.QueryCollection([
+ return new QueryCollection([
{
title: "Home",
colors: ["red", "yellow", "blue"],
View
2  test/index.html
@@ -11,7 +11,7 @@
<script src="../js/backbone-query.js"></script>
</head>
<body>
- <h1 id="qunit-header">backbone-forms tests</h1>
+ <h1 id="qunit-header">backbone-query tests</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
Please sign in to comment.
Something went wrong with that request. Please try again.