Add scar tests.

This commit is contained in:
Lars Jung 2016-06-01 02:15:04 +02:00
parent 1cba9290b6
commit c4fa90a747
12 changed files with 263 additions and 3 deletions

39
ghu.js
View file

@ -7,6 +7,7 @@ const {
const ROOT = resolve(__dirname);
const SRC = join(ROOT, 'src');
const TEST = join(ROOT, 'test');
const TEST_SCAR = join(ROOT, 'test-scar');
const BUILD = join(ROOT, 'build');
const mapper = mapfn.p(SRC, BUILD).s('.less', '.css').s('.jade', '');
@ -150,7 +151,41 @@ ghu.task('build:tests', ['build:scripts', 'build:styles'], 'build the test suite
});
});
ghu.task('build', ['build:scripts', 'build:styles', 'build:pages', 'build:copy', 'build:tests'],
ghu.task('build:tests-scar', ['build:scripts', 'build:styles'], 'build the test suite', () => {
const webpackConfig = {
module: {
loaders: [
{
include: [TEST_SCAR],
loader: 'babel',
query: {cacheDirectory: true}
}
]
}
};
return Promise.all([
read(`${BUILD}/_h5ai/public/js/scripts.js`)
.then(newerThan(`${BUILD}/test-scar/h5ai-scripts.js`))
.then(write(`${BUILD}/test-scar/h5ai-scripts.js`, {overwrite: true})),
read(`${BUILD}/_h5ai/public/css/styles.css`)
.then(newerThan(`${BUILD}/test-scar/h5ai-styles.css`))
.then(write(`${BUILD}/test-scar/h5ai-styles.css`, {overwrite: true})),
read(`${TEST_SCAR}/tests.html`)
.then(newerThan(`${BUILD}/test-scar/tests.html`))
.then(write(`${BUILD}/test-scar/tests.html`, {overwrite: true})),
read(`${TEST_SCAR}: tests.js`)
.then(webpack(webpackConfig, {showStats: false}))
.then(write(mapfn.p(TEST_SCAR, `${BUILD}/test-scar`), {overwrite: true}))
]).then(() => {
console.log(`browse to file://${BUILD}/test-scar/tests.html to run the test suite`);
});
});
ghu.task('build', ['build:scripts', 'build:styles', 'build:pages', 'build:copy', 'build:tests', 'build:tests-scar'],
'build all updated files, optionally use :production');
ghu.task('deploy', ['build'], 'deploy to a specified path with :dest=/some/path', runtime => {
@ -167,7 +202,7 @@ ghu.task('deploy', ['build'], 'deploy to a specified path with :dest=/some/path'
});
ghu.task('watch', runtime => {
return watch([SRC, TEST], () => ghu.run(runtime.sequence.filter(x => x !== 'watch'), runtime.args, true));
return watch([SRC, TEST, TEST_SCAR], () => ghu.run(runtime.sequence.filter(x => x !== 'watch'), runtime.args, true));
});
ghu.task('release', ['force-production', 'clean', 'build'], 'create a zipball', runtime => {

View file

@ -18,7 +18,9 @@
"babel-loader": "6.2.4",
"babel-preset-es2015": "6.9.0",
"eslint": "2.11.0",
"ghu": "0.6.0"
"ghu": "0.6.0",
"scar": "0.10.1",
"sinon": "2.0.0-pre"
},
"engines": {
"node": ">=6.0.0"

3
test-scar/.eslintrc Normal file
View file

@ -0,0 +1,3 @@
---
env:
browser: true

10
test-scar/tests.html Normal file
View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>h5ai test suite - scar</title>
<link rel="stylesheet" href="h5ai-styles.css">
<script src="h5ai-scripts.js"></script>
<script src="tests.js"></script>
</head>
</html>

16
test-scar/tests.js Normal file
View file

@ -0,0 +1,16 @@
const {test} = require('scar');
const {clearModulejs, mockConfigModule} = require('./util/modjs');
const {pinHtml} = require('./util/pin');
mockConfigModule();
clearModulejs();
require('./tests/premisses');
require('./tests/unit/boot');
require('./tests/unit/config');
require('./tests/unit/libs');
require('./tests/unit/modulejs');
pinHtml();
test.cli({sync: true});

View file

@ -0,0 +1,21 @@
const {test, assert} = require('scar');
test('window is global object', () => {
assert.equal(typeof window, 'object');
assert.equal(window, window.window);
});
test('document is global object', () => {
assert.equal(typeof window.document, 'object');
});
test('jQuery and $ are global functions', () => {
assert.equal(typeof window.jQuery, 'function');
assert.equal(window.jQuery.fn.jquery, '2.2.4');
assert.equal(window.jQuery, window.$);
});
test('_ is global function', () => {
assert.equal(typeof window._, 'function');
assert.equal(window._.VERSION, '4.13.1');
});

View file

@ -0,0 +1,33 @@
const {test, assert} = require('scar');
const sinon = require('sinon');
const ID = 'boot';
const DEPS = ['$', 'core/server'];
const getDef = () => window.modulejs._private.definitions[ID];
const createInst = () => getDef().fn.call(null, window.jQuery, {});
test(`module '${ID}' is defined`, () => {
assert.ok(getDef());
});
test(`module '${ID}' has correct id`, () => {
assert.equal(getDef().id, ID);
});
test(`module '${ID}' has correct deps`, () => {
assert.deepEqual(getDef().deps, DEPS);
});
test(`module '${ID}' has args for each dependency`, () => {
const def = getDef();
assert.deepEqual(def.deps.length, def.fn.length);
});
test(`module '${ID}' inits without errors`, () => {
createInst();
});
test(`module '${ID}' instance is undefined`, () => {
assert.equal(createInst(), undefined);
});

View file

@ -0,0 +1,32 @@
const {test, assert} = require('scar');
const ID = 'config';
const DEPS = [];
const getDef = () => window.modulejs._private.definitions[ID];
const createInst = () => getDef().fn();
test(`module '${ID}' is defined`, () => {
assert.ok(getDef());
});
test(`module '${ID}' has correct id`, () => {
assert.equal(getDef().id, ID);
});
test(`module '${ID}' has correct deps`, () => {
assert.deepEqual(getDef().deps, DEPS);
});
test(`module '${ID}' has args for each dependency`, () => {
const def = getDef();
assert.deepEqual(def.deps.length, def.fn.length);
});
test(`module '${ID}' inits without errors`, () => {
createInst();
});
test(`module '${ID}' is only dummy definiton`, () => {
assert.deepEqual(createInst(), {_dummyConfig: true});
});

View file

@ -0,0 +1,25 @@
const {test, assert} = require('scar');
const libs = {
_: window._,
$: window.jQuery,
marked: window.marked,
prism: window.Prism
};
Object.keys(libs).forEach(id => {
test(`module '${id}' is defined`, () => {
assert.ok(window.modulejs._private.definitions[id]);
});
test(`module '${id}' has no instance`, () => {
assert.equal(window.modulejs._private.instances[id], undefined);
});
test(`module '${id}' returns global lib`, () => {
const definition = window.modulejs._private.definitions[id];
const instance = definition.fn();
assert.ok(instance);
assert.equal(instance, libs[id]);
});
});

View file

@ -0,0 +1,33 @@
const {test, assert} = require('scar');
test('modulejs is global object', () => {
assert.equal(typeof window.modulejs, 'object');
});
test('modulejs.define() is function', () => {
assert.equal(typeof window.modulejs.define, 'function');
});
test('modulejs.require() is function', () => {
assert.equal(typeof window.modulejs.require, 'function');
});
test('modulejs.state() is function', () => {
assert.equal(typeof window.modulejs.state, 'function');
});
test('modulejs.log() is function', () => {
assert.equal(typeof window.modulejs.log, 'function');
});
test('modulejs._private is object', () => {
assert.equal(typeof window.modulejs._private, 'object');
});
test('modulejs has definitions', () => {
assert.ok(Object.keys(window.modulejs._private.definitions).length >= 0);
});
test('modulejs has no instances', () => {
assert.equal(Object.keys(window.modulejs._private.instances).length, 0);
});

17
test-scar/util/modjs.js Normal file
View file

@ -0,0 +1,17 @@
const lodash = window._;
const modjs = window.modulejs;
function clearModulejs() {
lodash.each(modjs._private.instances, (val, key) => {
delete modjs._private.instances[key]; // eslint-disable-line prefer-reflect
});
}
function mockConfigModule() {
modjs.define('config', {_dummyConfig: true});
}
module.exports = {
clearModulejs,
mockConfigModule
};

33
test-scar/util/pin.js Normal file
View file

@ -0,0 +1,33 @@
const jq = window.jQuery;
let title;
let htmlId;
let htmlClasses;
let bodyId;
let bodyClasses;
let $pinnedElements;
function pinHtml() {
title = document.title;
htmlId = jq('html').attr('id');
htmlClasses = jq('html').attr('class');
bodyId = jq('body').attr('id');
bodyClasses = jq('body').attr('class');
$pinnedElements = jq('head,body').children();
}
function restoreHtml() {
document.title = title;
jq('html').attr('id', htmlId);
jq('html').attr('class', htmlClasses);
jq('body').attr('id', bodyId);
jq('body').attr('class', bodyClasses);
jq('head,body').children().not($pinnedElements).remove();
if (window.localStorage && window.localStorage.clear) {
window.localStorage.clear();
}
}
module.exports = {
pinHtml,
restoreHtml
};