diff --git a/.eslintrc.js b/.eslintrc.js
index a850e9954af..9512c474dba 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -166,20 +166,6 @@ module.exports = {
'disable-features/disable-generator-functions': 'off',
}),
},
- {
- // matches node-land files that aren't shipped to consumers (allows using Node 6+ features)
- files: [
- 'broccoli/**/*.js',
- 'tests/node/**/*.js',
- 'ember-cli-build.js',
- 'rollup.config.js',
- 'd8-runner.js',
- ],
-
- rules: {
- 'node/no-unsupported-features': ['error', { version: 6 }],
- }
- },
{
files: [ 'node-tests/**/*.js' ],
diff --git a/tests/node/component-rendering-test.js b/tests/node/component-rendering-test.js
index e8fcce14a91..a5e9c17aeef 100644
--- a/tests/node/component-rendering-test.js
+++ b/tests/node/component-rendering-test.js
@@ -33,4 +33,12 @@ QUnit.module('Components can be rendered without a DOM dependency', function(hoo
assert.ok(html.match(/rel="canonical"/));
});
+
+ QUnit.test('attributes requiring protocol sanitization do not error', function(assert) {
+ this.set('someHref', 'https://foo.com/');
+
+ let html = this.render('Some Link');
+
+ assert.ok(html.match(/Some Link<\/a>/));
+ });
});
diff --git a/tests/node/fastboot-sandbox-test.js b/tests/node/fastboot-sandbox-test.js
new file mode 100644
index 00000000000..87a69bfa9c0
--- /dev/null
+++ b/tests/node/fastboot-sandbox-test.js
@@ -0,0 +1,137 @@
+const fs = require('fs');
+const vm = require('vm');
+const SimpleDOM = require('simple-dom');
+const { emberPath, loadEmber, clearEmber } = require('./helpers/load-ember');
+
+function assertHTMLMatches(assert, actualHTML, expectedHTML) {
+ assert.ok(actualHTML.match(expectedHTML), actualHTML + ' matches ' + expectedHTML);
+}
+
+function handleError(assert) {
+ return function(error) {
+ assert.ok(false, error.stack);
+ };
+}
+
+// This is based on what fastboot-server does
+let HTMLSerializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap);
+
+async function fastbootVisit(context, url) {
+ let doc = new SimpleDOM.Document();
+ let rootElement = doc.body;
+ let options = { isBrowser: false, document: doc, rootElement: rootElement };
+
+ let { app } = context;
+
+ await app.boot();
+
+ let instance = await app.buildInstance();
+
+ try {
+ await instance.boot(options);
+ await instance.visit(url, options);
+
+ return {
+ url: instance.getURL(),
+ title: doc.title,
+ body: HTMLSerializer.serialize(rootElement),
+ };
+ } finally {
+ instance.destroy();
+ }
+}
+
+function assertFastbootResult(assert, expected) {
+ return function(actual) {
+ assert.equal(actual.url, expected.url);
+ assertHTMLMatches(assert, actual.body, expected.body);
+ };
+}
+
+// essentially doing the same as what is done in FastBoot 3.1.0
+// https://github.com/ember-fastboot/fastboot/blob/v3.1.0/src/sandbox.js
+function buildSandboxContext(precompile) {
+ let URL = require('url');
+
+ let sandbox = {
+ console,
+ setTimeout,
+ clearTimeout,
+ URL,
+
+ // Convince jQuery not to assume it's in a browser
+ module: { exports: {} },
+ };
+
+ // Set the global as `window`
+ sandbox.window = sandbox;
+ sandbox.window.self = sandbox;
+
+ let context = vm.createContext(sandbox);
+
+ let environmentSetupScript = new vm.Script(
+ `
+var EmberENV = {
+ _TEMPLATE_ONLY_GLIMMER_COMPONENTS: true,
+ _APPLICATION_TEMPLATE_WRAPPER: false,
+ _DEFAULT_ASYNC_OBSERVERS: true,
+ _JQUERY_INTEGRATION: false,
+};`,
+ { filename: 'prepend.js' }
+ );
+ environmentSetupScript.runInContext(context);
+
+ let emberSource = fs.readFileSync(emberPath, { encoding: 'utf-8' });
+ let emberScript = new vm.Script(emberSource, { filename: emberPath });
+ emberScript.runInContext(context);
+
+ let applicationSource = `
+class Router extends Ember.Router {}
+Router.map(function() {
+ this.route('a');
+ this.route('b');
+});
+
+const registry = {
+ 'router:main': Router,
+ 'template:application': ${precompile('Hello world!
\n{{outlet}}')}
+};
+
+class Resolver extends Ember.Object {
+ resolve(specifier) {
+ return registry[specifier];
+ }
+}
+
+var app = Ember.Application.extend().create({
+ autoboot: false,
+ Resolver,
+});
+`;
+ let appScript = new vm.Script(applicationSource, { filename: 'app.js' });
+ appScript.runInContext(context);
+
+ return context;
+}
+
+QUnit.module('Ember.Application - visit() Integration Tests', function(hooks) {
+ hooks.beforeEach(function() {
+ let { precompile } = loadEmber();
+ this.context = buildSandboxContext(precompile);
+ });
+
+ hooks.afterEach(function() {
+ clearEmber();
+ });
+
+ QUnit.test('FastBoot: basic', async function(assert) {
+ let result = await fastbootVisit(this.context, '/');
+
+ assert.equal(result.url, '/', 'landed on correct url');
+ assert.equal(
+ result.body,
+ 'Hello world!
\n',
+ 'results in expected HTML'
+ );
+ });
+});
diff --git a/tests/node/helpers/load-ember.js b/tests/node/helpers/load-ember.js
index 7a9da12fbd7..4b6d5df56a3 100644
--- a/tests/node/helpers/load-ember.js
+++ b/tests/node/helpers/load-ember.js
@@ -7,19 +7,27 @@ const templateCompilerPath = path.join(distPath, 'ember-template-compiler');
// properly to avoid the @glimmer/validator assertion
const originalGlobalSymbols = Object.getOwnPropertySymbols(global).map(sym => [sym, global[sym]]);
+module.exports.emberPath = require.resolve(emberPath);
+
module.exports.loadEmber = function() {
let Ember = require(emberPath);
- let precompile = require(templateCompilerPath).precompile;
+ let _precompile = require(templateCompilerPath).precompile;
+
+ let precompile = function(templateString, options) {
+ let templateSpec = _precompile(templateString, options);
+
+ return `Ember.HTMLBars.template(${templateSpec})`;
+ };
let compile = function(templateString, options) {
- let templateSpec = precompile(templateString, options);
+ let templateSpec = _precompile(templateString, options);
let template = new Function('return ' + templateSpec)();
return Ember.HTMLBars.template(template);
};
- return { Ember, compile };
+ return { Ember, compile, precompile };
};
module.exports.clearEmber = function() {