From 22ef877d418de11acb46a8b010267df3af947e61 Mon Sep 17 00:00:00 2001 From: pangratz Date: Tue, 8 Dec 2015 17:23:02 +0100 Subject: [PATCH 1/3] Strip code for feature flags, which are not enabled This add the `babel-plugin-feature-flag` BabelJS plugin to the build pipeline, so all code paths are stripped for features, which are not enabled in `config/features.json`. Feature detection within the addon is handled similar to the one in Ember.js: ``` import isEnabled from 'ember-data/features'; if (isEnabled("ds-new-feature")) { // code for the feature } ``` --- addon/features.js | 5 +++++ lib/javascripts.js | 10 ++++++++++ package.json | 1 + 3 files changed, 16 insertions(+) create mode 100644 addon/features.js diff --git a/addon/features.js b/addon/features.js new file mode 100644 index 00000000000..8e023905a04 --- /dev/null +++ b/addon/features.js @@ -0,0 +1,5 @@ +import Ember from 'ember'; + +export default function isEnabled() { + return Ember.FEATURES.isEnabled(...arguments); +} diff --git a/lib/javascripts.js b/lib/javascripts.js index 2e39d30c0a5..60eddc17dcb 100644 --- a/lib/javascripts.js +++ b/lib/javascripts.js @@ -1,10 +1,12 @@ var filterImports = require('babel-plugin-filter-imports'); +var featureFlags = require('babel-plugin-feature-flags'); var babel = require('broccoli-babel-transpiler'); var merge = require('broccoli-merge-trees'); var concat = require('broccoli-concat'); var uglify = require('broccoli-uglify-sourcemap'); var stew = require('broccoli-stew'); var version = require('./version'); +var fs = require('fs'); var path = require('path'); var Funnel = require('broccoli-funnel'); var versionReplace = require('./version-replace'); @@ -56,7 +58,15 @@ function debugBuild(packageName, tree) { } function strippedBuild(packageName, tree) { + var featuresJson = fs.readFileSync('config/features.json', { encoding: 'utf8' }); + var features = JSON.parse(featuresJson); + var plugins = [ + featureFlags({ + import: { module: 'ember-data/features' }, + features: features + }), + filterImports({ 'ember-data/debug': [ 'assert', diff --git a/package.json b/package.json index 95a9afe10ed..3a60d20a0ac 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "ember-cli-babel": "^5.1.3" }, "devDependencies": { + "babel-plugin-feature-flags": "^0.2.0", "babel-plugin-filter-imports": "^0.2.0", "bower": "^1.6.5", "broccoli-asset-rev": "^2.1.2", From f58ffe442dbbd26a9cc71b53d153c5bd56d617c6 Mon Sep 17 00:00:00 2001 From: pangratz Date: Tue, 8 Dec 2015 20:22:45 +0100 Subject: [PATCH 2/3] Add possibility to run tests for feature flags via `ember test` Optional features and the corresponding tests can now be enabled within the tests by specifying the `test-optional-features` environment: ember test --environment=test-optional-features --- .travis.yml | 1 + config/environment.js | 20 +++++++++++++++----- package.json | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e8dcd45020a..ad55c004238 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ install: script: - ./bin/lint-features - npm run-script test + - npm run-script test:optional-features after_success: - npm run-script production - "./bin/bower-ember-data-build" diff --git a/config/environment.js b/config/environment.js index 80369f82b6c..c7058a3411c 100644 --- a/config/environment.js +++ b/config/environment.js @@ -1,13 +1,23 @@ 'use strict'; +var fs = require('fs'); +var featuresJson = fs.readFileSync('config/features.json', { encoding: 'utf8' }); +var featureFlags = JSON.parse(featuresJson); + module.exports = function(environment, appConfig) { var ENV = { }; - if (environment === 'testing') { - ENV.EmberENV = { - RAISE_ON_DEPRECATION: true, - ENABLE_DS_FILTER: true - }; + ENV.EmberENV = { + FEATURES: featureFlags, + ENABLE_DS_FILTER: true, + + // don't raise on deprecation yet, since there are too many thrown errors; + // this should be addressed in another PR + // RAISE_ON_DEPRECATION: true + }; + + if (environment === 'test-optional-features') { + ENV.EmberENV.ENABLE_OPTIONAL_FEATURES = true; } return ENV; diff --git a/package.json b/package.json index 3a60d20a0ac..d876f57e666 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "build": "ember build", "start": "ember server", "test": "ember try:testall", + "test:optional-features": "ember test --environment=test-optional-features", "bower": "bower install", "production": "ember build --environment=production" }, From a1cdc95aad289b66202949a13ac57d2ac10d4284 Mon Sep 17 00:00:00 2001 From: pangratz Date: Tue, 8 Dec 2015 20:31:05 +0100 Subject: [PATCH 3/3] Re-add possibility to enable feature flags within Browser Optional feature flags can now be enabled via a checkbox, rendered at the top of the test page. The state of the checkbox is set as query parameter in the URL. An in-repo-addon ensures that the ENABLE_OPTIONAL_FEATURES flag works correctly, when the tests are run inside a browser: the workaround using the in-repo-addon is needed, since the flag needs to be set before Ember.js is loaded, but there is currently no other way. --- lib/enable-optional-features-via-url/index.js | 27 +++++++++++++++++++ .../package.json | 6 +++++ package.json | 5 +++- tests/test-helper.js | 9 +------ 4 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 lib/enable-optional-features-via-url/index.js create mode 100644 lib/enable-optional-features-via-url/package.json diff --git a/lib/enable-optional-features-via-url/index.js b/lib/enable-optional-features-via-url/index.js new file mode 100644 index 00000000000..0c16d924cc0 --- /dev/null +++ b/lib/enable-optional-features-via-url/index.js @@ -0,0 +1,27 @@ +/*jshint node:true*/ +module.exports = { + name: 'enable-optional-features-via-url', + + /** + So the ENABLE_OPTIONAL_FEATURES flag is considered correctly within the + index.html, it needs to be set before Ember.js is loaded. Since there is + currently no way to access the `window` object within config/environment.js + (and hereby check if there is a query parameter present for the checkbox), + a script is injected, before Ember.js is loaded. The script checks if there + is no value yet for the ENABLE_OPTIONAL_FEATURES flag, and if so, it sets + the flag to true when there is a `enableoptionalfeatures` query parameter. + */ + contentFor: function(name) { + if (name === "vendor-prefix") { + var array = [ + "", + "window.EmberENV = window.EmberENV || {};", + "if (typeof window.EmberENV.ENABLE_OPTIONAL_FEATURES === 'undefined') {", + " window.EmberENV.ENABLE_OPTIONAL_FEATURES = window.location.search.indexOf('enableoptionalfeatures') !== -1;", + "}" + ]; + + return array.join('\n'); + } + } +}; diff --git a/lib/enable-optional-features-via-url/package.json b/lib/enable-optional-features-via-url/package.json new file mode 100644 index 00000000000..ea6c08dab4d --- /dev/null +++ b/lib/enable-optional-features-via-url/package.json @@ -0,0 +1,6 @@ +{ + "name": "enable-optional-features-via-url", + "keywords": [ + "ember-addon" + ] +} diff --git a/package.json b/package.json index d876f57e666..f41d413d282 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,9 @@ "ember-addon" ], "ember-addon": { - "configPath": "tests/dummy/config" + "configPath": "tests/dummy/config", + "paths": [ + "lib/enable-optional-features-via-url" + ] } } diff --git a/tests/test-helper.js b/tests/test-helper.js index ce98f980535..bf6077bcb49 100644 --- a/tests/test-helper.js +++ b/tests/test-helper.js @@ -19,14 +19,8 @@ import Ember from 'ember'; setResolver(resolver); -const ENV = Ember.ENV; -const QUNIT_PARAMS = QUnit.urlParams; const { assert } = QUnit; -ENV.EXTEND_PROTOTYPES = QUNIT_PARAMS.extendprototypes; -ENV.ENABLE_OPTIONAL_FEATURES = QUNIT_PARAMS.enableoptionalfeatures; -ENV.ENABLE_DS_FILTER = true; - QUnit.begin(function() { Ember.RSVP.configure('onerror', function(reason) { // only print error messages if they're exceptions; @@ -76,6 +70,5 @@ assert.without = function(array, item) { addEmberAssertions(assert); -QUnit.config.testTimeout= 2000; +QUnit.config.testTimeout = 2000; QUnit.config.urlConfig.push({ id: 'enableoptionalfeatures', label: "Enable Opt Features" }); -