Skip to content

Commit

Permalink
Avoid using Ember global
Browse files Browse the repository at this point in the history
  • Loading branch information
mydea committed May 25, 2021
1 parent 65bc0bb commit 60d4de0
Show file tree
Hide file tree
Showing 7 changed files with 442 additions and 211 deletions.
112 changes: 112 additions & 0 deletions addon/initializers/ember-cli-deprecation-workflow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { registerDeprecationHandler } from '@ember/debug';
import { macroCondition, isDevelopingApp, isTesting } from '@embroider/macros';

export function initialize() {
if (macroCondition(isDevelopingApp() || isTesting())) {
setupDeprecationWorkflow();
}
}

export default {
initialize,
};

function setupDeprecationWorkflow() {
self.deprecationWorkflow = self.deprecationWorkflow || {};
self.deprecationWorkflow.deprecationLog = {
messages: {},
};

function detectWorkflow(config, message, options) {
if (!config || !config.workflow) {
return;
}

let i, workflow, matcher, idMatcher;
for (i = 0; i < config.workflow.length; i++) {
workflow = config.workflow[i];
matcher = workflow.matchMessage;
idMatcher = workflow.matchId;

if (
typeof idMatcher === 'string' &&
options &&
idMatcher === options.id
) {
return workflow;
} else if (typeof matcher === 'string' && matcher === message) {
return workflow;
} else if (matcher instanceof RegExp && matcher.exec(message)) {
return workflow;
}
}
}

registerDeprecationHandler(function handleDeprecationWorkflow(
message,
options,
next
) {
let config = self.deprecationWorkflow.config || {};

let matchingWorkflow = detectWorkflow(config, message, options);
if (!matchingWorkflow) {
if (config && config.throwOnUnhandled) {
throw new Error(message);
} else {
next(message, options);
}
} else {
switch (matchingWorkflow.handler) {
case 'silence':
// no-op
break;
case 'log':
console.warn('DEPRECATION: ' + message);
break;
case 'throw':
throw new Error(message);
default:
next(message, options);
break;
}
}
});

registerDeprecationHandler(function deprecationCollector(
message,
options,
next
) {
let key = (options && options.id) || message;
let matchKey = options && key === options.id ? 'matchId' : 'matchMessage';

self.deprecationWorkflow.deprecationLog.messages[key] =
' { handler: "silence", ' +
matchKey +
': ' +
JSON.stringify(key) +
' }';
next(message, options);
});

let preamble = [
'self.deprecationWorkflow = self.deprecationWorkflow || {};',
'self.deprecationWorkflow.config = {\n workflow: [\n',
].join('\n');

let postamble = [' ]\n};'].join('\n');

self.deprecationWorkflow.flushDeprecations = function flushDeprecations() {
let messages = self.deprecationWorkflow.deprecationLog.messages;
let logs = [];

for (let message in messages) {
logs.push(messages[message]);
}

let deprecations = logs.join(',\n') + '\n';

return preamble + deprecations + postamble;
};
}
4 changes: 4 additions & 0 deletions app/initializers/ember-cli-deprecation-workflow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export {
default,
initialize,
} from 'ember-cli-deprecation-workflow/initializers/ember-cli-deprecation-workflow';
121 changes: 16 additions & 105 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,30 @@
module.exports = {
name: require('./package').name,

init() {
this._super.init && this._super.init.apply(this, arguments);
included() {
this._super.included.apply(this, arguments);

this._templateDeprecations = [];
if (this._shouldIncludeConfig()) {
let app = this._findHost();
app.import(
'vendor/ember-cli-deprecation-workflow/deprecation-workflow.js'
);
}
},

_shouldInclude() {
_shouldIncludeConfig() {
// the presence of `this.app.tests` shows that we are in one of:
//
// * running non-production build
// * running tests against production
//
var app = this.app || this._findHost();
let app = this.app || this._findHost();
return app.tests;
},

included() {
// From https://github.com/rwjblue/ember-debug-handlers-polyfill/blob/master/index.js
var app = this.app || this._findHost();

if (this._shouldInclude()) {
app.import('vendor/ember-debug-handlers-polyfill/debug.js');
app.import(
'vendor/ember-cli-deprecation-workflow/deprecation-workflow.js'
);
app.import('vendor/ember-cli-deprecation-workflow/main.js');
} else {
app.import('vendor/ember-debug-handlers-polyfill/prod.js');
}
},

treeForVendor(tree) {
var root = process.env._DUMMY_CONFIG_ROOT_PATH || this.project.root;
var configDir = '/config';
let root = this.project.root;
let configDir = '/config';

if (
this.project.pkg['ember-addon'] &&
Expand All @@ -45,9 +35,9 @@ module.exports = {
configDir = '/' + this.project.pkg['ember-addon']['configPath'];
}

var mergeTrees = require('broccoli-merge-trees');
var Funnel = require('broccoli-funnel');
var configTree = new Funnel(root + configDir, {
let mergeTrees = require('broccoli-merge-trees');
let Funnel = require('broccoli-funnel');
let configTree = new Funnel(root + configDir, {
include: ['deprecation-workflow.js'],

destDir: 'ember-cli-deprecation-workflow',
Expand All @@ -56,88 +46,9 @@ module.exports = {
return mergeTrees([tree, configTree], { overwrite: true });
},

_findHtmlbarsPreprocessor(registry) {
var plugins = registry.load('template');

return plugins.filter(function (plugin) {
return plugin.name === 'ember-cli-htmlbars';
})[0];
},

_monkeyPatch_EmberDeprecate(htmlbarsCompilerPreprocessor) {
if (!htmlbarsCompilerPreprocessor._addon) {
// not a new enough ember-cli-htmlbars to monkey patch
// we need 1.0.3
return;
}
var addonContext = this;
var originalHtmlbarsOptions =
htmlbarsCompilerPreprocessor._addon.htmlbarsOptions;
var logToNodeConsole = this.project.config(process.env.EMBER_ENV)
.logTemplateLintToConsole;

htmlbarsCompilerPreprocessor._addon.htmlbarsOptions = function () {
var options = originalHtmlbarsOptions.apply(this, arguments);
var Ember = options.templateCompiler._Ember;

if (Ember.Debug && Ember.Debug.registerDeprecationHandler) {
Ember.Debug.registerDeprecationHandler(function (
message,
options,
next
) {
addonContext._templateDeprecations.push({
message: JSON.stringify(message),
test: false,
options: JSON.stringify(options),
});

if (logToNodeConsole) {
next();
}
});
}

var originalDeprecate = options.templateCompiler._Ember.deprecate;
Ember.deprecate = function (message, test, options) {
var noDeprecation;

if (typeof test === 'function') {
noDeprecation = test();
} else {
noDeprecation = test;
}

if (!noDeprecation) {
addonContext._templateDeprecations.push({
message: JSON.stringify(message),
test: !!test,
options: JSON.stringify(options),
});
}

if (logToNodeConsole) {
return originalDeprecate.apply(this, arguments);
}
};

return options;
};
},

setupPreprocessorRegistry(type, registry) {
if (type === 'parent') {
var htmlbarsCompilerPreprocessor = this._findHtmlbarsPreprocessor(
registry
);

this._monkeyPatch_EmberDeprecate(htmlbarsCompilerPreprocessor);
}
},

lintTree(type, tree) {
if (type === 'template') {
var TemplateLinter = require('./generate-deprecations-tree');
let TemplateLinter = require('./generate-deprecations-tree');

return new TemplateLinter(this, tree);
}
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@
"test:ember-compatibility": "ember try:each"
},
"dependencies": {
"@embroider/macros": "^0.41.0",
"broccoli-funnel": "^2.0.1",
"broccoli-merge-trees": "^3.0.1",
"broccoli-plugin": "^1.3.1",
"ember-cli-htmlbars": "^5.3.2",
"ember-debug-handlers-polyfill": "^1.1.1"
"ember-cli-babel": "^7.26.6",
"ember-cli-htmlbars": "^5.3.2"
},
"devDependencies": {
"@ember/optional-features": "^2.0.0",
Expand All @@ -42,7 +43,6 @@
"broccoli-asset-rev": "^3.0.0",
"ember-auto-import": "^1.10.1",
"ember-cli": "~3.25.0",
"ember-cli-babel": "^7.23.1",
"ember-cli-dependency-checker": "^3.2.0",
"ember-cli-inject-live-reload": "^2.0.2",
"ember-cli-sri": "^2.1.1",
Expand Down
37 changes: 26 additions & 11 deletions tests/acceptance/workflow-config-test.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,58 @@
import { deprecate } from '@ember/application/deprecations';
import Ember from 'ember';
import { module } from 'qunit';
import test from '../helpers/debug-test';
import { setupApplicationTest } from 'ember-qunit';
import { module, test } from 'qunit';

let originalWarn;
module('Acceptance | workflow config', function (hooks) {
setupApplicationTest(hooks);

module('workflow config', function (hooks) {
hooks.beforeEach(function () {
originalWarn = window.Testem.handleConsoleMessage;
this.originalWarn = console.warn;
});

hooks.afterEach(function () {
Ember.ENV.RAISE_ON_DEPRECATION = false;
window.deprecationWorkflow.deprecationLog = { messages: {} };
window.Testem.handleConsoleMessage = originalWarn;
console.warn = this.originalWarn;
});

test('deprecation silenced with string matcher', (assert) => {
deprecate('silence-me', false, { until: 'forever', id: 'test' });
deprecate('silence-me', false, {
until: 'forever',
since: '0.0.0',
id: 'test',
for: 'testing',
});
assert.ok(true, 'Deprecation did not raise');
});

test('deprecation logs with string matcher', (assert) => {
assert.expect(1);

let message = 'log-me';
window.Testem.handleConsoleMessage = function (passedMessage) {
console.warn = function (passedMessage) {
assert.ok(
passedMessage.indexOf('DEPRECATION: ' + message) === 0,
'deprecation logs'
);
};
deprecate(message, false, { until: 'forever', id: 'test' });
deprecate(message, false, {
until: 'forever',
since: '0.0.0',
id: 'test',
for: 'testing',
});
});

test('deprecation thrown with string matcher', (assert) => {
Ember.ENV.RAISE_ON_DEPRECATION = true;
assert.throws(function () {
deprecate('throw-me', false, { until: 'forever', id: 'test' });
deprecate('throw-me', false, {
until: 'forever',
since: '0.0.0',
id: 'test',
for: 'testing',
});
}, 'deprecation throws');
});

Expand All @@ -48,7 +63,7 @@ module('workflow config', function (hooks) {
let id = 'ember.workflow';
let options = { id, since: '2.0.0', until: '3.0.0', for: 'testing' };
let expected = `DEPRECATION: ${message}`;
window.Testem.handleConsoleMessage = function (passedMessage) {
console.warn = function (passedMessage) {
assert.equal(
passedMessage.substr(0, expected.length),
expected,
Expand Down
Loading

0 comments on commit 60d4de0

Please sign in to comment.