Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

[gh238] [bz5667423] support for multiple application configuration files #905

Merged
merged 6 commits into from

2 participants

Caridy Patiño Drew Folta
Caridy Patiño
Owner

Continuation of PR #898.

By specifying the list of files to aggregate with the application.json, developers will have the flexibility to split the application configuration into various files, e.g:

[
    {
        "settings": [ "master" ],
        "applicationConfigFiles": [
            "node_modules/devices/application.json",
            "relative/path/to/custom.json"
        ],
        "testKey1": "testVal1",
        "testKey2": "testVal2",
        "testKey3": "testVal3"
    }
]
Drew Folta drewfish commented on the diff
lib/app/addons/rs/config.js
((7 lines not shown))
+ * @method createMultipartYCB
+ * @param {array} paths list of files to load
+ * @return {YCB|undefined} return a YCB library object, or undefined if an error occurs
+ */
+ createMultipartYCB: function(paths) {
+ var p,
+ path,
+ config,
+ s,
+ section,
+ settings = {},
+ bundle = [];
+ bundle.push(this.getDimensions()[0]);
+ for (p = 0; p < paths.length; p += 1) {
+ path = paths[p];
+ config = this.readConfigSync(path);
Drew Folta Owner

This should use readConfigSimple() instead. The work to wire in YAML will update readConfigSimple() to also understand YAML files.

Caridy Patiño Owner
caridy added a note

At the moment, readConfigSimple does not provide that capability, and the multi-extension capability as well. Once that land it, we can change it I guess.

Drew Folta Owner

That's part of what I'm saying. Right now in develop, we should not be trying to support YAML. So, you should use readConfigSimple(). The work to support YAML will do the needful, whether that's update readConfigSimple() to readConfigSync() or not.

(I am working on the YAML support. readConfigSync() is going away, so calling it will cause a merge conflict of sorts. It's better to use the established API (readConfigSimple) than to use readConfigSync() which isn't used by anyone else and which is going away.)

Said another way, this pull request should -only- be focused on implementing multiple application.jsons, and not also trying to partially support YAML.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Drew Folta
Owner

Does this support application.json which includes application2.json which includes application3.json?

Caridy Patiño
Owner

@drewfish No, that's not supported. It developers want to keep control over what they have/use, there is not need for that. Also the error tolerance is important, since application.json is optional.

Caridy Patiño
Owner

@drewfish I will merge this so we can work on the PR #907 to accomodate the rest of the changes.

Caridy Patiño caridy merged commit eb4947e into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
1  .gitignore
View
@@ -4,6 +4,7 @@
*.bak
*~
node_modules
+!tests/fixtures/app-jsons/node_modules
!tests/fixtures/packages/node_modules
!tests/fixtures/packages/node_modules/*/node_modules
arrowreport
93 lib/app/addons/rs/config.js
View
@@ -50,6 +50,7 @@ YUI.add('addon-rs-config', function(Y, NAME) {
this._jsonCache = {}; // fullPath: contents as JSON object
this._ycbCache = {}; // fullPath: context: YCB config object
this._ycbDims = this._readYcbDimensions();
+ this._ycbAppConfig = this._readYcbAppConfig();
},
@@ -64,6 +65,16 @@ YUI.add('addon-rs-config', function(Y, NAME) {
/**
+ * Returns the YCB library object for the application config.
+ * @method getAppConfigYCB
+ * @return {YCB} YCB library object for the application config
+ */
+ getAppConfigYCB: function() {
+ return this._ycbAppConfig;
+ },
+
+
+ /**
* Same as readConfigSync except the result is cached for future calls.
* @method readConfigSimple
* @param {string} fullPath path to JSON or YAML file
@@ -165,6 +176,48 @@ YUI.add('addon-rs-config', function(Y, NAME) {
/**
+ * Creates a YCB configuration bundle using contents from multiple files.
+ * The appropriate dimensions.json file will be mixed in, and doesn't need
+ * to be part of the list of files.
+ * @method createMultipartYCB
+ * @param {array} paths list of files to load
+ * @return {YCB|undefined} return a YCB library object, or undefined if an error occurs
+ */
+ createMultipartYCB: function(paths) {
+ var p,
+ path,
+ config,
+ s,
+ section,
+ settings = {},
+ bundle = [];
+ bundle.push(this.getDimensions()[0]);
+ for (p = 0; p < paths.length; p += 1) {
+ path = paths[p];
+ config = this.readConfigSync(path);
Drew Folta Owner

This should use readConfigSimple() instead. The work to wire in YAML will update readConfigSimple() to also understand YAML files.

Caridy Patiño Owner
caridy added a note

At the moment, readConfigSimple does not provide that capability, and the multi-extension capability as well. Once that land it, we can change it I guess.

Drew Folta Owner

That's part of what I'm saying. Right now in develop, we should not be trying to support YAML. So, you should use readConfigSimple(). The work to support YAML will do the needful, whether that's update readConfigSimple() to readConfigSync() or not.

(I am working on the YAML support. readConfigSync() is going away, so calling it will cause a merge conflict of sorts. It's better to use the established API (readConfigSimple) than to use readConfigSync() which isn't used by anyone else and which is going away.)

Said another way, this pull request should -only- be focused on implementing multiple application.jsons, and not also trying to partially support YAML.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ if (!Y.Lang.isArray(config)) {
+ Y.log('not a YCB file: ' + path, 'error', NAME);
+ return;
+ }
+ for (s = 0; s < config.length; s += 1) {
+ section = config[s];
+ if (!Y.Lang.isArray(section.settings)) {
+ Y.log('missing "settings" in YCB file: ' + path, 'error', NAME);
+ return;
+ }
+ if (settings[section.settings]) {
+ Y.log('settings "' + section.settings + '" exists in both \n' + path + ' and\n' + settings[section.settings], 'error', NAME);
+ return;
+ }
+ settings[section.settings] = path;
+ bundle.push(section);
+ }
+ }
+ return new libycb.Ycb(bundle);
+ },
+
+
+ /**
* Using AOP, this is called after the ResourceStore's version.
* @method findResourceVersionByConvention
* @param {object} source metadata about where the resource is located
@@ -259,8 +312,46 @@ YUI.add('addon-rs-config', function(Y, NAME) {
path = libpath.join(this.mojitoRoot, 'dimensions.json');
}
return this.readConfigSimple(path);
- }
+ },
+
+ /**
+ * Initializes the special multi-file YCB library for all the application
+ * files. By default, we try to load `application.json`, then mix any other
+ * relative config file specified in the master section under the
+ * `applicationConfigFiles` array, which is optional.
+ * @private
+ * @method _readYcbAppConfig
+ * @return {object} libycb object
+ */
+ _readYcbAppConfig: function() {
+ var ycb,
+ i,
+ rootAppJSON = libpath.join(this.appRoot, 'application.json'),
+ paths = [],
+ relativePaths;
+
+ // trying to collect the app-level application.json which happens
+ // to be optional.
+ if (Y.Lang.isArray(this.readConfigSimple(rootAppJSON))) {
+ ycb = this.readConfigYCB(rootAppJSON, {});
+ // adding the master application.json as the top level
+ paths = [rootAppJSON];
+ // optional applicationConfigFiles to mix in more configs
+ relativePaths = ycb.applicationConfigFiles || [];
+ for (i = 0; i < relativePaths.length; i += 1) {
+ paths.push(libpath.join(this.appRoot, relativePaths[i]));
+ }
+ }
+
+ // Note: it doesn't matter if we try to reach the same file multiple
+ // times (application.json) because readConfigSync will cache it anyway
+ ycb = this.createMultipartYCB(paths);
+ if (!ycb) {
+ throw new Error("failed to create a YCB config from the following files:\n " + paths.join("\n "));
+ }
+ return ycb;
+ }
});
Y.namespace('mojito.addons.rs');
13 lib/app/addons/rs/selector.js
View
@@ -4,7 +4,7 @@
* See the accompanying LICENSE file for terms.
*/
-/*jslint anon:true, sloppy:true, nomen:true, stupid:true*/
+/*jslint anon:true, sloppy:true, nomen:true*/
/*global YUI*/
@@ -18,9 +18,6 @@
*/
YUI.add('addon-rs-selector', function(Y, NAME) {
- var libpath = require('path'),
- libycb = require('ycb');
-
function RSAddonSelector() {
RSAddonSelector.superclass.constructor.apply(this, arguments);
}
@@ -36,16 +33,10 @@ YUI.add('addon-rs-selector', function(Y, NAME) {
* @return {nothing}
*/
initializer: function(config) {
- var dims,
- json;
this.appRoot = config.appRoot;
this.mojitoRoot = config.mojitoRoot;
- dims = config.host.config.getDimensions();
- json = config.host.config.readConfigSimple(libpath.join(this.appRoot, 'application.json'));
- json = dims.concat(json);
- // TODO: use rs.config for this too
- this._appConfigYCB = new libycb.Ycb(json);
+ this._appConfigYCB = config.host.config.getAppConfigYCB();
this._poslCache = {}; // context: POSL
},
13 lib/app/autoload/store.server.js
View
@@ -223,6 +223,8 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
this._validDims = this._parseValidDims(this.config.getDimensions());
this.validateContext(this._config.context);
this._fwConfig = this.config.readConfigSimple(this._libs.path.join(this._config.mojitoRoot, 'config.json'));
+
+ this._appConfigYCB = this.config.getAppConfigYCB();
this._appConfigStatic = this.getAppConfig({});
},
destructor: function() {},
@@ -349,13 +351,14 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
key,
ycb;
+ ctx = this.blendStaticContext(ctx);
key = JSON.stringify(ctx || {});
if (this._appConfigCache[key]) {
return JSON.parse(this._appConfigCache[key]);
}
- ycb = this.config.readConfigYCB(this._libs.path.join(this._config.root, 'application.json'), ctx);
+ ycb = this._appConfigYCB.read(ctx);
appConfig = Y.mojito.util.blend(this._fwConfig.appConfigBase, this._config.appConfig);
appConfig = Y.mojito.util.blend(appConfig, ycb);
@@ -364,6 +367,8 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
return appConfig;
},
+
+
/**
* Preloads everything in the app, and as well pertinent parts of
* the framework.
@@ -374,10 +379,16 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
preload: function() {
// We need to do an initial sweep to find the resource store addons.
this.preloadResourceVersions();
+
+ // We need to rebuild _appConfigStatic -before- we load the addons,
+ // since they might (they do) cache the results of getStaticAppConfig().
+ this._appConfigStatic = this.getAppConfig({});
+
// And then use them.
this.loadAddons();
// Then, do another sweep so that the loaded addons can be used.
this.preloadResourceVersions();
+
this.makeResourceVersions();
this.resolveResourceVersions();
},
7 tests/fixtures/app-jsons/application-nosettings.json
View
@@ -0,0 +1,7 @@
+[
+ {
+ "testKey1": "testVal1",
+ "testKey2": "testVal2",
+ "testKey3": "testVal3"
+ }
+]
8 tests/fixtures/app-jsons/application-notycb.json
View
@@ -0,0 +1,8 @@
+{
+ "foo": {
+ "settings": [ "master" ],
+ "testKey1": "testVal1",
+ "testKey2": "testVal2",
+ "testKey3": "testVal3"
+ }
+}
12 tests/fixtures/app-jsons/application.json
View
@@ -0,0 +1,12 @@
+[
+ {
+ "settings": [ "master" ],
+ "applicationConfigFiles": [
+ "node_modules/devices/application.json",
+ "node_modules/runtimes/application.json"
+ ],
+ "testKey1": "testVal1",
+ "testKey2": "testVal2",
+ "testKey3": "testVal3"
+ }
+]
8 tests/fixtures/app-jsons/application2.json
View
@@ -0,0 +1,8 @@
+[
+ {
+ "settings": [ "master" ],
+ "testKey1": "testVal1-app2",
+ "testKey2": "testVal2-app2",
+ "testKey3": "testVal3-app2"
+ }
+]
14 tests/fixtures/app-jsons/node_modules/devices/application.json
View
@@ -0,0 +1,14 @@
+[
+ {
+ "settings": [ "device:iphone" ],
+ "selector": "iphone"
+ },
+ {
+ "settings": [ "device:android" ],
+ "selector": "droid"
+ },
+ {
+ "settings": [ "device:android", "environment:dev" ],
+ "selector": "devdroid"
+ }
+]
14 tests/fixtures/app-jsons/node_modules/runtimes/application.json
View
@@ -0,0 +1,14 @@
+[
+ {
+ "settings": [ "runtime:server" ],
+ "selector": "shelves",
+ "testKey1": "testVal1-server",
+ "pathos": "portended"
+ },
+ {
+ "settings": [ "runtime:client" ],
+ "selector": "right",
+ "testKey2": "testVal2-client",
+ "testKey4": "testVal4-client"
+ }
+]
13 tests/fixtures/app-jsons/package.json
View
@@ -0,0 +1,13 @@
+{
+ "name": "root",
+ "version": "666.0.0",
+ "description": "root package",
+ "author": "Team Mojito (http://developer.yahoo.com/cocktails/mojito)",
+ "dependencies": {},
+ "main": ".",
+ "engines": {
+ "node": ">= 0.4.0",
+ "npm": ">= 1.0.0"
+ },
+ "devDependencies": {}
+}
141 tests/unit/lib/app/addons/rs/test-config.js
View
@@ -3,7 +3,7 @@
* Copyrights licensed under the New BSD License.
* See the accompanying LICENSE file for terms.
*/
-YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
+YUI().use('addon-rs-config', 'mojito-util', 'mojito-test-extra', 'base', 'oop', 'test', function(Y) {
var suite = new YUITest.TestSuite('mojito-addon-rs-config-tests'),
libfs = require('fs'),
@@ -58,31 +58,6 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
}
- function cmp(x, y, msg, path) {
- if (Y.Lang.isArray(x)) {
- A.isArray(x, msg || 'first arg should be an array');
- A.isArray(y, msg || 'second arg should be an array');
- A.areSame(x.length, y.length, msg || 'arrays are different lengths');
- for (var i = 0; i < x.length; i += 1) {
- cmp(x[i], y[i], msg);
- }
- return;
- }
- if (Y.Lang.isObject(x)) {
- A.isObject(x, msg || 'first arg should be an object');
- A.isObject(y, msg || 'second arg should be an object');
- A.areSame(Object.keys(x).length, Object.keys(y).length, msg || 'object keys are different lengths');
- for (var i in x) {
- if (x.hasOwnProperty(i)) {
- cmp(x[i], y[i], msg);
- }
- }
- return;
- }
- A.areSame(x, y, msg || 'args should be the same');
- }
-
-
function makeSource(dir, dirType, subdir, file, isFile) {
var source = {
fs: {
@@ -106,9 +81,9 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
suite.add(new YUITest.TestCase({
-
+
name: 'config rs addon tests',
-
+
'read dimensions': function() {
// from mojito
var fixtures = libpath.join(__dirname, '../../../../../fixtures/store');
@@ -116,7 +91,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
store.plug(Y.mojito.addons.rs.config, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
var have = store.config.getDimensions();
var want = readJSON(mojitoRoot, 'dimensions.json');
- cmp(want, have);
+ Y.TEST_CMP(want, have);
// app-specified
fixtures = libpath.join(__dirname, '../../../../../fixtures/ycb');
@@ -124,7 +99,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
store.plug(Y.mojito.addons.rs.config, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
have = store.config.getDimensions();
want = readJSON(fixtures, 'dimensions.json');
- cmp(want, have);
+ Y.TEST_CMP(want, have);
},
@@ -137,49 +112,49 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
var source = makeSource(fixtures, 'app', '.', 'server.js', true);
var have = store.findResourceVersionByConvention(source, null);
var want = undefined;
- cmp(have, want, 'skip non-json files');
+ Y.TEST_CMP(have, want, 'skip non-json files');
// include all json files in the app
source = makeSource(fixtures, 'app', '.', 'x.json', true);
have = store.findResourceVersionByConvention(source, null);
want = { type: 'config' };
- cmp(have, want, 'include all json files in the app');
+ Y.TEST_CMP(have, want, 'include all json files in the app');
// ... explicitly including package.json
source = makeSource(fixtures, 'app', '.', 'package.json', true);
have = store.findResourceVersionByConvention(source, null);
want = { type: 'config' };
- cmp(have, want, 'include package.json in the app');
+ Y.TEST_CMP(have, want, 'include package.json in the app');
// exclude all json files in a bundle
source = makeSource(fixtures, 'bundle', '.', 'x.json', true);
have = store.findResourceVersionByConvention(source, null);
want = undefined;
- cmp(have, want, 'exclude all json files in a bundle');
+ Y.TEST_CMP(have, want, 'exclude all json files in a bundle');
// ... explicitly excluding package.json
source = makeSource(fixtures, 'bundle', '.', 'package.json', true);
have = store.findResourceVersionByConvention(source, null);
want = undefined;
- cmp(have, want, 'exclude package.json in a bundle');
+ Y.TEST_CMP(have, want, 'exclude package.json in a bundle');
// include all json files in a mojit
source = makeSource(fixtures, 'mojit', '.', 'x.json', true);
have = store.findResourceVersionByConvention(source, 'foo');
want = { type: 'config' };
- cmp(have, want, 'include all json files in a mojit');
+ Y.TEST_CMP(have, want, 'include all json files in a mojit');
// ... except for the 'shared' mojit
source = makeSource(fixtures, 'mojit', '.', 'x.json', true);
have = store.findResourceVersionByConvention(source, 'shared');
want = undefined;
- cmp(have, want, 'exclude all json files in the "shared" mojit');
+ Y.TEST_CMP(have, want, 'exclude all json files in the "shared" mojit');
// ... explicitly including package.json
source = makeSource(fixtures, 'mojit', '.', 'package.json', true);
have = store.findResourceVersionByConvention(source, 'shared');
want = { type: 'config' };
- cmp(have, want, 'include package.json in the "shared" mojit');
+ Y.TEST_CMP(have, want, 'include package.json in the "shared" mojit');
},
@@ -191,7 +166,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
var source = makeSource(fixtures, 'app', '.', 'application.json', true);
var res = store.parseResourceVersion(source, 'config');
A.isNotUndefined(res);
- cmp(res.source, source);
+ Y.TEST_CMP(res.source, source);
A.areSame('config', res.type);
A.areSame('common', res.affinity);
A.areSame('*', res.selector);
@@ -202,7 +177,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
source = makeSource(fixtures, 'mojit', '.', 'defaults.json', true);
res = store.parseResourceVersion(source, 'config', undefined, 'x');
A.isNotUndefined(res);
- cmp(res.source, source);
+ Y.TEST_CMP(res.source, source);
A.areSame('config', res.type);
A.areSame('common', res.affinity);
A.areSame('*', res.selector);
@@ -220,7 +195,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
var path = libpath.join(fixtures, 'application.json');
var have = store.config.readConfigSimple(path);
var want = readJSON(fixtures, 'application.json');
- cmp(have, want);
+ Y.TEST_CMP(have, want);
},
@@ -276,7 +251,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
"selector": "shelves",
"pathos": "portended"
};
- cmp(have, want);
+ Y.TEST_CMP(have, want);
},
@@ -303,15 +278,9 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
var path = libpath.join(fixtures, 'routes.json');
var have = store.config.readConfigYCB(path, {});
var want = {};
- cmp(have, want);
- }
+ Y.TEST_CMP(have, want);
+ },
-
- }));
-
- suite.add(new YUITest.TestCase({
-
- name: 'config rs addon tests',
"readConfigSync JSON file": function () {
@@ -327,6 +296,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
A.areSame("val", obj.key);
},
+
"readConfigSync YAML file": function () {
var fixtures = libpath.join(__dirname, '../../../../../fixtures'),
@@ -341,6 +311,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
A.areSame("val", obj.key);
},
+
"readConfigSync YML file": function () {
var fixtures = libpath.join(__dirname, '../../../../../fixtures'),
@@ -355,6 +326,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
A.areSame("val", obj.key);
},
+
"readConfigSync no ext file": function () {
var fixtures = libpath.join(__dirname, '../../../../../fixtures'),
@@ -369,6 +341,7 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
A.areSame("val", obj.key);
},
+
"readConfigSync YAML file with TAB not space": function () {
var fixtures = libpath.join(__dirname, '../../../../../fixtures'),
@@ -383,9 +356,73 @@ YUI().use('addon-rs-config', 'mojito-util', 'base', 'oop', 'test', function(Y) {
catch (err) {
A.areSame('Error parsing file:', err.message.substr(0, 19));
}
+ },
+
+
+ 'create multipart ycb': function () {
+ var fixtures = libpath.join(__dirname, '../../../../../fixtures/app-jsons'),
+ store = new MockRS({ root: fixtures });
+ store.plug(Y.mojito.addons.rs.config, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
+
+ var paths, ycb, config;
+ paths = [
+ libpath.join(fixtures, 'application.json'),
+ libpath.join(fixtures, 'node_modules', 'devices', 'application.json'),
+ libpath.join(fixtures, 'node_modules', 'runtimes', 'application.json')
+ ];
+ ycb = store.config.createMultipartYCB(paths);
+ A.isObject(ycb);
+ config = ycb.read({runtime: 'client'});
+ A.isObject(config);
+ A.areSame('testVal2-client', config.testKey2);
+ config = ycb.read({device: 'android'});
+ A.isObject(config);
+ A.areSame('droid', config.selector);
+
+ // detect non-ycb file
+ paths = [
+ libpath.join(fixtures, 'application.json'),
+ libpath.join(fixtures, 'application-notycb.json')
+ ];
+ ycb = store.config.createMultipartYCB(paths);
+ A.isUndefined(ycb);
+
+ // detect missing settings
+ paths = [
+ libpath.join(fixtures, 'application.json'),
+ libpath.join(fixtures, 'application-nosettings.json')
+ ];
+ ycb = store.config.createMultipartYCB(paths);
+ A.isUndefined(ycb);
+
+ // detect duplicate settings
+ paths = [
+ libpath.join(fixtures, 'application.json'),
+ libpath.join(fixtures, 'application2.json')
+ ];
+ ycb = store.config.createMultipartYCB(paths);
+ A.isUndefined(ycb);
+ },
+
+
+ 'test applicationExtras in _readYcbAppConfig': function () {
+ var fixtures = libpath.join(__dirname, '../../../../../fixtures/app-jsons'),
+ store = new MockRS({ root: fixtures });
+ store.plug(Y.mojito.addons.rs.config, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
+
+ var ycb, config;
+ ycb = store.config._readYcbAppConfig();
+ A.isObject(ycb);
+ config = ycb.read({runtime: 'client'});
+ A.isObject(config);
+ A.areSame('testVal2-client', config.testKey2);
+ config = ycb.read({device: 'android'});
+ A.isObject(config);
+ A.areSame('droid', config.selector);
}
+
}));
-
+
Y.Test.Runner.add(suite);
-
+
});
55 tests/unit/lib/app/addons/rs/test-selector.js
View
@@ -4,6 +4,7 @@
* See the accompanying LICENSE file for terms.
*/
YUI().use(
+ 'mojito-test-extra',
'base',
'oop',
'addon-rs-config',
@@ -13,7 +14,9 @@ YUI().use(
var suite = new Y.Test.Suite('mojito-addon-rs-selector-tests'),
libpath = require('path'),
+ libycb = require('ycb'),
mojitoRoot = libpath.join(__dirname, '../../../../../../lib'),
+ fixtures = libpath.join(__dirname, '../../../../../fixtures/store');
A = Y.Assert;
@@ -33,6 +36,9 @@ YUI().use(
'*': true
};
},
+ blendStaticContext: function() {
+ return {};
+ },
validateContext: function() {},
cloneObj: function(o) {
return Y.clone(o);
@@ -40,74 +46,47 @@ YUI().use(
});
- function cmp(x, y, msg, path) {
- if (Y.Lang.isArray(x)) {
- A.isArray(x, msg || 'first arg should be an array');
- A.isArray(y, msg || 'second arg should be an array');
- A.areSame(x.length, y.length, msg || 'arrays are different lengths');
- for (var i = 0; i < x.length; i += 1) {
- cmp(x[i], y[i], msg);
- }
- return;
- }
- if (Y.Lang.isObject(x)) {
- A.isObject(x, msg || 'first arg should be an object');
- A.isObject(y, msg || 'second arg should be an object');
- A.areSame(Object.keys(x).length, Object.keys(y).length, msg || 'object keys are different lengths');
- for (var i in x) {
- if (x.hasOwnProperty(i)) {
- cmp(x[i], y[i], msg);
- }
- }
- return;
- }
- A.areSame(x, y, msg || 'args should be the same');
- }
-
-
suite.add(new Y.Test.Case({
name: 'selector rs addon tests',
'read dimensions': function() {
// from mojito
- var fixtures = libpath.join(__dirname, '../../../../../fixtures/store');
var store = new MockRS({ root: fixtures });
store.plug(Y.mojito.addons.rs.config, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
store.plug(Y.mojito.addons.rs.selector, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
var have = store.selector.getPOSLFromContext({});
var want = ['*'];
- cmp(have, want);
+ Y.TEST_CMP(have, want);
var have = store.selector.getPOSLFromContext({runtime:'client'});
var want = ['right', '*'];
- cmp(have, want);
+ Y.TEST_CMP(have, want);
var have = store.selector.getPOSLFromContext({runtime:'server'});
var want = ['shelves', '*'];
- cmp(have, want);
+ Y.TEST_CMP(have, want);
var have = store.selector.getPOSLFromContext({device:'android'});
var want = ['droid', '*'];
- cmp(have, want);
+ Y.TEST_CMP(have, want);
var have = store.selector.getPOSLFromContext({runtime:'server', device:'android'});
var want = ['shelves', 'droid', '*'];
- cmp(have, want);
+ Y.TEST_CMP(have, want);
var have = store.selector.getPOSLFromContext({device:'android', environment:'dev'});
var want = ['devdroid', 'droid', '*'];
- cmp(have, want);
+ Y.TEST_CMP(have, want);
var have = store.selector.getPOSLFromContext({runtime:'server', device:'android', environment:'dev'});
var want = ['shelves', 'devdroid', 'droid', '*'];
- cmp(have, want);
+ Y.TEST_CMP(have, want);
},
'get all posls': function() {
- var fixtures = libpath.join(__dirname, '../../../../../fixtures/store');
var store = new MockRS({ root: fixtures });
store.plug(Y.mojito.addons.rs.config, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
store.plug(Y.mojito.addons.rs.selector, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
@@ -121,12 +100,11 @@ YUI().use(
[ 'right', 'devdroid', 'droid', '*' ],
[ 'right', 'droid', '*' ]
];
- cmp(want, have);
+ Y.TEST_CMP(want, have);
},
'list used dimensions': function() {
- var fixtures = libpath.join(__dirname, '../../../../../fixtures/store');
var store = new MockRS({ root: fixtures });
store.plug(Y.mojito.addons.rs.config, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
store.plug(Y.mojito.addons.rs.selector, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
@@ -137,12 +115,11 @@ YUI().use(
device: ['iphone', 'android'],
environment: ['dev']
}
- cmp(want, have);
+ Y.TEST_CMP(want, have);
},
'list used contexts': function() {
- var fixtures = libpath.join(__dirname, '../../../../../fixtures/store');
var store = new MockRS({ root: fixtures });
store.plug(Y.mojito.addons.rs.config, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
store.plug(Y.mojito.addons.rs.selector, { appRoot: fixtures, mojitoRoot: mojitoRoot } );
@@ -162,7 +139,7 @@ YUI().use(
{ runtime: 'client', environment: 'dev' },
{ runtime: 'client' }
];
- cmp(want, have);
+ Y.TEST_CMP(want, have);
}
27 tests/unit/lib/app/autoload/test-store.server.js
View
@@ -5,6 +5,7 @@
*/
YUI().use(
'oop',
+ 'mojito-test-extra',
'mojito-resource-store',
'addon-rs-config',
'addon-rs-selector',
@@ -23,30 +24,6 @@ YUI().use(
OA = Y.ObjectAssert;
- function cmp(x, y, msg) {
- if (Y.Lang.isArray(x)) {
- A.isArray(x, msg || 'first arg should be an array');
- A.isArray(y, msg || 'second arg should be an array');
- A.areSame(x.length, y.length, msg || 'arrays are different lengths');
- for (var i = 0; i < x.length; i += 1) {
- cmp(x[i], y[i], msg);
- }
- return;
- }
- if (Y.Lang.isObject(x)) {
- A.isObject(x, msg || 'first arg should be an object');
- A.isObject(y, msg || 'second arg should be an object');
- A.areSame(Object.keys(x).length, Object.keys(y).length, msg || 'object keys are different lengths');
- for (var i in x) {
- if (x.hasOwnProperty(i)) {
- cmp(x[i], y[i], msg);
- }
- }
- return;
- }
- A.areSame(x, y, msg || 'args should be the same');
- }
-
suite.add(new Y.Test.Case({
name: 'Store tests -- preload fixture "store"',
@@ -294,7 +271,7 @@ YUI().use(
appResources: Y.clone(store._appResources, true),
mojitResources: Y.clone(store._mojitResources, true)
};
- cmp(post, pre);
+ Y.TEST_CMP(post, pre);
},
'instance with base pointing to non-existant spec': function() {
Something went wrong with that request. Please try again.