Skip to content

Commit 6a1cf0c

Browse files
author
Ellery Newcomer
committed
set up unit tests
jasmine + karma
1 parent 429d802 commit 6a1cf0c

File tree

8 files changed

+223
-9
lines changed

8 files changed

+223
-9
lines changed

aurelia_project/aurelia.json

+13-8
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,7 @@
1919
}
2020
],
2121
"options": {
22-
"minify": {
23-
"prod": {
24-
"compress": {
25-
"collapse_vars": false
26-
}
27-
}
28-
},
22+
"minify": false,
2923
"sourcemaps": "dev & stage"
3024
},
3125
"bundles": [
@@ -221,7 +215,14 @@
221215
"id": "vscode",
222216
"displayName": "Visual Studio Code"
223217
},
224-
"unitTestRunner": {
218+
"unitTestRunners": [
219+
{
220+
"id": "karma",
221+
"displayName": "Karma",
222+
"source": "test/unit/**/*.ts"
223+
}
224+
],
225+
"integrationTestRunner": {
225226
"id": "none",
226227
"displayName": "None"
227228
},
@@ -236,5 +237,9 @@
236237
"attributes": "resources/attributes",
237238
"valueConverters": "resources/value-converters",
238239
"bindingBehaviors": "resources/binding-behaviors"
240+
},
241+
"testFramework": {
242+
"id": "jasmine",
243+
"displayName": "Jasmine"
239244
}
240245
}

aurelia_project/tasks/test.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "test",
3+
"description": "Runs all unit tests and reports the results.",
4+
"flags": [
5+
{
6+
"name": "env",
7+
"description": "Sets the build environment.",
8+
"type": "string"
9+
},
10+
{
11+
"name": "watch",
12+
"description": "Watches test files for changes and re-runs the tests automatically.",
13+
"type": "boolean"
14+
}
15+
]
16+
}

aurelia_project/tasks/test.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import * as gulp from 'gulp';
2+
import {Server as Karma} from 'karma';
3+
import {CLIOptions} from 'aurelia-cli';
4+
import build from './build';
5+
import watch from './watch';
6+
import * as path from 'path';
7+
8+
let karma = done => {
9+
new Karma({
10+
configFile: path.join(__dirname, '/../../karma.conf.js'),
11+
singleRun: !CLIOptions.hasFlag('watch')
12+
}, done).start();
13+
};
14+
15+
let unit;
16+
17+
if (CLIOptions.hasFlag('watch')) {
18+
unit = gulp.series(
19+
build,
20+
gulp.parallel(
21+
done => { watch(); done(); },
22+
karma
23+
)
24+
);
25+
} else {
26+
unit = gulp.series(
27+
build,
28+
karma
29+
);
30+
}
31+
32+
export { unit as default };

karma.conf.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
const path = require('path');
3+
const project = require('./aurelia_project/aurelia.json');
4+
const tsconfig = require('./tsconfig.json');
5+
const karmaConfig = project.unitTestRunners.find(x => x.id === 'karma');
6+
7+
let testSrc = [
8+
{ pattern: karmaConfig.source, included: false },
9+
'test/aurelia-karma.js'
10+
];
11+
12+
let output = project.platform.output;
13+
let appSrc = project.build.bundles.map(x => path.join(output, x.name));
14+
let entryIndex = appSrc.indexOf(path.join(output, project.build.loader.configTarget));
15+
let entryBundle = appSrc.splice(entryIndex, 1)[0];
16+
let sourceMaps = [{pattern:'scripts/**/*.js.map', included: false}];
17+
let files = [entryBundle].concat(testSrc).concat(appSrc).concat(sourceMaps);
18+
19+
let compilerOptions = tsconfig.compilerOptions;
20+
compilerOptions.inlineSourceMap = true;
21+
compilerOptions.inlineSources = true;
22+
23+
module.exports = function(config) {
24+
config.set({
25+
basePath: '',
26+
frameworks: [project.testFramework.id],
27+
files: files,
28+
exclude: [],
29+
preprocessors: {
30+
[karmaConfig.source]: [project.transpiler.id],
31+
[appSrc]: ['sourcemap']
32+
},
33+
typescriptPreprocessor: {
34+
typescript: require('typescript'),
35+
options: compilerOptions
36+
},
37+
reporters: ['progress'],
38+
port: 9876,
39+
colors: true,
40+
logLevel: config.LOG_INFO,
41+
autoWatch: true,
42+
browsers: ['Chrome'],
43+
singleRun: false,
44+
// client.args must be a array of string.
45+
// Leave 'aurelia-root', project.paths.root in this order so we can find
46+
// the root of the aurelia project.
47+
client: {
48+
args: ['aurelia-root', project.paths.root]
49+
}
50+
});
51+
};
52+

