<repo_name>mytourbook/mytourbook-dojo-toolkit<file_sep>/rql/test/js-array.js
var assert = require("assert"),
	Query = require("../query").Query,
    executeQuery = require("../js-array").executeQuery;

var data = [
	{
		"with/slash": "slashed",
		"nested": {
			"property": "value"
		},
		"price": 10,
		"name": "ten",
		"tags": ["fun", "even"]
	},
	{
		"price": 5,
		"name": "five",
		"tags": ["fun"]
	}];

exports.testFiltering = function() {
	assert.equal(executeQuery("price=lt=10", {}, data).length, 1); 
	assert.equal(executeQuery("price=lt=11", {}, data).length, 2); 
	assert.equal(executeQuery("nested/property=value", {}, data).length, 1); 
	assert.equal(executeQuery("with%2Fslash=slashed", {}, data).length, 1); 
	assert.equal(executeQuery("out(price,(5,10))", {}, data).length, 0); 
	assert.equal(executeQuery("out(price,(5))", {}, data).length, 1); 
	assert.equal(executeQuery("contains(tags,even)", {}, data).length, 1); 
	assert.equal(executeQuery("contains(tags,fun)", {}, data).length, 2); 
	assert.equal(executeQuery("excludes(tags,fun)", {}, data).length, 0); 
	assert.equal(executeQuery("excludes(tags,ne(fun))", {}, data).length, 1); 
	assert.equal(executeQuery("excludes(tags,ne(even))", {}, data).length, 0); 
	// eq() on re: should trigger .match()
	assert.deepEqual(executeQuery("price=match=10", {}, data), [data[0]]);
	// ne() on re: should trigger .not(.match())
	assert.deepEqual(executeQuery("name=match=f.*", {}, data), [data[1]]);
	assert.deepEqual(executeQuery("name=match=glob:f*", {}, data), [data[1]]);
};

exports.testFiltering1 = function() {
	var data = [{"path.1":[1,2,3]}, {"path.1":[9,3,7]}];
	assert.deepEqual(executeQuery("contains(path,3)&sort()", {}, data), []); // path is undefined
	assert.deepEqual(executeQuery("contains(path.1,3)&sort()", {}, data), data); // 3 found in both
	assert.deepEqual(executeQuery("excludes(path.1,3)&sort()", {}, data), []); // 3 found in both
	assert.deepEqual(executeQuery("excludes(path.1,7)&sort()", {}, data), [data[0]]); // 7 found in second
};

if (require.main === module)
    require("patr/runner").run(exports);
<file_sep>/rql/test/query.js
var assert = require("assert"),
    Query = require("../query").Query,
    parseQuery = require("../parser").parseQuery;
exports.testJSArray = require("./js-array");

exports.testBehavior = function() {
    //assert.error(parseQuery(), "parseQuery requires a string");
    assert.ok(parseQuery("") instanceof Query, "should inherit from Query");
    assert.ok(parseQuery("a=b") instanceof Query, "should inherit from Query");
    //assert.error(parseQuery("?a=b"), "cannot begin with a ?");
};

