@ember/app-blueprint 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +19 -0
- package/.github/workflows/ci.yml +35 -0
- package/.github/workflows/plan-release.yml +94 -0
- package/.github/workflows/publish.yml +43 -0
- package/.prettierrc.cjs +13 -0
- package/.release-plan.json +22 -0
- package/CHANGELOG.md +17 -0
- package/RELEASE.md +27 -0
- package/eslint.config.mjs +30 -0
- package/files/.editorconfig +19 -0
- package/files/.ember-cli +7 -0
- package/files/.github/workflows/ci.yml +53 -0
- package/files/.prettierignore +13 -0
- package/files/.prettierrc.js +39 -0
- package/files/.stylelintignore +5 -0
- package/files/.stylelintrc.js +5 -0
- package/files/.template-lintrc.js +5 -0
- package/files/.watchmanconfig +3 -0
- package/files/README.md +58 -0
- package/files/_js_babel.config.cjs +42 -0
- package/files/_js_eslint.config.mjs +115 -0
- package/files/_ts_babel.config.cjs +50 -0
- package/files/_ts_eslint.config.mjs +135 -0
- package/files/app/app.ts +18 -0
- package/files/app/components/.gitkeep +0 -0
- package/files/app/config/environment.ts +17 -0
- package/files/app/controllers/.gitkeep +0 -0
- package/files/app/deprecation-workflow.ts +24 -0
- package/files/app/helpers/.gitkeep +0 -0
- package/files/app/models/.gitkeep +0 -0
- package/files/app/router.ts +11 -0
- package/files/app/routes/.gitkeep +0 -0
- package/files/app/styles/app.css +1 -0
- package/files/app/templates/_js_application.hbs +10 -0
- package/files/app/templates/_ts_application.gts +15 -0
- package/files/config/ember-cli-update.json +16 -0
- package/files/config/environment.js +48 -0
- package/files/config/optional-features.json +7 -0
- package/files/config/targets.js +11 -0
- package/files/ember-cli-build.js +22 -0
- package/files/gitignore +26 -0
- package/files/index.html +29 -0
- package/files/package.json +112 -0
- package/files/public/robots.txt +3 -0
- package/files/testem.js +25 -0
- package/files/tests/helpers/index.ts +43 -0
- package/files/tests/index.html +43 -0
- package/files/tests/integration/.gitkeep +0 -0
- package/files/tests/test-helper.ts +15 -0
- package/files/tests/unit/.gitkeep +0 -0
- package/files/tsconfig.json +31 -0
- package/files/vite.config.mjs +15 -0
- package/index.js +158 -0
- package/lib/directory-for-package-name.js +31 -0
- package/lib/prepend-emoji.js +12 -0
- package/package.json +33 -6
- package/tests/default.test.mjs +145 -0
- package/tests/fixture/app/components/custom-component.hbs +3 -0
- package/tests/fixture/app/initializers/test-init.js +6 -0
- package/tests/fixture/app/instance-initializers/test-instance-init.js +6 -0
- package/tests/fixture/app/router.js +12 -0
- package/tests/fixture/app/routes/styles.js +6 -0
- package/tests/fixture/app/styles/app.css +5 -0
- package/tests/fixture/app/templates/application.hbs +3 -0
- package/tests/fixture/app/templates/custom-component.hbs +1 -0
- package/tests/fixture/app/templates/index.hbs +1 -0
- package/tests/fixture/app/templates/styles.hbs +5 -0
- package/tests/fixture/testem-proxy.js +35 -0
- package/tests/fixture/tests/acceptance/app-init-test.js +13 -0
- package/tests/fixture/tests/acceptance/custom-component-test.js +14 -0
- package/tests/fixture/tests/acceptance/styles-test.js +18 -0
- package/tests/fixture/tests/acceptance/welcome-page-test.js +14 -0
- package/tests/fixture-ts/app/initializers/test-init.ts +10 -0
- package/tests/fixture-ts/app/instance-initializers/test-instance-init.ts +10 -0
- package/tests/fixture-ts/app/router.ts +12 -0
- package/tests/fixture-ts/app/routes/styles.ts +8 -0
- package/tests/fixture-ts/app/styles/app.css +5 -0
- package/tests/fixture-ts/app/templates/components/custom.gts +5 -0
- package/tests/fixture-ts/app/templates/custom-component.gts +5 -0
- package/tests/fixture-ts/app/templates/index.gts +5 -0
- package/tests/fixture-ts/app/templates/styles.gts +7 -0
- package/tests/fixture-ts/testem-proxy.js +36 -0
- package/tests/fixture-ts/tests/acceptance/app-init-test.ts +22 -0
- package/tests/fixture-ts/tests/acceptance/custom-component-test.ts +14 -0
- package/tests/fixture-ts/tests/acceptance/styles-test.ts +18 -0
- package/tests/fixture-ts/tests/acceptance/welcome-page-test.ts +14 -0
- package/tests/helpers.mjs +57 -0
- package/tests/typescript.test.mjs +24 -0
- package/vitest.config.ts +10 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title><%= namespace %> Tests</title>
|
|
6
|
+
<meta name="description" content="">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
+
|
|
9
|
+
{{content-for "head"}}
|
|
10
|
+
{{content-for "test-head"}}
|
|
11
|
+
|
|
12
|
+
<link rel="stylesheet" href="/@embroider/virtual/vendor.css">
|
|
13
|
+
<link rel="stylesheet" href="/@embroider/virtual/app.css">
|
|
14
|
+
<link rel="stylesheet" href="/@embroider/virtual/test-support.css">
|
|
15
|
+
|
|
16
|
+
{{content-for "head-footer"}}
|
|
17
|
+
{{content-for "test-head-footer"}}
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
{{content-for "body"}}
|
|
21
|
+
{{content-for "test-body"}}
|
|
22
|
+
|
|
23
|
+
<div id="qunit"></div>
|
|
24
|
+
<div id="qunit-fixture">
|
|
25
|
+
<div id="ember-testing-container">
|
|
26
|
+
<div id="ember-testing"></div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<script src="/testem.js" integrity="" data-embroider-ignore></script>
|
|
31
|
+
<script src="/@embroider/virtual/vendor.js"></script>
|
|
32
|
+
<script src="/@embroider/virtual/test-support.js"></script>
|
|
33
|
+
<script type="module">import "ember-testing";</script>
|
|
34
|
+
|
|
35
|
+
<script type="module">
|
|
36
|
+
import { start } from './test-helper';
|
|
37
|
+
import.meta.glob("./**/*.{js,ts,gjs,gts}", { eager: true });
|
|
38
|
+
start();
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
{{content-for "body-footer"}}
|
|
42
|
+
</body>
|
|
43
|
+
</html>
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Application from '<%= modulePrefix %>/app';
|
|
2
|
+
import config from '<%= modulePrefix %>/config/environment';
|
|
3
|
+
import * as QUnit from 'qunit';
|
|
4
|
+
import { setApplication } from '@ember/test-helpers';
|
|
5
|
+
import { setup } from 'qunit-dom';
|
|
6
|
+
import { start as qunitStart, setupEmberOnerrorValidation } from 'ember-qunit';
|
|
7
|
+
|
|
8
|
+
export function start() {
|
|
9
|
+
setApplication(Application.create(config.APP));
|
|
10
|
+
|
|
11
|
+
setup(QUnit.assert);
|
|
12
|
+
setupEmberOnerrorValidation();
|
|
13
|
+
|
|
14
|
+
qunitStart();
|
|
15
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "@ember/app-tsconfig",
|
|
3
|
+
"include": [
|
|
4
|
+
"app", "tests", "types"
|
|
5
|
+
],
|
|
6
|
+
"glint": {
|
|
7
|
+
"environment": [
|
|
8
|
+
"ember-loose",
|
|
9
|
+
"ember-template-imports"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"compilerOptions": {
|
|
13
|
+
"allowJs": true,
|
|
14
|
+
"paths": {
|
|
15
|
+
"<%= name %>/tests/*": [
|
|
16
|
+
"./tests/*"
|
|
17
|
+
],
|
|
18
|
+
"<%= name %>/*": [
|
|
19
|
+
"./app/*"
|
|
20
|
+
],
|
|
21
|
+
"*": [
|
|
22
|
+
"./types/*"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"types": [
|
|
26
|
+
"ember-source/types",
|
|
27
|
+
"@embroider/core/virtual",
|
|
28
|
+
"vite/client"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import { extensions, classicEmberSupport, ember } from '@embroider/vite';
|
|
3
|
+
import { babel } from '@rollup/plugin-babel';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [
|
|
7
|
+
classicEmberSupport(),
|
|
8
|
+
ember(),
|
|
9
|
+
// extra plugins here
|
|
10
|
+
babel({
|
|
11
|
+
babelHelpers: 'runtime',
|
|
12
|
+
extensions,
|
|
13
|
+
}),
|
|
14
|
+
],
|
|
15
|
+
});
|
package/index.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const stringUtil = require('ember-cli-string-utils');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const directoryForPackageName = require('./lib/directory-for-package-name');
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
description: 'The default blueprint for ember-cli projects.',
|
|
9
|
+
|
|
10
|
+
shouldTransformTypeScript: true,
|
|
11
|
+
|
|
12
|
+
filesToRemove: [
|
|
13
|
+
'app/styles/.gitkeep',
|
|
14
|
+
'app/templates/.gitkeep',
|
|
15
|
+
'app/views/.gitkeep',
|
|
16
|
+
'public/.gitkeep',
|
|
17
|
+
'Brocfile.js',
|
|
18
|
+
'testem.json',
|
|
19
|
+
],
|
|
20
|
+
|
|
21
|
+
locals(options) {
|
|
22
|
+
let entity = options.entity;
|
|
23
|
+
let rawName = entity.name;
|
|
24
|
+
let name = stringUtil.dasherize(rawName);
|
|
25
|
+
let namespace = stringUtil.classify(rawName);
|
|
26
|
+
|
|
27
|
+
let hasOptions = !options.welcome || options.packageManager || options.ciProvider;
|
|
28
|
+
let blueprintOptions = '';
|
|
29
|
+
if (hasOptions) {
|
|
30
|
+
let indent = `\n `;
|
|
31
|
+
let outdent = `\n `;
|
|
32
|
+
|
|
33
|
+
blueprintOptions =
|
|
34
|
+
indent +
|
|
35
|
+
[
|
|
36
|
+
!options.welcome && '"--no-welcome"',
|
|
37
|
+
options.packageManager === 'yarn' && '"--yarn"',
|
|
38
|
+
options.packageManager === 'pnpm' && '"--pnpm"',
|
|
39
|
+
options.ciProvider && `"--ci-provider=${options.ciProvider}"`,
|
|
40
|
+
options.typescript && `"--typescript"`,
|
|
41
|
+
!options.emberData && `"--no-ember-data"`,
|
|
42
|
+
]
|
|
43
|
+
.filter(Boolean)
|
|
44
|
+
.join(',\n ') +
|
|
45
|
+
outdent;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let invokeScriptPrefix = 'npm run';
|
|
49
|
+
let execBinPrefix = 'npm exec';
|
|
50
|
+
|
|
51
|
+
if (options.packageManager === 'yarn') {
|
|
52
|
+
invokeScriptPrefix = 'yarn';
|
|
53
|
+
execBinPrefix = 'yarn';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (options.packageManager === 'pnpm') {
|
|
57
|
+
invokeScriptPrefix = 'pnpm';
|
|
58
|
+
execBinPrefix = 'pnpm';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
appDirectory: directoryForPackageName(name),
|
|
63
|
+
name,
|
|
64
|
+
modulePrefix: name,
|
|
65
|
+
namespace,
|
|
66
|
+
blueprintVersion: require('./package').version,
|
|
67
|
+
yarn: options.packageManager === 'yarn',
|
|
68
|
+
pnpm: options.packageManager === 'pnpm',
|
|
69
|
+
npm: options.packageManager !== 'yarn' && options.packageManager !== 'pnpm',
|
|
70
|
+
invokeScriptPrefix,
|
|
71
|
+
execBinPrefix,
|
|
72
|
+
welcome: options.welcome,
|
|
73
|
+
blueprint: 'app',
|
|
74
|
+
blueprintOptions,
|
|
75
|
+
lang: options.lang,
|
|
76
|
+
emberData: options.emberData,
|
|
77
|
+
ciProvider: options.ciProvider,
|
|
78
|
+
typescript: options.typescript,
|
|
79
|
+
packageManager: options.packageManager ?? 'npm',
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
files(options) {
|
|
84
|
+
if (this._files) {
|
|
85
|
+
return this._files;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let files = this._super();
|
|
89
|
+
|
|
90
|
+
if (options.ciProvider !== 'github') {
|
|
91
|
+
files = files.filter((file) => file.indexOf('.github') < 0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!options.typescript) {
|
|
95
|
+
files = files.filter(
|
|
96
|
+
(file) => !['tsconfig.json', 'app/config/', 'types/'].includes(file) && !file.endsWith('.d.ts')
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!options.emberData) {
|
|
101
|
+
files = files.filter((file) => !file.includes('models/'));
|
|
102
|
+
files = files.filter((file) => !file.includes('ember-data/'));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
this._files = files;
|
|
106
|
+
|
|
107
|
+
return this._files;
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
beforeInstall() {
|
|
111
|
+
const prependEmoji = require('./lib/prepend-emoji');
|
|
112
|
+
|
|
113
|
+
this.ui.writeLine(prependEmoji('✨', `Creating a new Ember app in ${chalk.yellow(process.cwd())}:`));
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @override
|
|
118
|
+
*
|
|
119
|
+
* This modification of buildFileInfo allows our differing
|
|
120
|
+
* input files to output to a single file, depending on the options.
|
|
121
|
+
* For example:
|
|
122
|
+
*
|
|
123
|
+
* for javascript,
|
|
124
|
+
* _ts_eslint.config.mjs is deleted
|
|
125
|
+
* _js_eslint.config.mjs is renamed to eslint.config.mjs
|
|
126
|
+
*
|
|
127
|
+
* for typescript,
|
|
128
|
+
* _js_eslint.config.mjs is deleted
|
|
129
|
+
* _ts_eslint.config.mjs is renamed to eslint.config.mjs
|
|
130
|
+
*/
|
|
131
|
+
buildFileInfo(intoDir, templateVariables, file, options) {
|
|
132
|
+
let fileInfo = this._super.buildFileInfo.apply(this, arguments);
|
|
133
|
+
|
|
134
|
+
if (file.includes('_js_')) {
|
|
135
|
+
if (options.typescript) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
fileInfo.outputBasePath = fileInfo.outputPath.replace('_js_', '');
|
|
140
|
+
fileInfo.outputPath = fileInfo.outputPath.replace('_js_', '');
|
|
141
|
+
fileInfo.displayPath = fileInfo.outputPath.replace('_js_', '');
|
|
142
|
+
return fileInfo;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (file.includes('_ts_')) {
|
|
146
|
+
if (!options.typescript) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
fileInfo.outputBasePath = fileInfo.outputPath.replace('_ts_', '');
|
|
151
|
+
fileInfo.outputPath = fileInfo.outputPath.replace('_ts_', '');
|
|
152
|
+
fileInfo.displayPath = fileInfo.outputPath.replace('_ts_', '');
|
|
153
|
+
return fileInfo;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return fileInfo;
|
|
157
|
+
},
|
|
158
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Derive a directory name from a package name.
|
|
7
|
+
* Takes scoped packages into account.
|
|
8
|
+
*
|
|
9
|
+
* @method directoryForPackageName
|
|
10
|
+
* @param {String} packageName
|
|
11
|
+
* @return {String} Derived directory name.
|
|
12
|
+
*/
|
|
13
|
+
module.exports = function directoryForPackageName(packageName) {
|
|
14
|
+
let isScoped = packageName[0] === '@' && packageName.includes('/');
|
|
15
|
+
|
|
16
|
+
if (isScoped) {
|
|
17
|
+
let slashIndex = packageName.indexOf('/');
|
|
18
|
+
let scopeName = packageName.substring(1, slashIndex);
|
|
19
|
+
let packageNameWithoutScope = packageName.substring(slashIndex + 1);
|
|
20
|
+
let pathParts = process.cwd().split(path.sep);
|
|
21
|
+
let parentDirectoryContainsScopeName = pathParts.includes(scopeName);
|
|
22
|
+
|
|
23
|
+
if (parentDirectoryContainsScopeName) {
|
|
24
|
+
return packageNameWithoutScope;
|
|
25
|
+
} else {
|
|
26
|
+
return `${scopeName}-${packageNameWithoutScope}`;
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
return packageName;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function supportEmoji() {
|
|
4
|
+
const hasEmojiTurnedOff = process.argv.indexOf('--no-emoji') > -1;
|
|
5
|
+
return process.stdout.isTTY && process.platform !== 'win32' && !hasEmojiTurnedOff;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const areEmojiSupported = supportEmoji();
|
|
9
|
+
|
|
10
|
+
module.exports = function prependEmoji(emoji, msg) {
|
|
11
|
+
return areEmojiSupported ? `${emoji} ${msg}` : msg;
|
|
12
|
+
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ember/app-blueprint",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "",
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Blueprint for next generation of Ember apps",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ember-blueprint"
|
|
7
|
+
],
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git@github.com:ember-cli/ember-app-blueprint.git"
|
|
11
|
+
},
|
|
8
12
|
"license": "MIT",
|
|
13
|
+
"author": "",
|
|
14
|
+
"main": "index.js",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"lodash": "^4.17.21",
|
|
17
|
+
"walk-sync": "^3.0.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@eslint/js": "^9.3.0",
|
|
21
|
+
"ember-cli": "^6.3.1",
|
|
22
|
+
"eslint": "9.x",
|
|
23
|
+
"eslint-config-prettier": "^9.1.0",
|
|
24
|
+
"execa": "^9.1.0",
|
|
25
|
+
"fixturify": "^3.0.0",
|
|
26
|
+
"globals": "^15.3.0",
|
|
27
|
+
"prettier": "^3.2.5",
|
|
28
|
+
"prettier-plugin-ember-template-tag": "^2.0.2",
|
|
29
|
+
"release-plan": "^0.16.0",
|
|
30
|
+
"resolve-bin": "^1.0.1",
|
|
31
|
+
"strip-ansi": "^7.1.0",
|
|
32
|
+
"tmp-promise": "^3.0.3",
|
|
33
|
+
"vitest": "^3.1.2"
|
|
34
|
+
},
|
|
9
35
|
"scripts": {
|
|
10
|
-
"
|
|
36
|
+
"lint": "eslint .",
|
|
37
|
+
"test": "vitest"
|
|
11
38
|
}
|
|
12
39
|
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { existsSync, writeFileSync } from 'fs';
|
|
4
|
+
import stripAnsi from 'strip-ansi';
|
|
5
|
+
import { newProjectWithFixtures } from './helpers.mjs';
|
|
6
|
+
|
|
7
|
+
const SCENARIOS = [
|
|
8
|
+
{
|
|
9
|
+
flags: [
|
|
10
|
+
/* none, default */
|
|
11
|
+
],
|
|
12
|
+
fixturePath: join(import.meta.dirname, 'fixture'),
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
flags: ['--typescript'],
|
|
16
|
+
fixturePath: join(import.meta.dirname, 'fixture-ts'),
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
describe('basic functionality', function () {
|
|
21
|
+
for (let { flags, fixturePath } of SCENARIOS) {
|
|
22
|
+
describe(`with flags: '${flags.join(' ')}'`, function () {
|
|
23
|
+
let project = newProjectWithFixtures({
|
|
24
|
+
fixturePath,
|
|
25
|
+
flags,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('verify files', async function () {
|
|
29
|
+
expect(
|
|
30
|
+
!existsSync(join(project.dir(), 'app/index.html')),
|
|
31
|
+
'the app index.html has been removed',
|
|
32
|
+
);
|
|
33
|
+
expect(
|
|
34
|
+
existsSync(join(project.dir(), 'index.html')),
|
|
35
|
+
'the root index.html has been added',
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('successfully lints', async function () {
|
|
40
|
+
let result = await project.execa('pnpm', ['lint']);
|
|
41
|
+
|
|
42
|
+
console.log(result.stdout);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('successfully builds', async function () {
|
|
46
|
+
let result = await project.execa('pnpm', ['build']);
|
|
47
|
+
|
|
48
|
+
console.log(result.stdout);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('successfully runs tests', async function () {
|
|
52
|
+
let result;
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
result = await project.execa('pnpm', ['test:ember']);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
console.log(err.stdout, err.stderr);
|
|
58
|
+
throw 'Failed to successfully run test:ember';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// make sure that each of the tests that we expect actually show up
|
|
62
|
+
// alternatively we can change this to search for `pass 3`
|
|
63
|
+
expect(result.stdout).to.contain(
|
|
64
|
+
'Acceptance | welcome page: visiting /index shows the welcome page',
|
|
65
|
+
);
|
|
66
|
+
expect(result.stdout).to.contain(
|
|
67
|
+
'Acceptance | styles: visiting /styles',
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
console.log(result.stdout);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('successfully runs tests in dev mode', async function () {
|
|
74
|
+
await project.$`pnpm install --save-dev testem http-proxy`;
|
|
75
|
+
let appURL;
|
|
76
|
+
|
|
77
|
+
let server;
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
server = project.execa('pnpm', ['start']);
|
|
81
|
+
|
|
82
|
+
await new Promise((resolve) => {
|
|
83
|
+
server.stdout.on('data', (line) => {
|
|
84
|
+
let result = /Local:\s+(https?:\/\/.*)\//g.exec(
|
|
85
|
+
stripAnsi(line.toString()),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
if (result) {
|
|
89
|
+
appURL = result[1];
|
|
90
|
+
resolve();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
writeFileSync(
|
|
96
|
+
join(project.dir(), 'testem-dev.js'),
|
|
97
|
+
`module.exports = {
|
|
98
|
+
test_page: 'tests/index.html?hidepassed',
|
|
99
|
+
disable_watching: true,
|
|
100
|
+
launch_in_ci: ['Chrome'],
|
|
101
|
+
launch_in_dev: ['Chrome'],
|
|
102
|
+
browser_start_timeout: 120,
|
|
103
|
+
browser_args: {
|
|
104
|
+
Chrome: {
|
|
105
|
+
ci: [
|
|
106
|
+
// --no-sandbox is needed when running Chrome inside a container
|
|
107
|
+
process.env.CI ? '--no-sandbox' : null,
|
|
108
|
+
'--headless',
|
|
109
|
+
'--disable-dev-shm-usage',
|
|
110
|
+
'--disable-software-rasterizer',
|
|
111
|
+
'--mute-audio',
|
|
112
|
+
'--remote-debugging-port=0',
|
|
113
|
+
'--window-size=1440,900',
|
|
114
|
+
].filter(Boolean),
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
middleware: [
|
|
118
|
+
require(__dirname + '/testem-proxy.js')('${appURL}')
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
`,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
let testResult = await project.execa('pnpm', [
|
|
125
|
+
'testem',
|
|
126
|
+
'--file',
|
|
127
|
+
'testem-dev.js',
|
|
128
|
+
'ci',
|
|
129
|
+
]);
|
|
130
|
+
expect(testResult.exitCode).to.eq(0, testResult.output);
|
|
131
|
+
} finally {
|
|
132
|
+
server?.kill('SIGINT');
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('successfully optimizes deps', function () {
|
|
137
|
+
return project.execa('pnpm', ['vite', 'optimize', '--force']);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('can run generators', function () {
|
|
141
|
+
return project.execa('pnpm', ['ember', 'g', 'route', 'fancy']);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import EmberRouter from '@ember/routing/router';
|
|
2
|
+
import config from 'test-app/config/environment';
|
|
3
|
+
|
|
4
|
+
export default class Router extends EmberRouter {
|
|
5
|
+
location = config.locationType;
|
|
6
|
+
rootURL = config.rootURL;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
Router.map(function () {
|
|
10
|
+
this.route('styles');
|
|
11
|
+
this.route('custom-component');
|
|
12
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<CustomComponent />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<WelcomePage />
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const httpProxy = require('http-proxy');
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
This can be installed as a testem middleware to make testem run against an
|
|
5
|
+
arbitrary real webserver at targetURL.
|
|
6
|
+
|
|
7
|
+
It allows testem to handle the well-known testem-specific paths and proxies
|
|
8
|
+
everything else, while rewriting the testem-added prefix out of your
|
|
9
|
+
"/tests/index.html" URL.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
module.exports = function testemProxy(targetURL) {
|
|
13
|
+
return function testemProxyHandler(app) {
|
|
14
|
+
const proxy = httpProxy.createProxyServer({
|
|
15
|
+
changeOrigin: true,
|
|
16
|
+
ignorePath: true,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
proxy.on('error', (err, _req, res) => {
|
|
20
|
+
res && res.status && res.status(500).json(err);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
app.all('*', (req, res, next) => {
|
|
24
|
+
let url = req.url;
|
|
25
|
+
if (url === '/testem.js' || url.startsWith('/testem/')) {
|
|
26
|
+
return next();
|
|
27
|
+
}
|
|
28
|
+
let m = /^(\/\d+)\/tests\/index.html/.exec(url);
|
|
29
|
+
if (m) {
|
|
30
|
+
url = url.slice(m[1].length);
|
|
31
|
+
}
|
|
32
|
+
proxy.web(req, res, { target: targetURL + url });
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { module, test } from 'qunit';
|
|
2
|
+
import { getApplication } from '@ember/test-helpers';
|
|
3
|
+
import { setupApplicationTest } from 'test-app/tests/helpers';
|
|
4
|
+
|
|
5
|
+
module('Acceptance | app route', function (hooks) {
|
|
6
|
+
setupApplicationTest(hooks);
|
|
7
|
+
|
|
8
|
+
test('loaded initializers /', async function (assert) {
|
|
9
|
+
const app = getApplication();
|
|
10
|
+
assert.strictEqual([...app._applicationInstances][0].__instance_test_init, 'set in the instance initializer');
|
|
11
|
+
assert.strictEqual(app.__test_init, 'coming from the initializer');
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { module, test } from 'qunit';
|
|
2
|
+
import { visit, currentURL } from '@ember/test-helpers';
|
|
3
|
+
import { setupApplicationTest } from 'test-app/tests/helpers';
|
|
4
|
+
|
|
5
|
+
module('Acceptance | custom-component page', function (hooks) {
|
|
6
|
+
setupApplicationTest(hooks);
|
|
7
|
+
|
|
8
|
+
test('visiting /custom-component', async function (assert) {
|
|
9
|
+
await visit('/custom-component');
|
|
10
|
+
|
|
11
|
+
assert.strictEqual(currentURL(), '/custom-component');
|
|
12
|
+
assert.dom('#custom-component').containsText('I am a custom component');
|
|
13
|
+
});
|
|
14
|
+
})
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { module, test } from 'qunit';
|
|
2
|
+
import { visit } from '@ember/test-helpers';
|
|
3
|
+
import { setupApplicationTest } from 'test-app/tests/helpers';
|
|
4
|
+
|
|
5
|
+
module('Acceptance | styles', function (hooks) {
|
|
6
|
+
setupApplicationTest(hooks);
|
|
7
|
+
|
|
8
|
+
test('visiting /styles', async function (assert) {
|
|
9
|
+
await visit('/styles');
|
|
10
|
+
|
|
11
|
+
assert.dom('.styles-test').hasStyle(
|
|
12
|
+
{
|
|
13
|
+
'background-color': 'rgb(0, 0, 255)',
|
|
14
|
+
},
|
|
15
|
+
'The background should be blue if the app styles are working correctly',
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { module, test } from 'qunit';
|
|
2
|
+
import { visit, currentURL } from '@ember/test-helpers';
|
|
3
|
+
import { setupApplicationTest } from 'test-app/tests/helpers';
|
|
4
|
+
|
|
5
|
+
module('Acceptance | welcome page', function (hooks) {
|
|
6
|
+
setupApplicationTest(hooks);
|
|
7
|
+
|
|
8
|
+
test('visiting /index shows the welcome page', async function (assert) {
|
|
9
|
+
await visit('/');
|
|
10
|
+
|
|
11
|
+
assert.strictEqual(currentURL(), '/');
|
|
12
|
+
assert.dom('h1').containsText('Congratulations, you made it!');
|
|
13
|
+
});
|
|
14
|
+
});
|