package.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@
6262
"tslint": "^3.11.0",
6363
"typescript": ">=1.9.0-dev || ^2.0.0",
6464
"uglify-js": "^3.0.19",
65-
"vinyl-fs": "^2.4.3"
65+
"vinyl-fs": "^2.4.3",
66+
"jasmine-core": "^2.4.1",
67+
"karma": "^0.13.22",
68+
"karma-chrome-launcher": "^2.2.0",
69+
"karma-jasmine": "^1.0.2",
70+
"karma-sourcemap-loader": "^0.3.7",
71+
"karma-typescript-preprocessor": "^0.2.1",
72+
"@types/jasmine": "^2.2.0"
6673
}
6774
}

test/aurelia-karma.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
(function(global) {
2+
var karma = global.__karma__;
3+
var requirejs = global.requirejs
4+
var locationPathname = global.location.pathname;
5+
var root = 'src';
6+
karma.config.args.forEach(function(value, index) {
7+
if (value === 'aurelia-root') {
8+
root = karma.config.args[index + 1];
9+
}
10+
});
11+
12+
if (!karma || !requirejs) {
13+
return;
14+
}
15+
16+
function normalizePath(path) {
17+
var normalized = []
18+
var parts = path
19+
.split('?')[0] // cut off GET params, used by noext requirejs plugin
20+
.split('/')
21+
22+
for (var i = 0; i < parts.length; i++) {
23+
if (parts[i] === '.') {
24+
continue
25+
}
26+
27+
if (parts[i] === '..' && normalized.length && normalized[normalized.length - 1] !== '..') {
28+
normalized.pop()
29+
continue
30+
}
31+
32+
normalized.push(parts[i])
33+
}
34+
35+
// Use case of testing source code. RequireJS doesn't add .js extension to files asked via sibling selector
36+
// If normalized path doesn't include some type of extension, add the .js to it
37+
if (normalized.length > 0 && normalized[normalized.length - 1].indexOf('.') < 0) {
38+
normalized[normalized.length - 1] = normalized[normalized.length - 1] + '.js'
39+
}
40+
41+
return normalized.join('/')
42+
}
43+
44+
function patchRequireJS(files, originalLoadFn, locationPathname) {
45+
var IS_DEBUG = /debug\.html$/.test(locationPathname)
46+
47+
requirejs.load = function (context, moduleName, url) {
48+
url = normalizePath(url)
49+
50+
if (files.hasOwnProperty(url) && !IS_DEBUG) {
51+
url = url + '?' + files[url]
52+
}
53+
54+
if (url.indexOf('/base') !== 0) {
55+
url = '/base/' + url;
56+
}
57+
58+
return originalLoadFn.call(this, context, moduleName, url)
59+
}
60+
61+
var originalDefine = global.define;
62+
global.define = function(name, deps, m) {
63+
if (typeof name === 'string') {
64+
originalDefine('/base/' + root + '/' + name, [name], function (result) { return result; });
65+
}
66+
67+
return originalDefine(name, deps, m);
68+
}
69+
}
70+
71+
function requireTests() {
72+
var TEST_REGEXP = /(spec)\.js$/i;
73+
var allTestFiles = ['/base/test/unit/setup.js'];
74+
75+
Object.keys(window.__karma__.files).forEach(function(file) {
76+
if (TEST_REGEXP.test(file)) {
77+
allTestFiles.push(file);
78+
}
79+
});
80+
81+
require(allTestFiles, window.__karma__.start);
82+
}
83+
84+
karma.loaded = function() {}; // make it async
85+
patchRequireJS(karma.files, requirejs.load, locationPathname);
86+
requireTests();
87+
})(window);

test/unit/app.spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {QrCodeDisplayDialog } from '../../src/qrcodes/display-dialog';
2+
3+
describe('qrcode display', () => {
4+
it('chunks data', () => {
5+
let display = new QrCodeDisplayDialog(null);
6+
7+
let result = display.obtainData("abcdefghij", 3);
8+
9+
expect(result).toEqual(["abc", "def", "ghi", "j"]);
10+
11+
});
12+
});

test/unit/setup.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import 'aurelia-polyfills';
2+
import {initialize} from 'aurelia-pal-browser';
3+
initialize();

0 commit comments

Comments
 (0)