var queryPairs = {
    "arrays": [
        {"a": {name:"and", args:["a"]}},
        {"(a)": {name:"and", args:[["a"]]}},
        {"a,b,c": {name:"and", args:["a", "b", "c"]}},
        {"(a,b,c)": {name:"and", args:[["a", "b", "c"]]}},
        {"a(b)": {name:"and","args":[{"name":"a","args":["b"]}]}},
        {"a(b,c)": {name:"and", args:[{name:"a", args:["b", "c"]}]}},
        {"a((b),c)": {"name": "and", args:[{name:"a", args:[["b"], "c"]}]}},
        {"a((b,c),d)": {name:"and", args:[{name:"a", args:[["b", "c"], "d"]}]}},
        {"a(b/c,d)": {name:"and", args:[{name:"a", args:[["b", "c"], "d"]}]}},
        {"a(b)&c(d(e))": {name:"and", args:[
            {name:"a", args:["b"]},
            {name:"c", args:[{name:"d", args:["e"]}]}
        ]}}
    ],
    "dot-comparison": [
    	{"foo.bar=3": {name:"and", args:[{name:"eq", args:["foo.bar",3]}]}},
    	{"select(sub.name)": {name:"and", args:[{name:"select", args:["sub.name"]}], cache: {select: ["sub.name"]}}}
    ],
    "equality": [
        {"eq(a,b)": {name:"and", args:[{name:"eq", args:["a","b"]}]}},
        {"a=eq=b": "eq(a,b)"},
        {"a=b": "eq(a,b)"}
    ],
    "inequality": [
        {"ne(a,b)": {name:"and", args:[{name:"ne", args:["a", "b"]}]}},
        {"a=ne=b": "ne(a,b)"},
        {"a!=b": "ne(a,b)"}
    ],
    "less-than": [
        {"lt(a,b)": {name:"and", args:[{name:"lt", args:["a", "b"]}]}},
        {"a=lt=b": "lt(a,b)"},
        {"a<b": "lt(a,b)"}
    ],
    "less-than-equals": [
        {"le(a,b)": {name:"and", args:[{name:"le", args:["a","b"]}]}},
        {"a=le=b": "le(a,b)"},
        {"a<=b": "le(a,b)"}
    ],
    "greater-than": [
        {"gt(a,b)": {name:"and", args:[{name:"gt", args:["a", "b"]}]}},
        {"a=gt=b": "gt(a,b)"},
        {"a>b": "gt(a,b)"}
    ],
    "greater-than-equals": [
        {"ge(a,b)": {name:"and", args:[{name:"ge", args:["a", "b"]}]}},
        {"a=ge=b": "ge(a,b)"},
        {"a>=b": "ge(a,b)"}
    ],
    "nested comparisons": [
        {"a(b(le(c,d)))": {name:"and", args:[{name:"a", args:[{name:"b", args:[{name:"le", args:["c", "d"]}]}]}]}},
        {"a(b(c=le=d))": "a(b(le(c,d)))"},
        {"a(b(c<=d))": "a(b(le(c,d)))"}
    ],
    "arbitrary FIQL desugaring": [
        {"a=b=c": {name:"and", args:[{name:"b", args:["a", "c"]}]}},
        {"a(b=cd=e)": {name:"and", args:[{name:"a", args:[{name:"cd", args:["b", "e"]}]}]}}
    ],
    "and grouping": [
        {"a&b&c": {name:"and", args:["a", "b", "c"]}},
        {"a(b)&c": {name:"and", args:[{name:"a", args:["b"]}, "c"]}},
        {"a&(b&c)": {"name":"and","args":["a",{"name":"and","args":["b","c"]}]}}
    ],
    "or grouping": [
        {"(a|b|c)": {name:"and", args:[{name:"or", args:["a", "b", "c"]}]}},
        {"(a(b)|c)": {name:"and", args:[{name:"or", args:[{name:"a", args:["b"]}, "c"]}]}}
    ],
    "complex grouping": [
        {"a&(b|c)": {name:"and", args:["a", {name:"or", args:["b", "c"]}]}},
        {"a|(b&c)": {name:"and", args:[{name:"or", args:["a", {name:"and", args:["b", "c"]}]}]}},
        {"a(b(c<d,e(f=g)))": {}}
    ],
    "complex comparisons": [

    ],
    "string coercion": [
        {"a(string)": {name:"and", args:[{name:"a", args:["string"]}]}},
        {"a(string:b)": {name:"and", args:[{name:"a", args:["b"]}]}},
        {"a(string:1)": {name:"and", args:[{name:"a", args:["1"]}]}}
    ],
    "number coercion": [
        {"a(number)": {name:"and", args:[{name:"a", args:["number"]}]}},
        {"a(number:1)": {name:"and", args:[{name:"a", args:[1]}]}}
//        {"a(number:b)": {name:"and", args:[{name:"a", args:[NaN]}]}} // supposed to throw an error
    ],
    "date coercion": [
        //FIXME do we need proper ISO date subset parsing?
        {"a(date)": {name:"and", args:[{name:"a", args:["date"]}]}},
        {"a(date:2009)": {name:"and", args:[{name:"a", args:[(new Date("2009"))]}]}},
        //{"a(date:b)": {name:"and", args:[{name:"a", args:[(new Date(NaN))]}]}} // XXX?// supposed to throw an error
    ],
    "boolean coercion": [
        {"a(true)": {name:"and", args:[{name:"a", args:[true]}]}},
        {"a(false)": {name:"and", args:[{name:"a", args:[false]}]}},
        {"a(boolean:true)": {name:"and", args:[{name:"a", args:[true]}]}}
    ],
    "null coercion": [
        {"a(null)": {name:"and", args:[{name:"a", args:[null]}]}},
        {"a(auto:null)": {name:"and", args:[{name:"a", args:[null]}]}},
        {"a(string:null)": {name:"and", args:[{name:"a", args:["null"]}]}}
    ],
    "complex coercion": [
        {"(a=b|c=d)&(e=f|g=1)": {"name":"and","args":[{"name":"or","args":[{"name":"eq","args":["a","b"]},{"name":"eq","args":["c","d"]}]},
        {"name":"or","args":[{"name":"eq","args":["e","f"]},{"name":"eq","args":["g",1]}]}]}}
    ],
    "complex grouping": [

    ]
};

