diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c082ed1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,22 @@ +--- +language: node_js +node_js: + - "0.12" + - "4" + +sudo: false + +cache: + directories: + - node_modules + +before_install: + - export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH + - "npm config set spin false" + - "npm install -g npm@^2" + +install: + - npm install + +script: + - npm test diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e93cfe..24b5bb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,28 +1,82 @@ # Change Log -## [0.2.3](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/0.2.3) (2016-03-29) -[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.2...0.2.3) +## [0.2.9](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/0.2.9) (2016-11-21) +[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.8...0.2.9) -- add logRaw method [\#9](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/9) ([ghedamat](https://github.com/ghedamat)) +**Merged pull requests:** -## [0.2.2](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/0.2.2) (2016-02-06) -[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.1...0.2.2) +- Add function to pluginHelper [\#17](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/17) ([achambers](https://github.com/achambers)) + +## [v0.2.8](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.2.8) (2016-11-21) +[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.7...v0.2.8) + +**Merged pull requests:** + +- Update core-object & mocha. [\#16](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/16) ([lukemelia](https://github.com/lukemelia)) + +## [v0.2.7](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.2.7) (2016-11-21) +[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.6...v0.2.7) + +[BREAKING] This release changes the context of `this` within a user-defined config property function from the base plugin itself to the surrounding config object. This behavior was previously inconsistent. + +**Merged pull requests:** + +- Add plugin helper [\#15](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/15) ([achambers](https://github.com/achambers)) + +## [v0.2.6](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.2.6) (2016-04-19) +[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.5...v0.2.6) + +**Merged pull requests:** + +- remove lodash, fix \#11 [\#12](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/12) ([ghedamat](https://github.com/ghedamat)) + +## [v0.2.5](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.2.5) (2016-04-01) +[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.4...v0.2.5) + +**Merged pull requests:** + +- require proper lodash [\#10](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/10) ([ghedamat](https://github.com/ghedamat)) + +## [v0.2.4](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.2.4) (2016-04-01) +[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.3...v0.2.4) + +**Merged pull requests:** + +- add logInfo color option [\#8](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/8) ([ghedamat](https://github.com/ghedamat)) + +## [v0.2.3](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.2.3) (2016-03-29) +[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.2...v0.2.3) + +**Merged pull requests:** + +- add plain option [\#9](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/9) ([ghedamat](https://github.com/ghedamat)) + +## [v0.2.2](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.2.2) (2016-02-06) +[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.1...v0.2.2) + +**Merged pull requests:** - ember cli uses the wrong spelling from originalOutputStream [\#7](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/7) ([ghedamat](https://github.com/ghedamat)) -## [0.2.1](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/0.2.1) (2016-01-23) -[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.0...0.2.1) +## [v0.2.1](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.2.1) (2016-01-24) +[Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.2.0...v0.2.1) + +**Merged pull requests:** - ensure that we start logging from the beginning of the line [\#6](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/6) ([ghedamat](https://github.com/ghedamat)) ## [v0.2.0](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.2.0) (2015-10-24) [Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.1.3...v0.2.0) +**Merged pull requests:** + - Add verbose option support to log method, and update docs [\#2](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/2) ([lukemelia](https://github.com/lukemelia)) ## [v0.1.3](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.1.3) (2015-08-04) [Full Changelog](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/compare/v0.1.2...v0.1.3) +**Merged pull requests:** + - Call default getters in plugin context [\#1](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/pull/1) ([dschmidt](https://github.com/dschmidt)) ## [v0.1.2](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.1.2) (2015-07-17) @@ -30,4 +84,5 @@ ## [v0.1.1](https://github.com/ember-cli-deploy/ember-cli-deploy-plugin/tree/v0.1.1) (2015-07-12) -- Initial release + +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file diff --git a/README.md b/README.md index 2ba301d..30aa43d 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,9 @@ module.exports = { someKey: 'defaultValue', anotherKey: function(context) { return context.anotherKey; // to use data added to the context by another plugin + }, + capsKey: function(context, pluginHelper) { + return pluginHelper.readConfig('someKey').toUppercase(); // pluginHelper.readConfig returns a clone of the specified config value } }, requiredConfig: ['awesomeApiKey'], // throw an error if this is not configured @@ -56,7 +59,3 @@ module.exports = { return new DeployPlugin(); } }; - -## TODO - -Tests diff --git a/index.js b/index.js index e50f211..c17d781 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,22 @@ var CoreObject = require('core-object'); var chalk = require('chalk'); -var _ = require('lodash'); +var cloneDeep = require('lodash.clonedeep'); + +function _pluginHelper() { + return { + readConfigDefault: function(property) { + var configuredValue = this.defaultConfig[property]; + if (typeof configuredValue === 'function') { + return cloneDeep(configuredValue.call(this, this.context)); + } + return cloneDeep(configuredValue); + }.bind(this), + + readConfig: function(property) { + return cloneDeep(this.readConfig(property)); + }.bind(this) + }; +} var DeployPluginBase = CoreObject.extend({ context: null, @@ -8,6 +24,12 @@ var DeployPluginBase = CoreObject.extend({ project: null, pluginConfig: null, defaultConfig: {}, + init: function() { + this._super.init.apply(this, arguments); + if (!this.name) { + throw new Error('Plugin is missing name property'); + } + }, beforeHook: function(context) { this.context = context; this.ui = context.ui; @@ -44,7 +66,7 @@ var DeployPluginBase = CoreObject.extend({ readConfig: function(property){ var configuredValue = this.pluginConfig[property]; if (typeof configuredValue === 'function') { - return configuredValue.call(this, this.context); + return configuredValue.call(this.pluginConfig, this.context, _pluginHelper.call(this)); } return configuredValue; }, diff --git a/package.json b/package.json index e40cc98..32b61fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ember-cli-deploy-plugin", - "version": "0.2.3", + "version": "0.2.9", "description": "For building plugins for ember-cli-deploy", "repository": "https://github.com/ember-cli-deploy/ember-cli-deploy-plugin", "engines": { @@ -8,10 +8,22 @@ }, "author": "Luke Melia and ember-cli-deploy team", "license": "MIT", - "devDependencies": {}, + "directories": { + "test": "tests" + }, + "scripts": { + "start": "ember server", + "build": "ember build", + "test": "node tests/runner.js" + }, + "devDependencies": { + "chai": "^3.5.0", + "glob": "^7.0.3", + "mocha": "^3.1.2" + }, "dependencies": { "chalk": "^1.0.0", - "core-object": "0.0.2", - "lodash": "^4.6.1" + "core-object": "2.0.6", + "lodash.clonedeep": "^4.5.0" } } diff --git a/tests/.jshintrc b/tests/.jshintrc new file mode 100644 index 0000000..ea8b88f --- /dev/null +++ b/tests/.jshintrc @@ -0,0 +1,51 @@ +{ + "predef": [ + "document", + "window", + "location", + "setTimeout", + "$", + "-Promise", + "define", + "console", + "visit", + "exists", + "fillIn", + "click", + "keyEvent", + "triggerEvent", + "find", + "findWithAssert", + "wait", + "DS", + "andThen", + "currentURL", + "currentPath", + "currentRouteName" + ], + "node": false, + "browser": false, + "boss": true, + "curly": false, + "debug": false, + "devel": false, + "eqeqeq": true, + "evil": true, + "forin": false, + "immed": false, + "laxbreak": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": false, + "nomen": false, + "onevar": false, + "plusplus": false, + "regexp": false, + "undef": true, + "sub": true, + "strict": false, + "white": false, + "eqnull": true, + "esnext": true +} diff --git a/tests/runner.js b/tests/runner.js new file mode 100644 index 0000000..1ffb333 --- /dev/null +++ b/tests/runner.js @@ -0,0 +1,27 @@ +'use strict'; + +var glob = require('glob'); +var Mocha = require('mocha'); + +var mocha = new Mocha({ + reporter: 'spec' +}); + +var arg = process.argv[2]; +var root = 'tests/'; + +function addFiles(mocha, files) { + glob.sync(root + files).forEach(mocha.addFile.bind(mocha)); +} + +addFiles(mocha, '/**/*-nodetest.js'); + +if (arg === 'all') { + addFiles(mocha, '/**/*-nodetest-slow.js'); +} + +mocha.run(function(failures) { + process.on('exit', function() { + process.exit(failures); + }); +}); diff --git a/tests/test-helper.js b/tests/test-helper.js new file mode 100644 index 0000000..e6cfb70 --- /dev/null +++ b/tests/test-helper.js @@ -0,0 +1,6 @@ +import resolver from './helpers/resolver'; +import { + setResolver +} from 'ember-qunit'; + +setResolver(resolver); diff --git a/tests/unit/.gitkeep b/tests/unit/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/index-nodetest.js b/tests/unit/index-nodetest.js new file mode 100644 index 0000000..eadcfb8 --- /dev/null +++ b/tests/unit/index-nodetest.js @@ -0,0 +1,252 @@ +/* jshint node: true */ +/* jshint jasmine: true */ +'use strict'; +var assert = require('chai').assert; + +var stubProject = { + name: function(){ + return 'my-project'; + } +}; + +describe('base plugin', function() { + var Subject, mockUi; + + beforeEach(function() { + Subject = require('../../index'); + mockUi = { + verbose: false, + messages: [], + write: function() { + }, + writeLine: function(message) { + this.messages.push(message); + }, + logInfoColor: 'blue' + }; + }); + + it('has a name', function() { + var plugin = new Subject({ + name: 'test-plugin', + }); + + assert.equal(plugin.name, 'test-plugin'); + }); + + it('errors when no name is set', function() { + var makePluginWithNoName = function() { + new Subject(); + }; + + assert.throws(makePluginWithNoName, /missing name/); + }); + + describe('log', function() { + + it('logs raw', function() { + var plugin = new Subject({ + name: 'test-plugin', + ui: mockUi + }); + plugin.logRaw('foo'); + assert.deepEqual(mockUi.messages, ['foo']); + }); + + it('logs with default blue color', function() { + var plugin = new Subject({ + name: 'test-plugin', + ui: mockUi + }); + plugin.log('foo'); + assert.deepEqual(mockUi.messages, ['\u001b[34m- foo\u001b[39m']); + }); + + it('logs verbose', function() { + var verboseUi = { + verbose: true, + messages: [], + write: function(message) { + this.messages.push(message); + }, + writeLine: function() { + } + }; + var plugin = new Subject({ + name: 'test-plugin', + ui: verboseUi + }); + plugin.log('foo', {verbose: true}); + assert.deepEqual(verboseUi.messages, ['\u001b[34m| \u001b[39m']); + }); + }); + + describe('plugin helper', function() { + it('provides access to the oringal default values', function() { + var Plugin = Subject.extend({ + defaultConfig: { + distFiles: ['index.html', 'assets/logo.png'], + jsonBlueprint: { + link: { + selector: 'link', + attributes: ['rel', 'href'] + }, + }, + git: { + sha: function() { + return '1'; + } + }, + revisionKey: function(context) { + return context.revisionData.revisionKey; + } + } + }); + + var plugin = new Plugin({ + name: 'build' + }); + + var context = { + revisionData: { revisionKey: '111' }, + config: { + build: { + distFiles: function(context, pluginHelper) { + var arr = pluginHelper.readConfigDefault('distFiles'); + arr.push('index.json'); + return arr; + }, + jsonBlueprint: function(context, pluginHelper) { + var blueprint = pluginHelper.readConfigDefault('jsonBlueprint'); + blueprint.link.attributes.push('integrity'); + + return blueprint; + }, + sha: function(context, pluginHelper) { + var git = pluginHelper.readConfigDefault('git'); + + return git.sha() + '2'; + }, + revisionKey: function(context, pluginHelper) { + return pluginHelper.readConfigDefault('revisionKey') + '222'; + } + } + } + }; + + plugin.beforeHook(context); + assert.deepEqual(plugin.readConfig('distFiles'), ['index.html', 'assets/logo.png', 'index.json']); + assert.deepEqual(plugin.readConfig('jsonBlueprint').link.attributes, ['rel', 'href', 'integrity']); + assert.equal(plugin.readConfig('sha'), '12'); + assert.equal(plugin.readConfig('revisionKey'), '111222'); + }); + + it('ensures default values do not get mutated', function() { + var Plugin = Subject.extend({ + defaultConfig: { + distFiles: ['index.html', 'assets/logo.png'], + jsonBlueprint: { + link: { + selector: 'link', + attributes: ['rel', 'href'] + } + } + } + }); + + var plugin = new Plugin({ + name: 'build' + }); + + var context = { + config: { + build: { + distFiles: function(context, pluginHelper) { + var arr = pluginHelper.readConfigDefault('distFiles'); + arr.push('index.json'); + return arr; + }, + jsonBlueprint: function(context, pluginHelper) { + var blueprint = pluginHelper.readConfigDefault('jsonBlueprint'); + blueprint.link.attributes.push('integrity'); + + return blueprint; + } + } + } + }; + + plugin.beforeHook(context); + plugin.readConfig('distFiles') + plugin.readConfig('jsonBlueprint') + + assert.deepEqual(plugin.defaultConfig.distFiles, ['index.html', 'assets/logo.png']); + assert.deepEqual(plugin.defaultConfig.jsonBlueprint.link.attributes, ['rel', 'href']); + }) + + it('provides the ability to read the plugin config', function() { + var Plugin = Subject.extend({ + defaultConfig: { + port: function() { + return 1234; + }, + host: 'foo.com' + } + }); + + var plugin = new Plugin({ + name: 'build' + }); + + var context = { + ui: mockUi, + config: { + build: { + username: 'bar', + options: function(context, pluginHelper) { + return { + port: pluginHelper.readConfig('port'), + host: pluginHelper.readConfig('host'), + username: pluginHelper.readConfig('username') + }; + } + } + } + }; + + plugin.beforeHook(context); + plugin.configure(context); + + assert.deepEqual(plugin.readConfig('options'), { port: 1234, host: 'foo.com', username: 'bar' }); + }); + + it('doesn\'t mutate the original plugin config', function() { + var Plugin = Subject.extend({ + defaultConfig: { } + }); + + var plugin = new Plugin({ + name: 'build' + }); + + var context = { + ui: mockUi, + config: { + build: { + tags: ['foo'], + options: function(context, pluginHelper) { + var tags = pluginHelper.readConfig('tags'); + tags.push('bar'); + return { tags: tags }; + } + } + } + }; + + plugin.beforeHook(context); + plugin.configure(context); + + assert.deepEqual(plugin.readConfig('options'), { tags: ['foo', 'bar']}); + }); + }); +});