diff --git a/.jshintignore b/.eslintignore similarity index 63% rename from .jshintignore rename to .eslintignore index d8f8557..1ede056 100644 --- a/.jshintignore +++ b/.eslintignore @@ -1,3 +1,2 @@ -node_modules/ coverage/ test/sandbox/ diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..70bcff8 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "loopback" +} diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 6637ea4..0000000 --- a/.jscsrc +++ /dev/null @@ -1,25 +0,0 @@ -{ - "preset": "google", - "requireCurlyBraces": [ - "do", - "try", - "catch" - ], - "disallowMultipleVarDecl": "exceptUndefined", - "disallowSpacesInsideObjectBrackets": null, - "requireSpaceAfterLineComment": true, - "maximumLineLength": { - "value": 80, - "allowRegex": true - }, - "validateJSDoc": { - "checkParamNames": false, - "checkRedundantParams": false, - "requireParamTypes": true - }, - "excludeFiles": [ - "node_modules/**", - "coverage/**", - "test/sandbox/**" - ] -} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 6f9fcc5..0000000 --- a/.jshintrc +++ /dev/null @@ -1,21 +0,0 @@ -{ -"node": true, -"browser": true, -"eqnull" : true, -"indent": 2, -"undef": true, -"unused": true, -"quotmark": "single", -"newcap": true, -"nonew": true, -"sub": true, -"unused": "vars", -"globals": { - "describe": false, - "it": false, - "before": false, - "beforeEach": false, - "after": false, - "afterEach": false -} -} diff --git a/CHANGES.md b/CHANGES.md index 61fe94d..334eb67 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,35 @@ +2016-06-20, Version 2.19.0 +========================== + + * update copyright notices and license (Ryan Graham) + + * Add flag var lazyConnect to ds config (juehou) + + +2016-04-13, Version 2.18.1 +========================== + + * parse config: should ignore null values (Loïc Mahieu) + + +2016-04-07, Version 2.18.0 +========================== + + * Dynamic datasources.json from ENV and config.json (David Cheung) + + * Use eslint with loopback config (Miroslav Bajtoš) + + +2016-02-23, Version 2.17.0 +========================== + + * executor: move "booted" and cb() to the next tick (Miroslav Bajtoš) + + * Fix lodash 4.0.0 breaking changes (Jérémie Drouet) + + * When config is overriden with null don't merge (Farid Neshat) + + 2015-12-22, Version 2.16.0 ========================== @@ -314,8 +346,6 @@ 2014-07-17, Version v2.0.0-beta3 ================================ - * v2.0.0-beta3 (Miroslav Bajtoš) - * compiler: return a clone of instructions (Miroslav Bajtoš) @@ -334,8 +364,6 @@ 2014-06-26, Version 2.0.0-beta1 =============================== - * 2.0.0-beta1 (Miroslav Bajtoš) - * test: fix jshint warnings (Miroslav Bajtoš) * compiler: fix references to loopback (Miroslav Bajtoš) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..63b1fed --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) IBM Corp. 2014,2016. All Rights Reserved. +Node module: loopback-boot +This project is licensed under the MIT License, full text below. + +-------- + +MIT license + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index ca2e8c9..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) 2013-2015 StrongLoop, Inc and other contributors. - -loopback-boot uses a dual license model. - -You may use this library under the terms of the [MIT License][], -or under the terms of the [StrongLoop Subscription Agreement][]. - -[MIT License]: http://opensource.org/licenses/MIT -[StrongLoop Subscription Agreement]: http://strongloop.com/license diff --git a/browser.js b/browser.js index becbec6..98c66c7 100644 --- a/browser.js +++ b/browser.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var execute = require('./lib/executor'); /** diff --git a/index.js b/index.js index e8a4ad7..9ece35c 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var ConfigLoader = require('./lib/config-loader'); var compile = require('./lib/compiler'); var execute = require('./lib/executor'); @@ -154,7 +159,7 @@ exports.compileToBrowserify = function(options, bundler) { addInstructionsToBrowserify(compile(options), bundler); }; -/*-- undocumented low-level API --*/ +/* -- undocumented low-level API -- */ exports.ConfigLoader = ConfigLoader; exports.compile = compile; diff --git a/lib/bundler.js b/lib/bundler.js index 52e0736..cb0552a 100644 --- a/lib/bundler.js +++ b/lib/bundler.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var fs = require('fs'); var path = require('path'); var commondir = require('commondir'); diff --git a/lib/compiler.js b/lib/compiler.js index ba5f5d8..70a2379 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var assert = require('assert'); var cloneDeep = require('lodash').cloneDeep; var fs = require('fs'); @@ -102,8 +107,8 @@ module.exports = function compile(options) { components: componentInstructions, mixins: mixinInstructions, files: { - boot: bootScripts - } + boot: bootScripts, + }, }; if (options.appId) @@ -214,7 +219,7 @@ function buildAllModelInstructions(rootDir, modelsConfig, sources, name: name, config: config, definition: definition.definition, - sourceFile: definition.sourceFile + sourceFile: definition.sourceFile, }; }); @@ -414,7 +419,6 @@ function tryResolveAppPath(rootDir, relativePath, resolveOptions) { try { // NOTE(bajtos) We need to create a proper String object here, // otherwise we can't attach additional properties to it - /*jshint -W053 */ var filePath = new String(require.resolve(absPath)); filePath.unresolvedPath = absPath; return filePath; @@ -456,7 +460,7 @@ function loadModelDefinition(rootDir, jsonFile, allFiles) { return { definition: definition, - sourceFile: sourceFile + sourceFile: sourceFile, }; } @@ -494,7 +498,7 @@ function buildMiddlewareInstructions(rootDir, config) { var item = { sourceFile: resolved.sourceFile, - config: middlewareConfig + config: middlewareConfig, }; if (resolved.fragment) { item.fragment = resolved.fragment; @@ -516,13 +520,13 @@ function buildMiddlewareInstructions(rootDir, config) { return { phases: flattenedPhaseNames, - middleware: middlewareList + middleware: middlewareList, }; } function resolveMiddlewarePath(rootDir, middleware, config) { var resolved = { - optional: !!config.optional + optional: !!config.optional, }; var segments = middleware.split('#'); @@ -531,7 +535,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) { var middlewarePath = pathName; var opts = { strict: true, - optional: !!config.optional + optional: !!config.optional, }; if (fragment) { @@ -551,7 +555,7 @@ function resolveMiddlewarePath(rootDir, middleware, config) { // node_modules/strong-express-metrics // instead of // node_modules/strong-express-metrics/index.js - fullResolve: false + fullResolve: false, }); var sourceFile = resolveAppScriptPath(rootDir, middlewarePath, resolveOpts); @@ -580,14 +584,13 @@ function resolveMiddlewarePath(rootDir, middleware, config) { // pathName + '/' + fragment ]; - var err; + var err = undefined; // see https://github.com/eslint/eslint/issues/5744 for (var ix in candidates) { try { resolved.sourceFile = resolveAppScriptPath(rootDir, candidates[ix], opts); delete resolved.fragment; return resolved; - } - catch (e) { + } catch (e) { // Report the error for the first candidate when no candidate matches if (!err) err = e; } @@ -614,7 +617,7 @@ function buildComponentInstructions(rootDir, componentConfig) { .map(function(name) { return { sourceFile: resolveAppScriptPath(rootDir, name, { strict: true }), - config: componentConfig[name] + config: componentConfig[name], }; }); } @@ -634,11 +637,11 @@ function resolveRelativePaths(relativePaths, appRootDir) { function getExcludedExtensions() { return { '.json': '.json', - '.node': 'node' + '.node': 'node', }; } -function isPreferredExtension (filename) { +function isPreferredExtension(filename) { var includeExtensions = require.extensions; var ext = path.extname(filename); @@ -792,7 +795,9 @@ function normalizeMixinName(str, options) { case 'classify': str = String(str).replace(/([A-Z]+)/g, ' $1').trim(); str = String(str).replace(/[\W_]/g, ' ').toLowerCase(); - str = str.replace(/(?:^|\s|-)\S/g, function(c) { return c.toUpperCase(); }); + str = str.replace(/(?:^|\s|-)\S/g, function(c) { + return c.toUpperCase(); + }); str = str.replace(/\s+/g, ''); return str; diff --git a/lib/config-loader.js b/lib/config-loader.js index c2baf32..8d8c451 100644 --- a/lib/config-loader.js +++ b/lib/config-loader.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var fs = require('fs'); var path = require('path'); var debug = require('debug')('loopback:boot:config-loader'); @@ -32,7 +37,6 @@ ConfigLoader.loadDataSources = function(rootDir, env) { * @returns {Object} */ ConfigLoader.loadModels = function(rootDir, env) { - /*jshint unused:false */ return loadNamed(rootDir, env, 'model-config', mergeModelConfig); }; @@ -98,7 +102,7 @@ function findConfigFiles(appRootDir, env, name) { var candidates = [ master, ifExistsWithAnyExt(name + '.local'), - ifExistsWithAnyExt(name + '.' + env) + ifExistsWithAnyExt(name + '.' + env), ]; return candidates.filter(function(c) { return c !== undefined; }); @@ -124,7 +128,7 @@ function loadConfigFiles(files) { var config = require(f); Object.defineProperty(config, '_filename', { enumerable: false, - value: f + value: f, }); return config; }); @@ -166,7 +170,7 @@ function mergeAppConfig(target, config, fileName) { } function mergeMiddlewareConfig(target, config, fileName) { - var err; + var err = undefined; // see https://github.com/eslint/eslint/issues/5744 for (var phase in config) { if (phase in target) { err = mergePhaseConfig(target[phase], config[phase], phase); @@ -203,7 +207,7 @@ function mergeNamedItems(arr1, arr2, key) { } function mergePhaseConfig(target, config, phase) { - var err; + var err = undefined; // see https://github.com/eslint/eslint/issues/5744 for (var mw in config) { if (mw in target) { var targetMiddleware = target[mw]; diff --git a/lib/executor.js b/lib/executor.js index 3b7614c..4059618 100644 --- a/lib/executor.js +++ b/lib/executor.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var assert = require('assert'); var semver = require('semver'); var debug = require('debug')('loopback:boot:executor'); @@ -43,15 +48,20 @@ module.exports = function execute(app, instructions, callback) { function(done) { enableAnonymousSwagger(app, instructions); done(); - }], function(err) { - app.booting = false; + }, + // Ensure both the "booted" event and the callback are always called + // in the next tick of the even loop. + // See http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony + process.nextTick, + ], function(err) { + app.booting = false; - if (err) return callback(err); + if (err) return callback(err); - app.emit('booted'); + app.emit('booted'); - callback(); - }); + callback(); + }); }; function patchAppLoopback(app) { @@ -123,7 +133,7 @@ function setPort(app, instructions) { instructions.config.port, process.env.npm_package_config_port, app.get('port'), - 3000 + 3000, ], function(p) { return p != null; }); @@ -166,6 +176,15 @@ function applyAppConfig(app, instructions) { function setupDataSources(app, instructions) { forEachKeyedObject(instructions.dataSources, function(key, obj) { + var opts = { + useEnvVars: true, + }; + obj = getUpdatedConfigObject(app, obj, opts); + var lazyConnect = process.env.LB_LAZYCONNECT_DATASOURCES; + if (lazyConnect) { + obj.lazyConnect = + lazyConnect === 'false' || lazyConnect === '0' ? false : true; + } app.dataSource(key, obj); }); } @@ -272,7 +291,7 @@ function runScripts(app, list, callback) { debug('Exported function detected %s', filepath); functions.push({ path: filepath, - func: exports + func: exports, }); } } catch (err) { @@ -325,24 +344,42 @@ function setupMiddleware(app, instructions) { } assert(typeof factory === 'function', 'Middleware factory must be a function'); - data.config = getUpdatedConfigObject(app, data.config); + var opts = { + useEnvVars: true, + }; + data.config = getUpdatedConfigObject(app, data.config, opts); app.middlewareFromConfig(factory, data.config); }); } -function getUpdatedConfigObject(app, config) { +function getUpdatedConfigObject(app, config, opts) { var DYNAMIC_CONFIG_PARAM = /\$\{(\w+)\}$/; + var useEnvVars = opts && opts.useEnvVars; function getConfigVariable(param) { var configVariable = param; var match = configVariable.match(DYNAMIC_CONFIG_PARAM); if (match) { - var appValue = app.get(match[1]); - if (appValue !== undefined) { + var varName = match[1]; + if (useEnvVars && process.env[varName] !== undefined) { + debug('Dynamic Configuration: Resolved via process.env: %s as %s', + process.env[varName], param); + configVariable = process.env[varName]; + } else if (app.get(varName) !== undefined) { + debug('Dynamic Configuration: Resolved via app.get(): %s as %s', + app.get(varName), param); + var appValue = app.get(varName); configVariable = appValue; } else { - console.warn('%s does not resolve to a valid value. ' + - '"%s" must be resolvable by app.get().', param, match[1]); + // previously it returns the original string such as "${restApiRoot}" + // it will now return `undefined`, for the use case of + // dynamic datasources url:`undefined` to fallback to other parameters + configVariable = undefined; + console.warn('%s does not resolve to a valid value, returned as %s. ' + + '"%s" must be resolvable in Environment variable or by app.get().', + param, configVariable, varName); + debug('Dynamic Configuration: Cannot resolve variable for `%s`, ' + + 'returned as %s', varName, configVariable); } } return configVariable; @@ -373,6 +410,8 @@ function getUpdatedConfigObject(app, config) { interpolated[configKey] = value.map(interpolateVariables); } else if (typeof value === 'string') { interpolated[configKey] = getConfigVariable(value); + } else if (value === null) { + interpolated[configKey] = value; } else if (typeof value === 'object' && Object.keys(value).length) { interpolated[configKey] = interpolateVariables(value); } else { @@ -389,7 +428,10 @@ function setupComponents(app, instructions) { instructions.components.forEach(function(data) { debug('Configuring component %j', data.sourceFile); var configFn = require(data.sourceFile); - data.config = getUpdatedConfigObject(app, data.config); + var opts = { + useEnvVars: true, + }; + data.config = getUpdatedConfigObject(app, data.config, opts); configFn(app, data.config); }); } diff --git a/package.json b/package.json index e266210..64591ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loopback-boot", - "version": "2.16.0", + "version": "2.19.0", "description": "Convention-based bootstrapper for LoopBack applications", "keywords": [ "StrongLoop", @@ -15,8 +15,9 @@ "main": "index.js", "browser": "browser.js", "scripts": { - "pretest": "jscs . && jshint .", - "test": "mocha" + "test": "mocha", + "posttest": "npm run lint", + "lint": "eslint ." }, "license": "MIT", "dependencies": { @@ -32,9 +33,9 @@ "chai": "^1.10.0", "coffee-script": "^1.8.0", "coffeeify": "^0.7.0", + "eslint": "^2.5.3", + "eslint-config-loopback": "^1.0.0", "fs-extra": "^0.12.0", - "jscs": "^1.7.3", - "jshint": "^2.5.6", "loopback": "^2.16.3", "mocha": "^1.19.0", "supertest": "^0.14.0" diff --git a/test/browser.multiapp.test.js b/test/browser.multiapp.test.js index e0a256d..bfcafd4 100644 --- a/test/browser.multiapp.test.js +++ b/test/browser.multiapp.test.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var boot = require('../'); var exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox; var fs = require('fs'); @@ -22,14 +27,14 @@ describe('browser support for multiple apps', function() { { appDir: app1Dir, appFile: './app.js', - moduleName: 'browser-app' + moduleName: 'browser-app', }, { appDir: app2Dir, appFile: './app.js', moduleName: 'browser-app2', - appId: 'browserApp2' - } + appId: 'browserApp2', + }, ]; browserifyTestApps(apps, function(err, bundlePath) { @@ -55,7 +60,7 @@ describe('browser support for multiple apps', function() { function browserifyTestApps(apps, next) { var b = browserify({ - debug: true + debug: true, }); for (var i in apps) { @@ -65,13 +70,13 @@ function browserifyTestApps(apps, next) { var appId = apps[i].appId; appFile = path.join(appDir, appFile); - b.require(appFile, {expose: moduleName}); + b.require(appFile, { expose: moduleName }); var opts = appDir; if (appId) { opts = { appId: appId, - appRootDir: appDir + appRootDir: appDir, }; } boot.compileToBrowserify(opts, b); diff --git a/test/browser.test.js b/test/browser.test.js index 44e0b7a..d179aa5 100644 --- a/test/browser.test.js +++ b/test/browser.test.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var boot = require('../'); var exportBrowserifyToFile = require('./helpers/browserify').exportToSandbox; var fs = require('fs'); @@ -13,7 +18,7 @@ var compileStrategies = { 'default': function(appDir) { var b = browserify({ basedir: appDir, - debug: true + debug: true, }); b.require('./app.js', { expose: 'browser-app' }); @@ -24,7 +29,7 @@ var compileStrategies = { var b = browserify({ basedir: appDir, extensions: ['.coffee'], - debug: true + debug: true, }); b.transform('coffeeify'); @@ -64,7 +69,7 @@ describe('browser support', function() { it('loads mixins', function(done) { var appDir = path.resolve(__dirname, './fixtures/browser-app'); var options = { - appRootDir: appDir + appRootDir: appDir, }; browserifyTestApp(options, function(err, bundlePath) { diff --git a/test/compiler.test.js b/test/compiler.test.js index 1f36bc5..d6d1068 100644 --- a/test/compiler.test.js +++ b/test/compiler.test.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var boot = require('../'); var fs = require('fs-extra'); var path = require('path'); @@ -15,9 +20,7 @@ describe('compiler', function() { beforeEach(appdir.init); describe('from options', function() { - var options; - var instructions; - var appConfig; + var options, instructions, appConfig; beforeEach(function() { options = { @@ -25,20 +28,20 @@ describe('compiler', function() { port: 3000, host: '127.0.0.1', restApiRoot: '/rest-api', - foo: {bar: 'bat'}, - baz: true + foo: { bar: 'bat' }, + baz: true, }, models: { 'foo-bar-bat-baz': { - dataSource: 'the-db' - } + dataSource: 'the-db', + }, }, dataSources: { 'the-db': { connector: 'memory', - defaultForType: 'db' - } - } + defaultForType: 'db', + }, + }, }; instructions = boot.compile(options); appConfig = instructions.config; @@ -59,7 +62,7 @@ describe('compiler', function() { it('has other settings', function() { expect(appConfig).to.have.property('baz', true); expect(appConfig.foo, 'appConfig.foo').to.eql({ - bar: 'bat' + bar: 'bat', }); }); @@ -68,10 +71,10 @@ describe('compiler', function() { expect(instructions.models[0]).to.eql({ name: 'foo-bar-bat-baz', config: { - dataSource: 'the-db' + dataSource: 'the-db', }, definition: undefined, - sourceFile: undefined + sourceFile: undefined, }); }); @@ -81,7 +84,7 @@ describe('compiler', function() { describe('with custom model definitions', function() { var dataSources = { - 'the-db': { connector: 'memory' } + 'the-db': { connector: 'memory' }, }; it('loads model without definition', function() { @@ -89,11 +92,11 @@ describe('compiler', function() { appRootDir: appdir.PATH, models: { 'model-without-definition': { - dataSource: 'the-db' - } + dataSource: 'the-db', + }, }, modelDefinitions: [], - dataSources: dataSources + dataSources: dataSources, }); expect(instruction.models[0].name) .to.equal('model-without-definition'); @@ -108,23 +111,23 @@ describe('compiler', function() { appRootDir: appdir.PATH, models: { 'coffee-model-with-definition': { - dataSource: 'the-db' - } + dataSource: 'the-db', + }, }, modelDefinitions: [ { definition: { - name: 'coffee-model-with-definition' + name: 'coffee-model-with-definition', }, - sourceFile: modelScript - } + sourceFile: modelScript, + }, ], - dataSources: dataSources + dataSources: dataSources, }); expect(instruction.models[0].name) .to.equal('coffee-model-with-definition'); expect(instruction.models[0].definition).to.eql({ - name: 'coffee-model-with-definition' + name: 'coffee-model-with-definition', }); expect(instruction.models[0].sourceFile).to.equal(modelScript); }); @@ -137,16 +140,16 @@ describe('compiler', function() { appRootDir: appdir.PATH, models: { 'model-without-ext': { - dataSource: 'the-db' - } + dataSource: 'the-db', + }, }, modelDefinitions: [{ definition: { - name: 'model-without-ext' + name: 'model-without-ext', }, - sourceFile: pathWithoutExtension(modelScript) + sourceFile: pathWithoutExtension(modelScript), }], - dataSources: dataSources + dataSources: dataSources, }); expect(instruction.models[0].name).to.equal('model-without-ext'); expect(instruction.models[0].sourceFile).to.equal(modelScript); @@ -160,16 +163,16 @@ describe('compiler', function() { appRootDir: appdir.PATH, models: { 'model-without-ext': { - dataSource: 'the-db' - } + dataSource: 'the-db', + }, }, modelDefinitions: [{ definition: { - name: 'model-without-ext' + name: 'model-without-ext', }, - sourceFile: pathWithoutExtension(modelScript) + sourceFile: pathWithoutExtension(modelScript), }], - dataSources: dataSources + dataSources: dataSources, }); expect(instruction.models[0].name).to.equal('model-without-ext'); expect(instruction.models[0].sourceFile).to.equal(modelScript); @@ -183,18 +186,18 @@ describe('compiler', function() { appRootDir: appdir.PATH, models: { 'model-with-definition': { - dataSource: 'the-db' - } + dataSource: 'the-db', + }, }, modelDefinitions: [ { definition: { - name: 'model-with-definition' + name: 'model-with-definition', }, - sourceFile: modelScript - } + sourceFile: modelScript, + }, ], - dataSources: dataSources + dataSources: dataSources, }); expect(instruction.models[0].name).to.equal('model-with-definition'); expect(instruction.models[0].definition).not.to.equal(undefined); @@ -207,19 +210,19 @@ describe('compiler', function() { appRootDir: appdir.PATH, models: { 'model-with-definition-with-falsey-source-file': { - dataSource: 'the-db' - } + dataSource: 'the-db', + }, }, modelDefinitions: [ { definition: { - name: 'model-with-definition-with-falsey-source-file' + name: 'model-with-definition-with-falsey-source-file', }, sourceFile: appdir.resolve('custom-models', - 'file-does-not-exist.js') - } + 'file-does-not-exist.js'), + }, ], - dataSources: dataSources + dataSources: dataSources, }); expect(instruction.models[0].name) .to.equal('model-with-definition-with-falsey-source-file'); @@ -233,18 +236,18 @@ describe('compiler', function() { appRootDir: appdir.PATH, models: { 'model-with-definition-without-source-file-property': { - dataSource: 'the-db' - } + dataSource: 'the-db', + }, }, modelDefinitions: [ { definition: { - name: 'model-with-definition-without-source-file-property' - } + name: 'model-with-definition-without-source-file-property', + }, // sourceFile is not set - } + }, ], - dataSources: dataSources + dataSources: dataSources, }); expect(instruction.models[0].name) .to.equal('model-with-definition-without-source-file-property'); @@ -257,22 +260,22 @@ describe('compiler', function() { appRootDir: appdir.PATH, models: { 'some-model': { - dataSource: 'the-db' - } + dataSource: 'the-db', + }, }, modelDefinitions: [ { definition: { - name: 'some-model' - } + name: 'some-model', + }, }, { definition: { - name: 'another-model' - } - } + name: 'another-model', + }, + }, ], - dataSources: dataSources + dataSources: dataSources, }); expect(instruction.models.map(getNameProperty)) @@ -289,22 +292,22 @@ describe('compiler', function() { expect(instructions.models[0]).to.eql({ name: 'User', config: { - dataSource: 'db' + dataSource: 'db', }, definition: undefined, - sourceFile: undefined + sourceFile: undefined, }); }); it('merges datasource configs from multiple files', function() { appdir.createConfigFilesSync(); appdir.writeConfigFileSync('datasources.local.json', { - db: { local: 'applied' } + db: { local: 'applied' }, }); var env = process.env.NODE_ENV || 'development'; appdir.writeConfigFileSync('datasources.' + env + '.json', { - db: { env: 'applied' } + db: { env: 'applied' }, }); var instructions = boot.compile(appdir.PATH); @@ -336,7 +339,7 @@ describe('compiler', function() { var objectValue = { key: 'value' }; appdir.createConfigFilesSync(); appdir.writeConfigFileSync('datasources.local.json', { - db: { nested: objectValue } + db: { nested: objectValue }, }); var instructions = boot.compile(appdir.PATH); @@ -350,17 +353,17 @@ describe('compiler', function() { appdir.createConfigFilesSync({}, { email: { transport: { - host: 'localhost' - } - } + host: 'localhost', + }, + }, }); appdir.writeConfigFileSync('datasources.local.json', { email: { transport: { - host: 'mail.example.com' - } - } + host: 'mail.example.com', + }, + }, }); var instructions = boot.compile(appdir.PATH); @@ -375,11 +378,11 @@ describe('compiler', function() { { template: { method: 'POST', - url: 'http://localhost:12345' - } - } - ] - } + url: 'http://localhost:12345', + }, + }, + ], + }, }); appdir.writeConfigFileSync('datasources.local.json', { @@ -387,11 +390,11 @@ describe('compiler', function() { operations: [ { template: { - url: 'http://api.example.com' - } - } - ] - } + url: 'http://api.example.com', + }, + }, + ], + }, }); var instructions = boot.compile(appdir.PATH); @@ -399,7 +402,7 @@ describe('compiler', function() { var rest = instructions.dataSources.rest; expect(rest.operations[0].template).to.eql({ method: 'POST', // the value from datasources.json - url: 'http://api.example.com' // overriden in datasources.local.json + url: 'http://api.example.com', // overriden in datasources.local.json }); }); @@ -407,7 +410,7 @@ describe('compiler', function() { var arrayValue = ['value']; appdir.createConfigFilesSync(); appdir.writeConfigFileSync('datasources.local.json', { - db: { nested: arrayValue } + db: { nested: arrayValue }, }); var instructions = boot.compile(appdir.PATH); @@ -420,7 +423,7 @@ describe('compiler', function() { it('allows env specific model-config json', function() { appdir.createConfigFilesSync(); appdir.writeConfigFileSync('model-config.local.json', { - foo: { dataSource: 'db' } + foo: { dataSource: 'db' }, }); var instructions = boot.compile(appdir.PATH); @@ -431,9 +434,9 @@ describe('compiler', function() { it('allows env specific model-config json to be merged', function() { appdir.createConfigFilesSync(null, null, - {foo: {dataSource: 'mongo', public: false}}); + { foo: { dataSource: 'mongo', public: false }}); appdir.writeConfigFileSync('model-config.local.json', { - foo: {dataSource: 'db'} + foo: { dataSource: 'db' }, }); var instructions = boot.compile(appdir.PATH); @@ -442,7 +445,7 @@ describe('compiler', function() { expect(instructions.models[0]).to.have.property('name', 'foo'); expect(instructions.models[0].config).to.eql({ dataSource: 'db', - public: false + public: false, }); }); @@ -460,18 +463,18 @@ describe('compiler', function() { it('refuses to merge Array properties of different length', function() { appdir.createConfigFilesSync({ nest: { - array: [] - } + array: [], + }, }); appdir.writeConfigFileSync('config.local.json', { nest: { array: [ { - key: 'value' - } - ] - } + key: 'value', + }, + ], + }, }); expect(function() { boot.compile(appdir.PATH); }) @@ -480,11 +483,11 @@ describe('compiler', function() { it('refuses to merge Array of different length in Array', function() { appdir.createConfigFilesSync({ - key: [[]] + key: [[]], }); appdir.writeConfigFileSync('config.local.json', { - key: [['value']] + key: [['value']], }); expect(function() { boot.compile(appdir.PATH); }) @@ -495,17 +498,17 @@ describe('compiler', function() { appdir.createConfigFilesSync({ toplevel: [ { - nested: [] - } - ] + nested: [], + }, + ], }); appdir.writeConfigFileSync('config.local.json', { toplevel: [ { - nested: ['value'] - } - ] + nested: ['value'], + }, + ], }); expect(function() { boot.compile(appdir.PATH); }) @@ -514,10 +517,10 @@ describe('compiler', function() { it('refuses to merge incompatible object properties', function() { appdir.createConfigFilesSync({ - key: [] + key: [], }); appdir.writeConfigFileSync('config.local.json', { - key: {} + key: {}, }); expect(function() { boot.compile(appdir.PATH); }) @@ -526,10 +529,10 @@ describe('compiler', function() { it('refuses to merge incompatible array items', function() { appdir.createConfigFilesSync({ - key: [[]] + key: [[]], }); appdir.writeConfigFileSync('config.local.json', { - key: [{}] + key: [{}], }); expect(function() { boot.compile(appdir.PATH); }) @@ -571,7 +574,7 @@ describe('compiler', function() { }); it('supports `appConfigRootDir` option', function() { - appdir.createConfigFilesSync({port:3000}); + appdir.createConfigFilesSync({ port: 3000 }); var customDir = path.resolve(appdir.PATH, 'custom'); fs.mkdirsSync(customDir); @@ -581,7 +584,7 @@ describe('compiler', function() { var instructions = boot.compile({ appRootDir: appdir.PATH, - appConfigRootDir: path.resolve(appdir.PATH, 'custom') + appConfigRootDir: path.resolve(appdir.PATH, 'custom'), }); expect(instructions.config).to.have.property('port'); @@ -598,7 +601,7 @@ describe('compiler', function() { var instructions = boot.compile({ appRootDir: appdir.PATH, - dsRootDir: path.resolve(appdir.PATH, 'custom') + dsRootDir: path.resolve(appdir.PATH, 'custom'), }); expect(instructions.dataSources).to.have.property('db'); @@ -607,12 +610,12 @@ describe('compiler', function() { it('supports `modelsRootDir` option', function() { appdir.createConfigFilesSync(); appdir.writeConfigFileSync('custom/model-config.json', { - foo: { dataSource: 'db' } + foo: { dataSource: 'db' }, }); var instructions = boot.compile({ appRootDir: appdir.PATH, - modelsRootDir: path.resolve(appdir.PATH, 'custom') + modelsRootDir: path.resolve(appdir.PATH, 'custom'), }); expect(instructions.models).to.have.length(1); @@ -633,7 +636,7 @@ describe('compiler', function() { 'module.exports = function(app) { app.fnCalled = true; };'); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootDirs: [path.dirname(initJs)] + bootDirs: [path.dirname(initJs)], }); expect(instructions.files.boot).to.eql([initJs]); }); @@ -644,7 +647,7 @@ describe('compiler', function() { 'module.exports = function(app) { app.fnCalled = true; };'); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootDirs:['./custom-boot'] + bootDirs: ['./custom-boot'], }); expect(instructions.files.boot).to.eql([initJs]); }); @@ -654,7 +657,7 @@ describe('compiler', function() { var initJs = appdir.writeFileSync('custom-boot/init.js', ''); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootDirs:['custom-boot'] + bootDirs: ['custom-boot'], }); expect(instructions.files.boot).to.eql([initJs]); }); @@ -664,7 +667,7 @@ describe('compiler', function() { appdir.writeFileSync('custom-boot/index.js', ''); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootDirs:['./custom-boot'] + bootDirs: ['./custom-boot'], }); expect(instructions.files.boot).to.have.length(0); }); @@ -676,13 +679,13 @@ describe('compiler', function() { var instructions = boot.compile({ appRootDir: appdir.PATH, - bootDirs: ['./custom-boot'] + bootDirs: ['./custom-boot'], }); expect(instructions.files.boot).to.eql([coffee]); }); it('prefers coffeescript over json in `bootDir` non-relative path', - function() { + function() { appdir.createConfigFilesSync(); var coffee = appdir.writeFileSync('custom-boot/init.coffee', ''); @@ -690,7 +693,7 @@ describe('compiler', function() { var instructions = boot.compile({ appRootDir: appdir.PATH, - bootDirs: ['custom-boot'] + bootDirs: ['custom-boot'], }); expect(instructions.files.boot).to.eql([coffee]); }); @@ -701,7 +704,7 @@ describe('compiler', function() { 'module.exports = function(app) { app.fnCalled = true; };'); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootScripts: [initJs] + bootScripts: [initJs], }); expect(instructions.files.boot).to.eql([initJs]); }); @@ -712,8 +715,8 @@ describe('compiler', function() { 'module.exports = function(app) { app.fnCalled = true; };'); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootDirs:[path.dirname(initJs)], - bootScripts: [initJs] + bootDirs: [path.dirname(initJs)], + bootScripts: [initJs], }); expect(instructions.files.boot).to.eql([initJs]); }); @@ -724,7 +727,7 @@ describe('compiler', function() { 'module.exports = function(app) { app.fnCalled = true; };'); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootScripts: ['./custom-boot/init.js'] + bootScripts: ['./custom-boot/init.js'], }); expect(instructions.files.boot).to.eql([initJs]); }); @@ -734,7 +737,7 @@ describe('compiler', function() { var initJs = appdir.writeFileSync('custom-boot/init.js', ''); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootScripts: ['custom-boot/init.js'] + bootScripts: ['custom-boot/init.js'], }); expect(instructions.files.boot).to.eql([initJs]); }); @@ -744,19 +747,19 @@ describe('compiler', function() { var initJs = appdir.writeFileSync('custom-boot/init.js', ''); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootScripts:['./custom-boot/init'] + bootScripts: ['./custom-boot/init'], }); expect(instructions.files.boot).to.eql([initJs]); }); it('resolves missing extensions in `bootScripts` in module relative path', - function() { + function() { appdir.createConfigFilesSync(); var initJs = appdir.writeFileSync('node_modules/custom-boot/init.js', ''); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootScripts: ['custom-boot/init'] + bootScripts: ['custom-boot/init'], }); expect(instructions.files.boot).to.eql([initJs]); }); @@ -766,7 +769,7 @@ describe('compiler', function() { var initJs = appdir.writeFileSync('node_modules/custom-boot/init.js', ''); var instructions = boot.compile({ appRootDir: appdir.PATH, - bootScripts: ['custom-boot/init.js'] + bootScripts: ['custom-boot/init.js'], }); expect(instructions.files.boot).to.eql([initJs]); }); @@ -779,7 +782,7 @@ describe('compiler', function() { var instructions = boot.compile({ appRootDir: appdir.PATH, - bootScripts: ['custom-boot/init.js'] + bootScripts: ['custom-boot/init.js'], }); expect(instructions.files.boot).to.eql([appJs]); }); @@ -795,7 +798,7 @@ describe('compiler', function() { it('throws when models-config.json contains 1.x `properties`', function() { appdir.createConfigFilesSync({}, {}, { - foo: { properties: { name: 'string' } } + foo: { properties: { name: 'string' }}, }); expect(function() { boot.compile(appdir.PATH); }) @@ -804,7 +807,7 @@ describe('compiler', function() { it('throws when model-config.json contains 1.x `options.base`', function() { appdir.createConfigFilesSync({}, {}, { - Customer: { options: { base: 'User' } } + Customer: { options: { base: 'User' }}, }); expect(function() { boot.compile(appdir.PATH); }) @@ -813,7 +816,7 @@ describe('compiler', function() { it('loads models from `./models`', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', { name: 'Car' }); appdir.writeFileSync('models/car.js', ''); @@ -824,18 +827,18 @@ describe('compiler', function() { expect(instructions.models[0]).to.eql({ name: 'Car', config: { - dataSource: 'db' + dataSource: 'db', }, definition: { - name: 'Car' + name: 'Car', }, - sourceFile: path.resolve(appdir.PATH, 'models', 'car.js') + sourceFile: path.resolve(appdir.PATH, 'models', 'car.js'), }); }); it('loads coffeescript models from `./models`', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', { name: 'Car' }); appdir.writeFileSync('models/car.coffee', ''); @@ -846,46 +849,46 @@ describe('compiler', function() { expect(instructions.models[0]).to.eql({ name: 'Car', config: { - dataSource: 'db' + dataSource: 'db', }, definition: { - name: 'Car' + name: 'Car', }, - sourceFile: path.resolve(appdir.PATH, 'models', 'car.coffee') + sourceFile: path.resolve(appdir.PATH, 'models', 'car.coffee'), }); }); it('supports `modelSources` option', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('custom-models/car.json', { name: 'Car' }); appdir.writeFileSync('custom-models/car.js', ''); var instructions = boot.compile({ appRootDir: appdir.PATH, - modelSources: ['./custom-models'] + modelSources: ['./custom-models'], }); expect(instructions.models).to.have.length(1); expect(instructions.models[0]).to.eql({ name: 'Car', config: { - dataSource: 'db' + dataSource: 'db', }, definition: { - name: 'Car' + name: 'Car', }, - sourceFile: path.resolve(appdir.PATH, 'custom-models', 'car.js') + sourceFile: path.resolve(appdir.PATH, 'custom-models', 'car.js'), }); }); it('supports `sources` option in `model-config.json`', function() { appdir.createConfigFilesSync({}, {}, { _meta: { - sources: ['./custom-models'] + sources: ['./custom-models'], }, - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('custom-models/car.json', { name: 'Car' }); appdir.writeFileSync('custom-models/car.js', ''); @@ -896,49 +899,49 @@ describe('compiler', function() { expect(instructions.models[0]).to.eql({ name: 'Car', config: { - dataSource: 'db' + dataSource: 'db', }, definition: { - name: 'Car' + name: 'Car', }, - sourceFile: path.resolve(appdir.PATH, 'custom-models', 'car.js') + sourceFile: path.resolve(appdir.PATH, 'custom-models', 'car.js'), }); }); it('supports sources relative to node_modules', function() { appdir.createConfigFilesSync({}, {}, { - User: { dataSource: 'db' } + User: { dataSource: 'db' }, }); var instructions = boot.compile({ appRootDir: appdir.PATH, modelSources: [ 'loopback/common/models', - 'loopback/common/dir-does-not-exist' - ] + 'loopback/common/dir-does-not-exist', + ], }); expect(instructions.models).to.have.length(1); expect(instructions.models[0]).to.eql({ name: 'User', config: { - dataSource: 'db' + dataSource: 'db', }, definition: require('loopback/common/models/user.json'), - sourceFile: require.resolve('loopback/common/models/user.js') + sourceFile: require.resolve('loopback/common/models/user.js'), }); }); it('resolves relative path in `modelSources` option', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('custom-models/car.json', { name: 'Car' }); var appJS = appdir.writeFileSync('custom-models/car.js', ''); var instructions = boot.compile({ appRootDir: appdir.PATH, - modelSources: ['./custom-models'] + modelSources: ['./custom-models'], }); expect(instructions.models).to.have.length(1); @@ -947,7 +950,7 @@ describe('compiler', function() { it('resolves module relative path in `modelSources` option', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('node_modules/custom-models/car.json', { name: 'Car' }); @@ -955,7 +958,7 @@ describe('compiler', function() { var instructions = boot.compile({ appRootDir: appdir.PATH, - modelSources: ['custom-models'] + modelSources: ['custom-models'], }); expect(instructions.models).to.have.length(1); @@ -963,12 +966,12 @@ describe('compiler', function() { }); it('resolves relative path in `sources` option in `model-config.json`', - function() { + function() { appdir.createConfigFilesSync({}, {}, { _meta: { - sources: ['./custom-models'] + sources: ['./custom-models'], }, - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('custom-models/car.json', { name: 'Car' }); var appJS = appdir.writeFileSync('custom-models/car.js', ''); @@ -980,12 +983,12 @@ describe('compiler', function() { }); it('resolves module relative path in `sources` option in model-config.json', - function() { + function() { appdir.createConfigFilesSync({}, {}, { _meta: { - sources: ['custom-models'] + sources: ['custom-models'], }, - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('node_modules/custom-models/car.json', { name: 'Car' }); @@ -1000,7 +1003,7 @@ describe('compiler', function() { it('handles model definitions with no code', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', { name: 'Car' }); @@ -1009,18 +1012,18 @@ describe('compiler', function() { expect(instructions.models).to.eql([{ name: 'Car', config: { - dataSource: 'db' + dataSource: 'db', }, definition: { - name: 'Car' + name: 'Car', }, - sourceFile: undefined + sourceFile: undefined, }]); }); it('excludes models not listed in `model-config.json`', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', { name: 'Car' }); appdir.writeConfigFileSync('models/bar.json', { name: 'Bar' }); @@ -1033,14 +1036,14 @@ describe('compiler', function() { it('includes models used as Base models', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', { name: 'Car', - base: 'Vehicle' + base: 'Vehicle', }); appdir.writeConfigFileSync('models/vehicle.json', { - name: 'Vehicle' + name: 'Vehicle', }); var instructions = boot.compile(appdir.PATH); @@ -1053,11 +1056,11 @@ describe('compiler', function() { it('excludes pre-built base models', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', { name: 'Car', - base: 'Model' + base: 'Model', }); var instructions = boot.compile(appdir.PATH); @@ -1070,18 +1073,18 @@ describe('compiler', function() { appdir.createConfigFilesSync({}, {}, { Vehicle: { dataSource: 'db' }, FlyingCar: { dataSource: 'db' }, - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', { name: 'Car', - base: 'Vehicle' + base: 'Vehicle', }); appdir.writeConfigFileSync('models/vehicle.json', { - name: 'Vehicle' + name: 'Vehicle', }); appdir.writeConfigFileSync('models/flying-car.json', { name: 'FlyingCar', - base: 'Car' + base: 'Car', }); var instructions = boot.compile(appdir.PATH); @@ -1093,15 +1096,15 @@ describe('compiler', function() { it('detects circular Model dependencies', function() { appdir.createConfigFilesSync({}, {}, { Vehicle: { dataSource: 'db' }, - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', { name: 'Car', - base: 'Vehicle' + base: 'Vehicle', }); appdir.writeConfigFileSync('models/vehicle.json', { name: 'Vehicle', - base: 'Car' + base: 'Car', }); expect(function() { boot.compile(appdir.PATH); }) @@ -1110,7 +1113,7 @@ describe('compiler', function() { it('uses file name as default value for model name', function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', {}); @@ -1121,9 +1124,9 @@ describe('compiler', function() { }); it('uses `OrderItem` as default model name for file with name `order-item`', - function() { + function() { appdir.createConfigFilesSync({}, {}, { - OrderItem: { dataSource: 'db' } + OrderItem: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/order-item.json', {}); @@ -1134,9 +1137,9 @@ describe('compiler', function() { }); it('uses `OrderItem` as default model name for file with name `order_item`', - function() { + function() { appdir.createConfigFilesSync({}, {}, { - OrderItem: { dataSource: 'db' } + OrderItem: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/order_item.json', {}); @@ -1147,9 +1150,9 @@ describe('compiler', function() { }); it('uses `OrderItem` as default model name for file with name `order item`', - function() { + function() { appdir.createConfigFilesSync({}, {}, { - OrderItem: { dataSource: 'db' } + OrderItem: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/order item.json', {}); @@ -1160,11 +1163,11 @@ describe('compiler', function() { }); it('overrides `default model name` by `name` in model definition', - function() { + function() { appdir.createConfigFilesSync({}, {}, { - overrideCar: { dataSource: 'db' } + overrideCar: { dataSource: 'db' }, }); - appdir.writeConfigFileSync('models/car.json', { name: 'overrideCar'}); + appdir.writeConfigFileSync('models/car.json', { name: 'overrideCar' }); var instructions = boot.compile(appdir.PATH); @@ -1174,20 +1177,20 @@ describe('compiler', function() { it('overwrites model with same default name', function() { appdir.createConfigFilesSync({}, {}, { - 'OrderItem': { dataSource: 'db' } + 'OrderItem': { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/order-item.json', { properties: { - price: { type: 'number' } - } + price: { type: 'number' }, + }, }); appdir.writeFileSync('models/order-item.js', ''); appdir.writeConfigFileSync('models/orderItem.json', { properties: { - quantity: { type: 'number' } - } + quantity: { type: 'number' }, + }, }); var appJS = appdir.writeFileSync('models/orderItem.js', ''); @@ -1196,36 +1199,36 @@ describe('compiler', function() { expect(instructions.models).to.eql([{ name: 'OrderItem', config: { - dataSource: 'db' + dataSource: 'db', }, definition: { name: 'OrderItem', properties: { - quantity: {type: 'number'} - } + quantity: { type: 'number' }, + }, }, - sourceFile: appJS + sourceFile: appJS, }]); }); it('overwrites model with same name in model definition', function() { appdir.createConfigFilesSync({}, {}, { - 'customOrder': { dataSource: 'db' } + 'customOrder': { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/order1.json', { - name : 'customOrder', + name: 'customOrder', properties: { - price: { type: 'number' } - } + price: { type: 'number' }, + }, }); appdir.writeFileSync('models/order1.js', ''); appdir.writeConfigFileSync('models/order2.json', { - name : 'customOrder', + name: 'customOrder', properties: { - quantity: { type: 'number' } - } + quantity: { type: 'number' }, + }, }); var appJS = appdir.writeFileSync('models/order2.js', ''); @@ -1234,15 +1237,15 @@ describe('compiler', function() { expect(instructions.models).to.eql([{ name: 'customOrder', config: { - dataSource: 'db' + dataSource: 'db', }, definition: { name: 'customOrder', properties: { - quantity: {type: 'number'} - } + quantity: { type: 'number' }, + }, }, - sourceFile: appJS + sourceFile: appJS, }]); }); @@ -1263,7 +1266,7 @@ describe('compiler', function() { var instructions = boot.compile({ appRootDir: appdir.PATH, - mixinDirs: mixinDirs + mixinDirs: mixinDirs, }); expect(instructions.mixins[0].sourceFile).to.eql(appJS); @@ -1288,11 +1291,11 @@ describe('compiler', function() { describe(' - mixinSources', function() { beforeEach(function() { appdir.createConfigFilesSync({}, {}, { - Car: { dataSource: 'db' } + Car: { dataSource: 'db' }, }); appdir.writeConfigFileSync('models/car.json', { name: 'Car', - mixins: {'TimeStamps': {} } + mixins: { 'TimeStamps': {}}, }); }); @@ -1301,7 +1304,7 @@ describe('compiler', function() { var instructions = boot.compile({ appRootDir: appdir.PATH, - mixinSources: mixinSources + mixinSources: mixinSources, }); expect(instructions.mixins[0].sourceFile).to.eql(appJS); @@ -1318,7 +1321,7 @@ describe('compiler', function() { }); it('resolves module relative path in `mixinSources` option', - function() { + function() { verifyMixinIsFoundViaMixinSources( 'node_modules/custom-mixins/time-stamps.js', ['custom-mixins']); @@ -1327,11 +1330,11 @@ describe('compiler', function() { it('supports `mixins` option in `model-config.json`', function() { appdir.createConfigFilesSync({}, {}, { _meta: { - mixins: ['./custom-mixins'] + mixins: ['./custom-mixins'], }, Car: { - dataSource: 'db' - } + dataSource: 'db', + }, }); var appJS = appdir.writeFileSync('custom-mixins/time-stamps.js', ''); @@ -1357,12 +1360,12 @@ describe('compiler', function() { it('loads mixins from model using mixin name in JSON file', function() { var appJS = appdir.writeFileSync('mixins/time-stamps.js', ''); appdir.writeConfigFileSync('mixins/time-stamps.json', { - name: 'Timestamping' + name: 'Timestamping', }); appdir.writeConfigFileSync('models/car.json', { name: 'Car', - mixins: {'Timestamping': {} } + mixins: { 'Timestamping': {}}, }); var instructions = boot.compile(appdir.PATH); @@ -1371,13 +1374,13 @@ describe('compiler', function() { }); it('loads mixin only once for dirs common to mixinDirs & mixinSources', - function() { + function() { var appJS = appdir.writeFileSync('custom-mixins/time-stamps.js', ''); var options = { appRootDir: appdir.PATH, mixinDirs: ['./custom-mixins'], - mixinSources: ['./custom-mixins'] + mixinSources: ['./custom-mixins'], }; var instructions = boot.compile(options); @@ -1386,14 +1389,14 @@ describe('compiler', function() { }); it('loads mixin from mixinSources, when it is also found in mixinDirs', - function() { + function() { appdir.writeFileSync('mixinDir/time-stamps.js', ''); var appJS = appdir.writeFileSync('mixinSource/time-stamps.js', ''); var options = { appRootDir: appdir.PATH, mixinDirs: ['./mixinDir'], - mixinSources: ['./mixinSource'] + mixinSources: ['./mixinSource'], }; var instructions = boot.compile(options); @@ -1407,7 +1410,7 @@ describe('compiler', function() { var options = { appRootDir: appdir.PATH, - mixinSources: ['./mixins1', './mixins2'] + mixinSources: ['./mixins1', './mixins2'], }; var instructions = boot.compile(options); @@ -1436,7 +1439,7 @@ describe('compiler', function() { var mixinNames = mixins.map(getNameProperty); expect(mixinNames).to.eql([ - 'CamelCase', 'Foo', 'PascalCase', 'SpaceName', 'TimeStamps' + 'CamelCase', 'Foo', 'PascalCase', 'SpaceName', 'TimeStamps', ]); }); @@ -1448,7 +1451,7 @@ describe('compiler', function() { var mixinNames = mixins.map(getNameProperty); expect(mixinNames).to.eql([ - 'camel-case', 'foo', 'pascal-case', 'space-name', 'time-stamps' + 'camel-case', 'foo', 'pascal-case', 'space-name', 'time-stamps', ]); }); @@ -1461,7 +1464,7 @@ describe('compiler', function() { var mixinNames = mixins.map(getNameProperty); expect(mixinNames).to.eql([ - 'CAMELCASE', 'FOO', 'PASCALCASE', 'SPACE NAME', 'TIME-STAMPS' + 'CAMELCASE', 'FOO', 'PASCALCASE', 'SPACE NAME', 'TIME-STAMPS', ]); }); @@ -1473,7 +1476,7 @@ describe('compiler', function() { var mixinNames = mixins.map(getNameProperty); expect(mixinNames).to.eql([ - 'camelCase', 'foo', 'PascalCase', 'space name', 'time-stamps' + 'camelCase', 'foo', 'PascalCase', 'space name', 'time-stamps', ]); }); @@ -1485,7 +1488,7 @@ describe('compiler', function() { var mixinNames = mixins.map(getNameProperty); expect(mixinNames).to.eql([ - 'camelCase', 'foo', 'PascalCase', 'space name', 'time-stamps' + 'camelCase', 'foo', 'PascalCase', 'space name', 'time-stamps', ]); }); @@ -1496,7 +1499,7 @@ describe('compiler', function() { var mixinNames = mixins.map(getNameProperty); expect(mixinNames).to.eql([ - 'CamelCase', 'Foo', 'PascalCase', 'SpaceName', 'TimeStamps' + 'CamelCase', 'Foo', 'PascalCase', 'SpaceName', 'TimeStamps', ]); }); @@ -1510,10 +1513,10 @@ describe('compiler', function() { it('overrides default mixin name, by `name` in JSON', function() { appdir.writeFileSync('mixins/foo.js', ''); - appdir.writeConfigFileSync('mixins/foo.json', {name: 'fooBar'}); + appdir.writeConfigFileSync('mixins/foo.json', { name: 'fooBar' }); var options = { appRootDir: appdir.PATH, - mixinDirs: ['./mixins'] + mixinDirs: ['./mixins'], }; var instructions = boot.compile(options); @@ -1537,8 +1540,8 @@ describe('compiler', function() { { name: 'FooBar', description: 'JSON file name same as JS file name', - sourceFile: appJS - } + sourceFile: appJS, + }, ]); }); }); @@ -1552,11 +1555,11 @@ describe('compiler', function() { initial: { }, custom: { - } + }, }; json.custom[middlewareId] = { - params: 'some-config-data' + params: 'some-config-data', }; appdir.writeConfigFileSync('middleware.json', json); @@ -1584,10 +1587,10 @@ describe('compiler', function() { sourceFile: sourceFile, config: { phase: 'custom', - params: 'some-config-data' - } - } - ] + params: 'some-config-data', + }, + }, + ], }); } @@ -1623,8 +1626,8 @@ describe('compiler', function() { it('fails when a module middleware cannot be resolved', function() { appdir.writeConfigFileSync('middleware.json', { final: { - 'loopback/path-does-not-exist': { } - } + 'loopback/path-does-not-exist': { }, + }, }); expect(function() { boot.compile(appdir.PATH); }) @@ -1632,13 +1635,13 @@ describe('compiler', function() { }); it('does not fail when an optional middleware cannot be resolved', - function() { + function() { appdir.writeConfigFileSync('middleware.json', { final: { 'loopback/path-does-not-exist': { - optional: 'this middleware is optional' - } - } + optional: 'this middleware is optional', + }, + }, }); expect(function() { boot.compile(appdir.PATH); }) @@ -1649,8 +1652,8 @@ describe('compiler', function() { function() { appdir.writeConfigFileSync('middleware.json', { final: { - 'loopback#path-does-not-exist': { } - } + 'loopback#path-does-not-exist': { }, + }, }); expect(function() { @@ -1664,9 +1667,9 @@ describe('compiler', function() { appdir.writeConfigFileSync('middleware.json', { final: { 'loopback#path-does-not-exist': { - optional: 'this middleware is optional' - } - } + optional: 'this middleware is optional', + }, + }, }); expect(function() { boot.compile(appdir.PATH); }) @@ -1678,8 +1681,8 @@ describe('compiler', function() { appdir.writeConfigFileSync('./middleware.json', { routes: { // resolves to ./my-middleware.js - './my-middleware': { } - } + './my-middleware': { }, + }, }); var instructions = boot.compile(appdir.PATH); @@ -1688,8 +1691,8 @@ describe('compiler', function() { phases: ['routes'], middleware: [{ sourceFile: path.resolve(appdir.PATH, 'my-middleware.js'), - config: { phase: 'routes' } - }] + config: { phase: 'routes' }, + }], }); }); @@ -1698,26 +1701,26 @@ describe('compiler', function() { routes: { './middleware': { params: { - key: 'initial value' - } - } - } + key: 'initial value', + }, + }, + }, }); appdir.writeConfigFileSync('./middleware.local.json', { routes: { './middleware': { params: { - key: 'custom value' - } - } - } + key: 'custom value', + }, + }, + }, }); var instructions = boot.compile(appdir.PATH); expectFirstMiddlewareParams(instructions).to.eql({ - key: 'custom value' + key: 'custom value', }); }); @@ -1726,18 +1729,18 @@ describe('compiler', function() { routes: { './middleware': { params: { - key: 'initial value' - } - } - } + key: 'initial value', + }, + }, + }, }); appdir.writeConfigFileSync('./middleware.local.json', { routes: { './middleware': { - enabled: false - } - } + enabled: false, + }, + }, }); var instructions = boot.compile(appdir.PATH); @@ -1756,19 +1759,19 @@ describe('compiler', function() { config: { phase: 'routes', params: { - key: 'initial value' - } - } + key: 'initial value', + }, + }, }, { sourceFile: path.resolve(appdir.PATH, 'middleware'), config: { phase: 'routes', params: { - key: 'custom value' - } - } - } + key: 'custom value', + }, + }, + }, ]); } @@ -1777,20 +1780,20 @@ describe('compiler', function() { routes: { './middleware': [{ params: { - key: 'initial value' - } - }] - } + key: 'initial value', + }, + }], + }, }); appdir.writeConfigFileSync('./middleware.local.json', { routes: { './middleware': [{ params: { - key: 'custom value' - } - }] - } + key: 'custom value', + }, + }], + }, }); verifyMiddlewareConfig(); @@ -1801,20 +1804,20 @@ describe('compiler', function() { routes: { './middleware': { params: { - key: 'initial value' - } - } - } + key: 'initial value', + }, + }, + }, }); appdir.writeConfigFileSync('./middleware.local.json', { routes: { './middleware': [{ params: { - key: 'custom value' - } - }] - } + key: 'custom value', + }, + }], + }, }); verifyMiddlewareConfig(); @@ -1825,20 +1828,20 @@ describe('compiler', function() { routes: { './middleware': [{ params: { - key: 'initial value' - } - }] - } + key: 'initial value', + }, + }], + }, }); appdir.writeConfigFileSync('./middleware.local.json', { routes: { './middleware': { params: { - key: 'custom value' - } - } - } + key: 'custom value', + }, + }, + }, }); verifyMiddlewareConfig(); @@ -1847,18 +1850,18 @@ describe('compiler', function() { it('merges config.params array to empty object', function() { appdir.writeConfigFileSync('./middleware.json', { routes: { - './middleware': {} - } + './middleware': {}, + }, }); appdir.writeConfigFileSync('./middleware.local.json', { routes: { './middleware': [{ params: { - key: 'custom value' - } - }] - } + key: 'custom value', + }, + }], + }, }); var instructions = boot.compile(appdir.PATH); @@ -1870,10 +1873,10 @@ describe('compiler', function() { config: { phase: 'routes', params: { - key: 'custom value' - } - } - } + key: 'custom value', + }, + }, + }, ]); }); @@ -1883,10 +1886,10 @@ describe('compiler', function() { './middleware': [{ name: 'a', params: { - key: 'initial value' - } - }] - } + key: 'initial value', + }, + }], + }, }); appdir.writeConfigFileSync('./middleware.local.json', { @@ -1894,14 +1897,14 @@ describe('compiler', function() { './middleware': [{ name: 'a', params: { - key: 'custom value' - } + key: 'custom value', + }, }, { params: { - key: '2nd value' - } - }] - } + key: '2nd value', + }, + }], + }, }); var instructions = boot.compile(appdir.PATH); @@ -1914,19 +1917,19 @@ describe('compiler', function() { name: 'a', phase: 'routes', params: { - key: 'custom value' - } - } + key: 'custom value', + }, + }, }, { sourceFile: path.resolve(appdir.PATH, 'middleware'), config: { phase: 'routes', params: { - key: '2nd value' - } - } - } + key: '2nd value', + }, + }, + }, ]); }); @@ -1936,12 +1939,12 @@ describe('compiler', function() { }, 'custom:before': { 'loopback/server/middleware/url-not-found': { - params: 'some-config-data' - } + params: 'some-config-data', + }, }, 'custom:after': { - } + }, }); var instructions = boot.compile(appdir.PATH); @@ -1954,8 +1957,8 @@ describe('compiler', function() { require.resolve('loopback/server/middleware/url-not-found'), config: { phase: 'custom:before', - params: 'some-config-data' - } + params: 'some-config-data', + }, }]); }); @@ -1965,13 +1968,13 @@ describe('compiler', function() { 'final': { './my-middleware': [ { - params: 'first' + params: 'first', }, { - params: 'second' - } - ] - } + params: 'second', + }, + ], + }, }); var instructions = boot.compile(appdir.PATH); @@ -1982,24 +1985,24 @@ describe('compiler', function() { sourceFile: path.resolve(appdir.PATH, 'my-middleware.js'), config: { phase: 'final', - params: 'first' - } + params: 'first', + }, }, { sourceFile: path.resolve(appdir.PATH, 'my-middleware.js'), config: { phase: 'final', - params: 'second' - } - } + params: 'second', + }, + }, ]); }); it('supports shorthand notation for middleware paths', function() { appdir.writeConfigFileSync('middleware.json', { 'final': { - 'loopback#url-not-found': {} - } + 'loopback#url-not-found': {}, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2012,8 +2015,8 @@ describe('compiler', function() { appdir.writeConfigFileSync('middleware.json', { 'routes': { './middleware/index#myMiddleware': { - } - } + }, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2030,8 +2033,8 @@ describe('compiler', function() { function() { appdir.writeConfigFileSync('middleware.json', { 'final': { - 'loopback#errorHandler': {} - } + 'loopback#errorHandler': {}, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2052,8 +2055,8 @@ describe('compiler', function() { appdir.writeConfigFileSync('middleware.json', { 'initial': { - 'handler': {} - } + 'handler': {}, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2068,8 +2071,8 @@ describe('compiler', function() { appdir.writeFileSync('node_modules/my-middleware.js', ''); appdir.writeConfigFileSync('middleware.json', { 'routes': { - './my-middleware': {} - } + './my-middleware': {}, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2080,13 +2083,13 @@ describe('compiler', function() { }); it('does not treat module relative path as `appRootDir` relative', - function() { + function() { appdir.writeFileSync('./my-middleware.js', ''); var moduleJS = appdir.writeFileSync('node_modules/my-middleware.js', ''); appdir.writeConfigFileSync('middleware.json', { 'routes': { - 'my-middleware': {} - } + 'my-middleware': {}, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2100,8 +2103,8 @@ describe('compiler', function() { var coffee = appdir.writeFileSync('my-middleware.coffee', ''); appdir.writeConfigFileSync('middleware.json', { 'routes': { - './my-middleware': {} - } + './my-middleware': {}, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2111,14 +2114,14 @@ describe('compiler', function() { }); it('loads coffeescript from middleware under node_modules', - function() { + function() { var file = appdir.writeFileSync('node_modules/my-middleware/index.coffee', ''); appdir.writeFileSync('node_modules/my-middleware/index.json', ''); appdir.writeConfigFileSync('middleware.json', { 'routes': { - 'my-middleware': {} - } + 'my-middleware': {}, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2129,13 +2132,13 @@ describe('compiler', function() { }); it('prefers coffeescript over json for relative middleware path', - function() { + function() { var coffee = appdir.writeFileSync('my-middleware.coffee', ''); appdir.writeFileSync('my-middleware.json', ''); appdir.writeConfigFileSync('middleware.json', { 'routes': { - './my-middleware': {} - } + './my-middleware': {}, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2146,14 +2149,14 @@ describe('compiler', function() { }); it('prefers coffeescript over json for module relative middleware path', - function() { + function() { var coffee = appdir.writeFileSync('node_modules/my-middleware.coffee', ''); appdir.writeFileSync('node_modules/my-middleware.json', ''); appdir.writeConfigFileSync('middleware.json', { 'routes': { - 'my-middleware': {} - } + 'my-middleware': {}, + }, }); var instructions = boot.compile(appdir.PATH); @@ -2166,7 +2169,7 @@ describe('compiler', function() { describe('config with relative paths in params', function() { var RELATIVE_PATH_PARAMS = [ '$!./here', - '$!../there' + '$!../there', ]; var absolutePathParams; @@ -2208,9 +2211,9 @@ describe('compiler', function() { it('converts paths in nested properties', function() { givenMiddlewareEntrySync({ params: { nestedObject: { - path: RELATIVE_PATH_PARAMS[0] + path: RELATIVE_PATH_PARAMS[0], }, - nestedArray: RELATIVE_PATH_PARAMS + nestedArray: RELATIVE_PATH_PARAMS, }}); var instructions = boot.compile(appdir.PATH); @@ -2218,15 +2221,15 @@ describe('compiler', function() { expectFirstMiddlewareParams(instructions) .to.eql({ nestedObject: { - path: absolutePathParams[0] + path: absolutePathParams[0], }, - nestedArray: absolutePathParams + nestedArray: absolutePathParams, }); }); it('does not convert values not starting with `./` or `../`', function() { var PARAMS = ['$!.somerc', '$!/root', '$!hello!']; - givenMiddlewareEntrySync({ params: PARAMS}); + givenMiddlewareEntrySync({ params: PARAMS }); var instructions = boot.compile(appdir.PATH); @@ -2240,15 +2243,15 @@ describe('compiler', function() { function testComponentConfigsMerge(alternativeDirTest) { appdir.createConfigFilesSync(); appdir.writeConfigFileSync('component-config.json', { - debug: { option: 'value' } + debug: { option: 'value' }, }); appdir.writeConfigFileSync('component-config.local.json', { - debug: { local: 'applied' } + debug: { local: 'applied' }, }); var env = process.env.NODE_ENV || 'development'; appdir.writeConfigFileSync('component-config.' + env + '.json', { - debug: { env: 'applied' } + debug: { env: 'applied' }, }); var instructions; @@ -2283,8 +2286,8 @@ describe('compiler', function() { config: { option: 'value', local: 'applied', - env: 'applied' - } + env: 'applied', + }, }); } @@ -2299,7 +2302,7 @@ describe('compiler', function() { it('loads component relative to appRootDir', function() { appdir.writeConfigFileSync('./component-config.json', { - './index': { } + './index': { }, }); var appJS = appdir.writeConfigFileSync('index.js', ''); @@ -2311,7 +2314,7 @@ describe('compiler', function() { it('loads component relative to node modules', function() { appdir.writeConfigFileSync('component-config.json', { - 'mycomponent': { } + 'mycomponent': { }, }); var js = appdir.writeConfigFileSync('node_modules/mycomponent/index.js', ''); @@ -2323,9 +2326,9 @@ describe('compiler', function() { }); it('retains backward compatibility for non-relative path in `appRootDir`', - function() { + function() { appdir.writeConfigFileSync('component-config.json', { - 'my-component/component.js': { } + 'my-component/component.js': { }, }); appdir.writeConfigFileSync('./my-component/component.js', ''); @@ -2334,9 +2337,9 @@ describe('compiler', function() { }); it('prefers coffeescript over json for relative path component', - function() { + function() { appdir.writeConfigFileSync('component-config.json', { - './component': { } + './component': { }, }); var coffee = appdir.writeFileSync('component.coffee', ''); @@ -2350,9 +2353,9 @@ describe('compiler', function() { }); it('prefers coffeescript over json for module relative component path', - function() { + function() { appdir.writeConfigFileSync('component-config.json', { - 'component': { } + 'component': { }, }); var coffee = appdir.writeFileSync('node_modules/component.coffee', ''); @@ -2364,7 +2367,6 @@ describe('compiler', function() { expect(instructions.components[0]).have.property( 'sourceFile', coffee); }); - }); }); @@ -2376,8 +2378,8 @@ function givenMiddlewareEntrySync(config) { appdir.writeConfigFileSync('middleware.json', { initial: { // resolves to ./middleware.json - './middleware': config - } + './middleware': config, + }, }); } diff --git a/test/executor.test.js b/test/executor.test.js index a6f716b..e051510 100644 --- a/test/executor.test.js +++ b/test/executor.test.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var async = require('async'); var boot = require('../'); var path = require('path'); @@ -37,22 +42,22 @@ describe('executor', function() { host: '127.0.0.1', restApiRoot: '/rest-api', foo: { bar: 'bat' }, - baz: true + baz: true, }, models: [ { name: 'User', config: { - dataSource: 'the-db' - } - } + dataSource: 'the-db', + }, + }, ], dataSources: { 'the-db': { connector: 'memory', - defaultForType: 'db' - } - } + defaultForType: 'db', + }, + }, }); describe('when booting', function() { @@ -66,15 +71,15 @@ describe('executor', function() { }); }); - it('should emit the `booted` event', function(done) { + it('should emit the `booted` event in the next tick', function(done) { + boot.execute(app, dummyInstructions, function(err) { + expect(err).to.be.undefined(); + }); app.on('booted', function() { // This test fails with a timeout when the `booted` event has not been // emitted correctly done(); }); - boot.execute(app, dummyInstructions, function(err) { - expect(err).to.be.undefined(); - }); }); it('should work when called synchronously', function() { @@ -109,9 +114,9 @@ describe('executor', function() { name: 'Customer', base: 'User', }, - sourceFile: path.resolve(appdir.PATH, 'models', 'Customer.js') - } - ] + sourceFile: path.resolve(appdir.PATH, 'models', 'Customer.js'), + }, + ], })); expect(app.models.Customer).to.exist(); @@ -127,9 +132,9 @@ describe('executor', function() { name: 'Vehicle', config: undefined, definition: { - name: 'Vehicle' + name: 'Vehicle', }, - sourceFile: undefined + sourceFile: undefined, }, { name: 'Car', @@ -138,9 +143,9 @@ describe('executor', function() { name: 'Car', base: 'Vehicle', }, - sourceFile: undefined + sourceFile: undefined, }, - ] + ], })); expect(Object.keys(app.models)).to.eql(['Car']); @@ -166,15 +171,15 @@ describe('executor', function() { name: 'Customer', config: { dataSource: 'db' }, definition: { name: 'Customer' }, - sourceFile: path.resolve(appdir.PATH, 'models', 'Customer.js') + sourceFile: path.resolve(appdir.PATH, 'models', 'Customer.js'), }, { name: 'UniqueName', config: { dataSource: 'db' }, definition: { name: 'UniqueName' }, - sourceFile: undefined - } - ] + sourceFile: undefined, + }, + ], })); expect(app.models.Customer._modelsWhenAttached).to.include('UniqueName'); @@ -188,9 +193,9 @@ describe('executor', function() { name: 'LocalCustomer', config: { dataSource: 'db' }, definition: { name: 'LocalCustomer' }, - sourceFile: undefined - } - ] + sourceFile: undefined, + }, + ], })); expect(Object.keys(loopback.registry.modelBuilder.models), 'global models') @@ -204,7 +209,7 @@ describe('executor', function() { 'require("doesnt-exist"); module.exports = {};'); function doBoot() { - boot.execute(app, someInstructions({ files: { boot: [file] } })); + boot.execute(app, someInstructions({ files: { boot: [file] }})); } expect(doBoot).to.throw(/Cannot find module \'doesnt-exist\'/); @@ -236,7 +241,7 @@ describe('executor', function() { require.resolve('loopback/common/models/user.json') ), config: { dataSource: 'db' }, - sourceFile: require.resolve('loopback/common/models/user.js') + sourceFile: require.resolve('loopback/common/models/user.js'), }; builtinModel.definition.redefined = true; @@ -260,7 +265,7 @@ describe('executor', function() { 'barLoaded', 'barSyncLoaded', 'fooLoaded', - 'barStarted' + 'barStarted', ]); // bar finished happens in the next tick @@ -272,7 +277,7 @@ describe('executor', function() { 'fooLoaded', 'barStarted', 'barFinished', - 'barSyncExecuted' + 'barSyncExecuted', ]); done(); }, 10); @@ -288,7 +293,7 @@ describe('executor', function() { 'fooLoaded', 'barStarted', 'barFinished', - 'barSyncExecuted' + 'barSyncExecuted', ]); done(); }); @@ -306,11 +311,11 @@ describe('executor', function() { 'function(Model, options) {}'); appdir.writeConfigFileSync('custom-mixins/time-stamps.json', { - name: 'Timestamping' + name: 'Timestamping', }); options = { - appRootDir: appdir.PATH + appRootDir: appdir.PATH, }; }); @@ -357,8 +362,8 @@ describe('executor', function() { boot.execute(app, someInstructions({ config: { port: undefined, - host: undefined - } + host: undefined, + }, })); } @@ -388,6 +393,7 @@ describe('executor', function() { it('should prioritize host sources', function() { // jscs:disable requireCamelCaseOrUpperCaseIdentifiers + /*eslint-disable camelcase*/ process.env.npm_config_host = randomHost(); process.env.OPENSHIFT_SLS_IP = randomHost(); process.env.OPENSHIFT_NODEJS_IP = randomHost(); @@ -397,9 +403,11 @@ describe('executor', function() { bootWithDefaults(); assert.equal(app.get('host'), process.env.npm_config_host); + /*eslint-enable camelcase*/ }); it('should prioritize port sources', function() { + /*eslint-disable camelcase*/ process.env.npm_config_port = randomPort(); process.env.OPENSHIFT_SLS_PORT = randomPort(); process.env.OPENSHIFT_NODEJS_PORT = randomPort(); @@ -409,6 +417,7 @@ describe('executor', function() { bootWithDefaults(); assert.equal(app.get('port'), process.env.npm_config_port); + /*eslint-enable camelcase*/ }); function randomHost() { @@ -420,24 +429,28 @@ describe('executor', function() { } it('should honor 0 for free port', function() { - boot.execute(app, someInstructions({ config: { port: 0 } })); + boot.execute(app, someInstructions({ config: { port: 0 }})); assert.equal(app.get('port'), 0); }); it('should default to port 3000', function() { - boot.execute(app, someInstructions({ config: { port: undefined } })); + boot.execute(app, someInstructions({ config: { port: undefined }})); assert.equal(app.get('port'), 3000); }); it('should respect named pipes port values in ENV', function() { var NAMED_PORT = '\\.\\pipe\\test'; process.env.PORT = NAMED_PORT; - boot.execute(app, someInstructions({ config: { port: 3000 } })); + boot.execute(app, someInstructions({ config: { port: 3000 }})); assert.equal(app.get('port'), NAMED_PORT); }); }); describe('with middleware.json', function() { + beforeEach(function() { + delete process.env.restApiRoot; + }); + it('should parse a simple config variable', function(done) { boot.execute(app, simpleMiddlewareConfig('routes', { path: '${restApiRoot}' } @@ -450,6 +463,36 @@ describe('executor', function() { }); }); + it('should parse simple config variable from env var', function(done) { + process.env.restApiRoot = '/url-from-env-var'; + boot.execute(app, simpleMiddlewareConfig('routes', + { path: '${restApiRoot}' } + )); + + supertest(app).get('/url-from-env-var').end(function(err, res) { + if (err) return done(err); + expect(res.body.path).to.equal('/url-from-env-var'); + done(); + }); + }); + + it('dynamic variable from `env var` should have' + + ' precedence over app.get()', function(done) { + process.env.restApiRoot = '/url-from-env-var'; + var bootInstructions; + bootInstructions = simpleMiddlewareConfig('routes', + { path: '${restApiRoot}' }); + bootInstructions.config = { restApiRoot: '/url-from-config' }; + boot.execute(app, someInstructions(bootInstructions)); + + supertest(app).get('/url-from-env-var').end(function(err, res) { + if (err) return done(err); + expect(app.get('restApiRoot')).to.equal('/url-from-config'); + expect(res.body.path).to.equal('/url-from-env-var'); + done(); + }); + }); + it('should parse multiple config variables', function(done) { boot.execute(app, simpleMiddlewareConfig('routes', { path: '${restApiRoot}', env: '${env}' } @@ -479,13 +522,13 @@ describe('executor', function() { it('should parse config variables in an object', function(done) { boot.execute(app, simpleMiddlewareConfig('routes', - { info: { path: '${restApiRoot}' } } + { info: { path: '${restApiRoot}' }} )); supertest(app).get('/').end(function(err, res) { if (err) return done(err); expect(res.body.info).to.eql({ - path: app.get('restApiRoot') + path: app.get('restApiRoot'), }); done(); }); @@ -493,13 +536,30 @@ describe('executor', function() { it('should parse config variables in a nested object', function(done) { boot.execute(app, simpleMiddlewareConfig('routes', - { nested: { info: { path: '${restApiRoot}' } } } + { nested: { info: { path: '${restApiRoot}' }}} )); supertest(app).get('/').end(function(err, res) { if (err) return done(err); expect(res.body.nested).to.eql({ - info: { path: app.get('restApiRoot') } + info: { path: app.get('restApiRoot') }, + }); + done(); + }); + }); + + it('should parse config variables with null values', function(done) { + boot.execute(app, simpleMiddlewareConfig('routes', + { nested: { info: { path: '${restApiRoot}', some: null }}} + )); + + supertest(app).get('/').end(function(err, res) { + if (err) return done(err); + expect(res.body.nested).to.eql({ + info: { + path: app.get('restApiRoot'), + some: null, + }, }); done(); }); @@ -509,7 +569,7 @@ describe('executor', function() { var invalidDataTypes = [undefined, function() {}]; async.each(invalidDataTypes, function(invalidDataType, cb) { var config = simpleMiddlewareConfig('routes', { - path: invalidDataType + path: invalidDataType, }); boot.execute(app, config); @@ -525,7 +585,7 @@ describe('executor', function() { it('should parse valid config variables', function(done) { var config = simpleMiddlewareConfig('routes', { - props: ['a', '${vVar}', 1, true, function() {}, {x:1, y: '${y}'}] + props: ['a', '${vVar}', 1, true, function() {}, { x: 1, y: '${y}' }], }); boot.execute(app, config); @@ -552,6 +612,10 @@ describe('executor', function() { }); describe('with component-config.json', function() { + beforeEach(function() { + delete process.env.DYNAMIC_ENVVAR; + delete process.env.DYNAMIC_VARIABLE; + }); it('should parse a simple config variable', function(done) { boot.execute(app, simpleComponentConfig( @@ -565,6 +629,46 @@ describe('executor', function() { }); }); + it('should parse config from `env-var` and `config`', function(done) { + var bootInstructions = simpleComponentConfig( + { + path: '${restApiRoot}', + fromConfig: '${DYNAMIC_CONFIG}', + fromEnvVar: '${DYNAMIC_ENVVAR}', + } + ); + + // result should get value from config.json + bootInstructions.config['DYNAMIC_CONFIG'] = 'FOOBAR-CONFIG'; + // result should get value from env var + process.env.DYNAMIC_ENVVAR = 'FOOBAR-ENVVAR'; + + boot.execute(app, bootInstructions); + supertest(app).get('/component').end(function(err, res) { + if (err) return done(err); + expect(res.body.fromConfig).to.equal('FOOBAR-CONFIG'); + expect(res.body.fromEnvVar).to.equal('FOOBAR-ENVVAR'); + done(); + }); + }); + + it('`env-var` should have precedence over `config`', function(done) { + var key = 'DYNAMIC_VARIABLE'; + var bootInstructions = simpleComponentConfig({ + path: '${restApiRoot}', + isDynamic: '${' + key + '}', + }); + bootInstructions.config[key] = 'should be overwritten'; + process.env[key] = 'successfully overwritten'; + + boot.execute(app, bootInstructions); + supertest(app).get('/component').end(function(err, res) { + if (err) return done(err); + expect(res.body.isDynamic).to.equal('successfully overwritten'); + done(); + }); + }); + it('should parse multiple config variables', function(done) { boot.execute(app, simpleComponentConfig( { path: '${restApiRoot}', env: '${env}' } @@ -594,13 +698,13 @@ describe('executor', function() { it('should parse config variables in an object', function(done) { boot.execute(app, simpleComponentConfig( - { info: { path: '${restApiRoot}' } } + { info: { path: '${restApiRoot}' }} )); supertest(app).get('/component').end(function(err, res) { if (err) return done(err); expect(res.body.info).to.eql({ - path: app.get('restApiRoot') + path: app.get('restApiRoot'), }); done(); }); @@ -608,18 +712,17 @@ describe('executor', function() { it('should parse config variables in a nested object', function(done) { boot.execute(app, simpleComponentConfig( - { nested: { info: { path: '${restApiRoot}' } } } + { nested: { info: { path: '${restApiRoot}' }}} )); supertest(app).get('/component').end(function(err, res) { if (err) return done(err); expect(res.body.nested).to.eql({ - info: { path: app.get('restApiRoot') } + info: { path: app.get('restApiRoot') }, }); done(); }); }); - }); it('calls function exported by boot/init.js', function() { @@ -627,7 +730,7 @@ describe('executor', function() { 'module.exports = function(app) { app.fnCalled = true; };'); delete app.fnCalled; - boot.execute(app, someInstructions({ files: { boot: [file] } })); + boot.execute(app, someInstructions({ files: { boot: [file] }})); expect(app.fnCalled, 'exported fn was called').to.be.true(); }); @@ -642,33 +745,33 @@ describe('executor', function() { sourceFile: pushNamePath, config: { phase: 'initial', - params: 'initial' - } + params: 'initial', + }, }, { sourceFile: pushNamePath, config: { phase: 'custom', - params: 'custom' - } + params: 'custom', + }, }, { sourceFile: pushNamePath, config: { phase: 'routes', - params: 'routes' - } + params: 'routes', + }, }, { sourceFile: pushNamePath, config: { phase: 'routes', enabled: false, - params: 'disabled' - } - } - ] - } + params: 'disabled', + }, + }, + ], + }, })); supertest(app) @@ -682,7 +785,6 @@ describe('executor', function() { }); it('configures middleware using shortform', function(done) { - boot.execute(app, someInstructions({ middleware: { middleware: [ @@ -691,11 +793,11 @@ describe('executor', function() { fragment: 'static', config: { phase: 'files', - params: path.join(__dirname, './fixtures/simple-app/client/') - } - } - ] - } + params: path.join(__dirname, './fixtures/simple-app/client/'), + }, + }, + ], + }, })); supertest(app) @@ -725,8 +827,8 @@ describe('executor', function() { it('configures components', function() { appdir.writeConfigFileSync('component-config.json', { './components/test-component': { - option: 'value' - } + option: 'value', + }, }); appdir.writeFileSync('components/test-component/index.js', @@ -743,7 +845,7 @@ describe('executor', function() { it('disables component when configuration is not set', function() { appdir.writeConfigFileSync('component-config.json', { - './components/test-component': false + './components/test-component': false, }); appdir.writeFileSync('components/test-component/index.js', @@ -758,10 +860,10 @@ describe('executor', function() { it('disable component if overrided by production configuration', function() { appdir.writeConfigFileSync('component-config.json', { - './components/test-component': {} + './components/test-component': {}, }); appdir.writeConfigFileSync('component-config.production.json', { - './components/test-component': null + './components/test-component': null, }); appdir.writeFileSync('components/test-component/index.js', @@ -785,11 +887,11 @@ describe('executor', function() { sourceFile: passportPath, fragment: 'initialize', config: { - phase: 'auth:before' - } - } - ] - } + phase: 'auth:before', + }, + }, + ], + }, })); supertest(app) @@ -809,6 +911,132 @@ describe('executor', function() { }); }); + describe('when booting with lazy connect', function() { + var SAMPLE_INSTRUCTION = someInstructions({ + dataSources: { + lazyConnector: { + connector: 'testLazyConnect', + name: 'lazyConnector', + }, + }, + }); + var connectTriggered = true; + + beforeEach(function() { + app.connector('testLazyConnect', { + initialize: function(dataSource, callback) { + if (dataSource.settings.lazyConnect) { + connectTriggered = false; + } else { + connectTriggered = true; + } + }, + }); + }); + + it('should trigger connect with ENV undefined', function(done) { + delete process.env.LB_LAZYCONNECT_DATASOURCES; + boot.execute(app, SAMPLE_INSTRUCTION, function() { + expect(connectTriggered).to.equal(true); + done(); + }); + }); + + it('should not trigger connect with ENV true', function(done) { + process.env.LB_LAZYCONNECT_DATASOURCES = 'true'; + boot.execute(app, SAMPLE_INSTRUCTION, function() { + expect(connectTriggered).to.equal(false); + done(); + }); + }); + + it('should trigger connect with ENV false', function(done) { + process.env.LB_LAZYCONNECT_DATASOURCES = 'false'; + boot.execute(app, SAMPLE_INSTRUCTION, function() { + expect(connectTriggered).to.equal(true); + done(); + }); + }); + + it('should trigger connect with ENV 0', function(done) { + process.env.LB_LAZYCONNECT_DATASOURCES = '0'; + boot.execute(app, SAMPLE_INSTRUCTION, function() { + expect(connectTriggered).to.equal(true); + done(); + }); + }); + }); + + describe('dynamic configuration for datasources.json', function() { + beforeEach(function() { + delete process.env.DYNAMIC_HOST; + delete process.env.DYNAMIC_PORT; + }); + + it('should convert dynamic variable for datasource', function(done) { + var datasource = { + mydb: { + host: '${DYNAMIC_HOST}', + port: '${DYNAMIC_PORT}', + }, + }; + var bootInstructions = { dataSources: datasource }; + + process.env.DYNAMIC_PORT = '10007'; + process.env.DYNAMIC_HOST = '123.321.123.132'; + + boot.execute(app, someInstructions(bootInstructions), function() { + expect(app.datasources.mydb.settings.host).to.equal('123.321.123.132'); + expect(app.datasources.mydb.settings.port).to.equal('10007'); + done(); + }); + }); + + it('should resolve dynamic config via app.get()', function(done) { + var datasource = { + mydb: { host: '${DYNAMIC_HOST}' }, + }; + var bootInstructions = { + config: { DYNAMIC_HOST: '127.0.0.4' }, + dataSources: datasource, + }; + boot.execute(app, someInstructions(bootInstructions), function() { + expect(app.get('DYNAMIC_HOST')).to.equal('127.0.0.4'); + expect(app.datasources.mydb.settings.host).to.equal( + '127.0.0.4'); + done(); + }); + }); + + it('should take ENV precedence over config.json', function(done) { + process.env.DYNAMIC_HOST = '127.0.0.2'; + var datasource = { + mydb: { host: '${DYNAMIC_HOST}' }, + }; + var bootInstructions = { + config: { DYNAMIC_HOST: '127.0.0.3' }, + dataSources: datasource, + }; + boot.execute(app, someInstructions(bootInstructions), function() { + expect(app.get('DYNAMIC_HOST')).to.equal('127.0.0.3'); + expect(app.datasources.mydb.settings.host).to.equal('127.0.0.2'); + done(); + }); + }); + + it('empty dynamic conf should resolve as `undefined`', function(done) { + var datasource = { + mydb: { host: '${DYNAMIC_HOST}' }, + }; + var bootInstructions = { dataSources: datasource }; + + boot.execute(app, someInstructions(bootInstructions), function() { + expect(app.get('DYNAMIC_HOST')).to.be.undefined(); + expect(app.datasources.mydb.settings.host).to.be.undefined(); + done(); + }); + }); + }); }); function simpleMiddlewareConfig(phase, paths, params) { @@ -819,7 +1047,7 @@ function simpleMiddlewareConfig(phase, paths, params) { var config = { phase: phase, - params: params + params: params, }; if (paths) config.paths = paths; @@ -831,9 +1059,9 @@ function simpleMiddlewareConfig(phase, paths, params) { { sourceFile: path.join(__dirname, './fixtures/simple-middleware.js'), config: config, - } - ] - } + }, + ], + }, }); } @@ -842,9 +1070,9 @@ function simpleComponentConfig(config) { components: [ { sourceFile: path.join(__dirname, './fixtures/simple-component.js'), - config: config - } - ] + config: config, + }, + ], }); } @@ -869,12 +1097,12 @@ function someInstructions(values) { var result = { config: values.config || {}, models: values.models || [], - dataSources: values.dataSources || { db: { connector: 'memory' } }, + dataSources: values.dataSources || { db: { connector: 'memory' }}, middleware: values.middleware || { phases: [], middleware: [] }, components: values.components || [], files: { - boot: [] - } + boot: [], + }, }; if (values.env) @@ -898,6 +1126,6 @@ function envAppInstructions() { fs.copySync(ENV_APP, appdir.PATH); return boot.compile({ appRootDir: appdir.PATH, - env: 'test' + env: 'test', }); } diff --git a/test/fixtures/browser-app-2/app.js b/test/fixtures/browser-app-2/app.js index f33937a..d6ba5d3 100644 --- a/test/fixtures/browser-app-2/app.js +++ b/test/fixtures/browser-app-2/app.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var loopback = require('loopback'); var boot = require('../../../'); @@ -5,5 +10,5 @@ var app = module.exports = loopback(); boot(app, { appId: 'browserApp2', - appRootDir: __dirname + appRootDir: __dirname, }); diff --git a/test/fixtures/browser-app-2/models/robot.js b/test/fixtures/browser-app-2/models/robot.js index 545c357..64c7d9b 100644 --- a/test/fixtures/browser-app-2/models/robot.js +++ b/test/fixtures/browser-app-2/models/robot.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + module.exports = function(Robot) { Robot.settings._customized = 'Robot'; Robot.base.settings._customized = 'Robot'; diff --git a/test/fixtures/browser-app/app.js b/test/fixtures/browser-app/app.js index 6a9b9cb..f2c4fb6 100644 --- a/test/fixtures/browser-app/app.js +++ b/test/fixtures/browser-app/app.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var loopback = require('loopback'); var boot = require('../../../'); diff --git a/test/fixtures/browser-app/boot/configure.js b/test/fixtures/browser-app/boot/configure.js index b159ba7..96bbc51 100644 --- a/test/fixtures/browser-app/boot/configure.js +++ b/test/fixtures/browser-app/boot/configure.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + module.exports = function(app) { app.set('custom-key', 'custom-value'); }; diff --git a/test/fixtures/browser-app/components/dummy-component.js b/test/fixtures/browser-app/components/dummy-component.js index 795a7a9..4a0da4b 100644 --- a/test/fixtures/browser-app/components/dummy-component.js +++ b/test/fixtures/browser-app/components/dummy-component.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + module.exports = function(app, options) { app.dummyComponentOptions = options; }; diff --git a/test/fixtures/browser-app/mixins/time-stamps.js b/test/fixtures/browser-app/mixins/time-stamps.js index c126e8b..0ca7ca5 100644 --- a/test/fixtures/browser-app/mixins/time-stamps.js +++ b/test/fixtures/browser-app/mixins/time-stamps.js @@ -1,5 +1,8 @@ +// Copyright IBM Corp. 2015,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + module.exports = function(Model, options) { - Model.timeStampsMixin = true; - }; diff --git a/test/fixtures/browser-app/models/customer.js b/test/fixtures/browser-app/models/customer.js index 79a512d..9e0a0b3 100644 --- a/test/fixtures/browser-app/models/customer.js +++ b/test/fixtures/browser-app/models/customer.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + module.exports = function(Customer) { Customer.settings._customized = 'Customer'; Customer.base.settings._customized = 'Base'; diff --git a/test/fixtures/env-app/boot/test/bar.js b/test/fixtures/env-app/boot/test/bar.js index d2a1f2f..68316c9 100644 --- a/test/fixtures/env-app/boot/test/bar.js +++ b/test/fixtures/env-app/boot/test/bar.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + process.bootFlags.push('barLoadedInTest'); module.exports = function(app, callback) { callback(); diff --git a/test/fixtures/passport.js b/test/fixtures/passport.js index 3dd8c13..d1833f2 100644 --- a/test/fixtures/passport.js +++ b/test/fixtures/passport.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var framework = { initialize: function(passport) { return function(req, res, next) { @@ -5,7 +10,7 @@ var framework = { res.setHeader('passport', 'initialized'); next(); }; - } + }, }; var Passport = function() { diff --git a/test/fixtures/simple-app/boot/bar.js b/test/fixtures/simple-app/boot/bar.js index 4e732a1..f726ea3 100644 --- a/test/fixtures/simple-app/boot/bar.js +++ b/test/fixtures/simple-app/boot/bar.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + process.bootFlags.push('barLoaded'); module.exports = function(app, callback) { process.bootFlags.push('barStarted'); diff --git a/test/fixtures/simple-app/boot/barSync.js b/test/fixtures/simple-app/boot/barSync.js index 4a38f80..7aca641 100644 --- a/test/fixtures/simple-app/boot/barSync.js +++ b/test/fixtures/simple-app/boot/barSync.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + process.bootFlags.push('barSyncLoaded'); module.exports = function(app) { process.bootFlags.push('barSyncExecuted'); diff --git a/test/fixtures/simple-app/boot/booting.js b/test/fixtures/simple-app/boot/booting.js index b7ec8b8..74f7031 100644 --- a/test/fixtures/simple-app/boot/booting.js +++ b/test/fixtures/simple-app/boot/booting.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + module.exports = function(app, cb) { if (app.booting) process.bootingFlagSet = true; diff --git a/test/fixtures/simple-app/boot/foo.js b/test/fixtures/simple-app/boot/foo.js index e2fd7a5..9add48f 100644 --- a/test/fixtures/simple-app/boot/foo.js +++ b/test/fixtures/simple-app/boot/foo.js @@ -1 +1,6 @@ +// Copyright IBM Corp. 2014. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + process.bootFlags.push('fooLoaded'); diff --git a/test/fixtures/simple-app/middleware/index.js b/test/fixtures/simple-app/middleware/index.js index d2b20d9..df0110d 100644 --- a/test/fixtures/simple-app/middleware/index.js +++ b/test/fixtures/simple-app/middleware/index.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + exports.myMiddleware = function(name) { return function(req, res, next) { req._names = req._names || []; diff --git a/test/fixtures/simple-app/node_modules/my-module/index.js b/test/fixtures/simple-app/node_modules/my-module/index.js index 5b64f75..3ee16e1 100644 --- a/test/fixtures/simple-app/node_modules/my-module/index.js +++ b/test/fixtures/simple-app/node_modules/my-module/index.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + /** * Exporting a middleware as a property of the main module */ diff --git a/test/fixtures/simple-component.js b/test/fixtures/simple-component.js index 952e5ae..b15b827 100644 --- a/test/fixtures/simple-component.js +++ b/test/fixtures/simple-component.js @@ -1,7 +1,10 @@ -module.exports = function(loopbackApp, params) { +// Copyright IBM Corp. 2015,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT +module.exports = function(loopbackApp, params) { loopbackApp.use('/component', function(req, res, next) { res.send(params); }); - }; diff --git a/test/fixtures/simple-middleware.js b/test/fixtures/simple-middleware.js index 30079f6..aec19a8 100644 --- a/test/fixtures/simple-middleware.js +++ b/test/fixtures/simple-middleware.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + module.exports = function(params) { return function(req, res, next) { res.send(params); diff --git a/test/helpers/appdir.js b/test/helpers/appdir.js index a52a606..cf1e67f 100644 --- a/test/helpers/appdir.js +++ b/test/helpers/appdir.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var path = require('path'); var fs = require('fs-extra'); var extend = require('util')._extend; @@ -27,8 +32,8 @@ appdir.createConfigFilesSync = function(appConfig, dataSources, models) { dataSources = extend({ db: { connector: 'memory', - defaultForType: 'db' - } + defaultForType: 'db', + }, }, dataSources); appdir.writeConfigFileSync ('datasources.json', dataSources); diff --git a/test/helpers/browser.js b/test/helpers/browser.js index 40bd5c4..dc21615 100644 --- a/test/helpers/browser.js +++ b/test/helpers/browser.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015,2016. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var vm = require('vm'); function createContext() { @@ -8,14 +13,14 @@ function createContext() { localStorage: { // used by `debug` module - debug: process.env.DEBUG + debug: process.env.DEBUG, }, // used by DataSource.prototype.ready setTimeout: setTimeout, // used by `debug` module - document: { documentElement: { style: {} } }, + document: { documentElement: { style: {}}}, // used by `debug` module navigator: { userAgent: 'sandbox' }, @@ -39,9 +44,9 @@ function createContext() { _logs: { log: [], warn: [], - error: [] + error: [], }, - } + }, }; // `window` is used by loopback to detect browser runtime @@ -52,9 +57,10 @@ function createContext() { exports.createContext = createContext; function printContextLogs(context) { - for (var k in context.console._logs) { + var k, ix; // see https://github.com/eslint/eslint/issues/5744 + for (k in context.console._logs) { var items = context.console._logs[k]; - for (var ix in items) { + for (ix in items) { console[k].apply(console, items[ix]); } } diff --git a/test/helpers/browserify.js b/test/helpers/browserify.js index 02e1fbe..aac32d8 100644 --- a/test/helpers/browserify.js +++ b/test/helpers/browserify.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2015. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var fs = require('fs'); var sandbox = require('./sandbox'); diff --git a/test/helpers/push-name-middleware.js b/test/helpers/push-name-middleware.js index f7e6d6c..e11a1bd 100644 --- a/test/helpers/push-name-middleware.js +++ b/test/helpers/push-name-middleware.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + module.exports = function(name) { return function(req, res, next) { req._names = req._names || []; diff --git a/test/helpers/sandbox.js b/test/helpers/sandbox.js index cdd35bd..9afe701 100644 --- a/test/helpers/sandbox.js +++ b/test/helpers/sandbox.js @@ -1,3 +1,8 @@ +// Copyright IBM Corp. 2014. All Rights Reserved. +// Node module: loopback-boot +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + var fs = require('fs-extra'); var path = require('path');