exports.testParsing = function() {
    for (var group in queryPairs) {
        queryPairs[group].forEach(function(pair) {
            var key = Object.keys(pair)[0];
            try{
	            var parsed = parseQuery(key);
	            if (!Object.keys(parsed.cache).length)
							  delete parsed.cache;
	            var result = pair[key];
	            if(typeof result == "string"){
	            	result = parseQuery(result);
  	            if (!Object.keys(result.cache).length)
									delete result.cache;
	            }
            }catch(e){
            	e.message += " parsing " + group + ": " + key;
            	throw e;
            }
            try{
            	var serialized = JSON.stringify(parsed);
            }catch(e){
            	serialized = e.message;
            }
            assert.deepEqual(parsed, result, group + ": " + key + " " + serialized);
        });
    }
};

exports.testBindParameters = function() {
    // TODO
    var parsed;
    parsed = parseQuery('in(id,$1)', [['a','b','c']]);
    assert.deepEqual(parsed, {name: 'and', args: [{name: 'in', args: ['id', ['a', 'b', 'c']]}], cache: {}});
    parsed = parseQuery('eq(id,$1)', ['a']);
    assert.deepEqual(parsed, {name: 'and', args: [{name: 'eq', args: ['id', 'a']}], cache: {id: 'a'}});
};

exports.testStringification = function() {
    // TODO
    var parsed;
    parsed = parseQuery('eq(id1,RE:%5Eabc%5C%2F)');
    // Hmmm. deepEqual gives null for regexps?
    assert.ok(parsed.args[0].args[1].toString() === /^abc\//.toString());
    //assert.deepEqual(parsed, {name: 'and', args: [{name: 'eq', args: ['id1', /^abc\//]}]});
    assert.ok(Query().eq('_1',/GGG(EE|FF)/i)+'' === 'eq(_1,re:GGG%28EE%7CFF%29)');
    parsed = parseQuery('eq(_1,re:GGG%28EE%7CFF%29)');
    console.log(parsed.args[0].args[1].toString() === /GGG(EE|FF)/i.toString());
    //assert.ok(Query().eq('_1',/GGG(EE|FF)/)+'' === 'eq(_1,RE:GGG%28EE%7CFF%29)');
    // string to array and back
    var str = 'somefunc(and(1),(a,b),(10,(10,1)),(a,b.c))';
    assert.equal(parseQuery(str)+'', str);
    // quirky arguments
    var name = ['a/b','c.d'];
    assert.equal(parseQuery(Query().eq(name,1)+'')+'', 'eq((a%2Fb,c.d),1)');
    assert.deepEqual(parseQuery(Query().eq(name,1)+'').args[0].args[0], name);
};

if (require.main === module)
    require("patr/runner").run(exports);
<file_sep>/tourbook/build-profile.js
var profile = (function() {

	var miniExcludes = {
		"tourbook/build-profile" : 1
	},

	testResource = /\/tests\//, //
	jsResource = /\.js$/,

	copyOnly = function(filename, mid) {
		
		var list = {};

		return (mid in list) //
			|| (/^tourbook\/resources\//.test(mid) && !/\.css$/.test(filename))
			|| /(html|ico|png|jpg|jpeg|gif|tiff)$/.test(filename);
		// Check if it is one of the special files, if it is in
		// app/resource (but not CSS) or is an image
	};

	return {

		resourceTags : {

			test : function(filename, mid) {
				return testResource.test(mid) || mid == "app/tests";
				// Tag our test files
			},

			copyOnly : function(filename, mid) {
				return copyOnly(filename, mid);
				// Tag our copy only files
			},

			miniExclude : function(filename, mid) {
				return testResource.test(mid) || mid in miniExcludes;
			},

			amd : function(filename, mid) {
				return !testResource.test(mid) && !copyOnly(filename, mid) && jsResource.test(filename);
				// If it isn't a test resource, copy only, but is a .js file, tag it as AMD
			}
		}
	};
})();<file_sep>/dstore/docs/Stores.md
# Included Stores

The dstore package includes several store implementations that can be used for the needs of different applications. These include:

* `Memory` - This is a simple memory-based store that takes an array and provides access to the objects in the array through the store interface.
* `Request` - This is a simple server-based collection that sends HTTP requests following REST conventions to access and modify data requested through the store interface.
* `Rest` - This is a store built on `Request` that implements add, remove, and update operations using HTTP requests following REST conventions.
* `RequestMemory` - This is a Memory based store that will retrieve its contents from a server/URL.
* `Cache` - This is a store mixin that combines a master and caching store to provide caching functionality.
* `Trackable` - This a store mixin that adds index information to `add`, `update`, and `remove` events of tracked store instances. This adds a track() method for tracking stores.
* `SimpleQuery` - This is a mixin with basic querying functionality, which is extended by the Memory store, and can be used to add client side querying functionality to the Request/Rest store.
* `Store` - This is a base store, with the base methods that are used by all other stores.

## Constructing Stores

All the stores can be instantiated with an options argument to the constructor, to provide properties to be copied to the store. This can include methods to be added to the new store.

## Memory

The Memory store is a basic client-side in-memory store that can be created from a simple JavaScript array. When creating a memory store, the data (which should be an array of objects) can be provided in the `data` property to the constructor. The data should be an array of objects, and all the objects are considered to be existing objects and must have identities (this is not "creating" new objects, no events are fired for the objects that are provided, nor are identities assigned).

For example:

    myStore = new Memory({
        data: [{
            id: 1,
            aProperty: ...,
            ...
        }]
    });

The `Memory` store provides synchronous equivalents of standard asynchronous store methods, including `getSync(id)`, `addSync(object, options)`, `putSync(object, options)`, and `removeSync(id)`. These methods directly return objects or results, without a promise.

## Request

This is a simple collection for accessing data by retrieval from a server (typically through XHR). The target URL path to use for requests can be defined with the `target` property. A request for data will be sent to the server when a fetch occurs (due a call to `fetch()`, `fetchRange()`, or `forEach()`).

## Rest

This store extends the Request store, to add functionality for adding, updating, and removing objects. All modifications trigger HTTP requests to the server using the corresponding RESTful HTTP methods. A `get()` triggers a `GET`, `remove()` triggers a `DELETE`, and `add()` and `put()` will trigger a `PUT` if an id is available or provided, and a `POST` will be used to create new objects with server provided ids.

For example:

    myStore = new Rest({
        target: '/PathToData/'
    });

All modification or retrieval methods (except `getIdentity()`) on `Request` and `Rest` execute asynchronously, returning a promise.

## Store

This is the base class used for all stores, providing basic functionality for tracking collection states and converting objects to be model instances. This (or any of the other classes above) can be extended for creating custom stores.

## RequestMemory

This store provides client-side querying functionality, but will load its data from the server, using the provided URL. This is
an asynchronous store since queries and data retrieval may be made before the data has been retrieved from the server.

## Cache

This is a mixin that can be used to add caching functionality to a store. This can also be used to wrap an existing store, by using the static `create` function:

    var cachedStore = Cache.create(existingStore, {
        cachingStore: new Memory()
    });

This store has the following properties and methods:

Name | Description
---- | -----------
`cachingStore` | This can be used to define the store to be used for caching the data. By default a Memory store will be used.
`isValidFetchCache` | This is a flag that indicates if the data fetched for a collection/store can be cached to fulfill subsequent fetches. This is false by default, and the value will be inherited by downstream collections.
`canCacheQuery(method, args)' | This can be a boolean or a method that will indicate if a collection can be cached (if it should have `isValidFetchCache` set to true), based on the query method and arguments used to derive the collection.
`isLoaded(object)` | This can be defined to indicate if a given object in a query can be cached (by default, objects are cached).

## Tree

This is a mixin that provides basic support for hierarchical data. This implements several methods that can then be used by hierarchical UI components (like [dgrid](https://github.com/SitePen/dgrid) with a tree column). This mixin uses a parent-based approach to finding children, retrieving the children of an object by querying for objects that have `parent` property with the id of the parent object. In addition, objects may have a `hasChildren` property to indicate if they have children (if the property is absent, it is assumed that they may have children). This mixin implements the following methods:

* `getChildren(parent)` - This returns a collection representing the children of the provided parent object. This is produced by filtering for objects that have a `parent` property with the id of the parent object.
* `mayHaveChildren(parent)` - This synchronously returns a boolean indicating whether or not the parent object might have children (the actual children may need to be retrieved asynchronously).
* `getRootCollection()` - This returns the root collection, the collection of objects with `parent` property that is `null`.

The Tree mixin may serve as an example for alternate hierarchical implementations. By implementing these methods as they are in `dstore/Tree`, one could change the property names for data that uses different parent references or indications of children. Another option would be define the children of an object as direct references from the parent object. In this case, you would define `getChildren` to associate the `parent` object with the returned collection and override `fetch` and `fetchRange` to return a promise to the array of the children of the parent.

## Resource Query Language

[Resource Query Language (RQL)](https://github.com/persvr/rql) is a query language specifically designed to be easily embedded in URLs (it is a compatible superset of standard encoded query parameters), as well as easily interpreted within JavaScript for client-side querying. Therefore RQL is a query language suitable for consistent client and server-delegated queries. The dstore packages serializes complex filter/queries into RQL (RQL supersets standard query parameters, and so simple queries are simply serialized as standard query parameters).

dstore also includes support for using RQL as the query language for filtering. This can be enabled by mixin `dstore/extensions/RqlQuery` into your collection type:

    require([
        'dojo/_base/declare',
        'dstore/Memory',
        'dstore/extensions/RqlQuery'
    ], function (declare, Memory, RqlQuery) {
        var RqlStore = declare([ Memory, RqlQuery ]);
        var rqlStore = new RqlStore({
            ...
        });

        rqlStore.filter('price<10|rating>3').forEach(function (product) {
            // return each product that has a price less than 10 or a rating greater than 3
        });
    }};

Make sure you have installed/included the [rql](https://github.com/persvr/rql) package if you are using the RQL query engine.
