mirror of
https://github.com/Oreolek/raconteur.git
synced 2024-06-26 03:30:47 +03:00
Add Karma testing + partial specs
This commit is contained in:
parent
9a071c2999
commit
3c1102d9de
74
karma.conf.js
Normal file
74
karma.conf.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Karma configuration
|
||||
// Generated on Sun Apr 12 2015 20:11:32 GMT-0300 (BRT)
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
|
||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||
basePath: '',
|
||||
|
||||
|
||||
// frameworks to use
|
||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
||||
frameworks: ['browserify', 'jasmine'],
|
||||
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'lib/*.js',
|
||||
'spec/*.js'
|
||||
],
|
||||
|
||||
|
||||
// list of files to exclude
|
||||
exclude: [
|
||||
],
|
||||
|
||||
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
preprocessors: {
|
||||
"lib/*.js": ['browserify'],
|
||||
"spec/*.js": ['browserify']
|
||||
},
|
||||
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
reporters: ['progress'],
|
||||
|
||||
|
||||
// web server port
|
||||
port: 9876,
|
||||
|
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
|
||||
|
||||
// level of logging
|
||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
|
||||
// start these browsers
|
||||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
|
||||
browsers: ['Chrome'],
|
||||
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, Karma captures browsers, runs the tests and exits
|
||||
|
||||
browserify: {
|
||||
debug: true,
|
||||
transform: ['babelify']
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
};
|
|
@ -105,9 +105,15 @@ elementHelper.prototype.toString = function () {
|
|||
if (this._classes) {
|
||||
classes += this._classes.join(' ');
|
||||
}
|
||||
|
||||
if (this._linkType) {
|
||||
classes += (' ' + this._linkType);
|
||||
if (classes) {
|
||||
classes += (' ' + this._linkType);
|
||||
} else {
|
||||
classes = this._linkType;
|
||||
}
|
||||
}
|
||||
|
||||
if (classes) {
|
||||
classString = ` class="${classes}"`;
|
||||
}
|
||||
|
@ -129,18 +135,18 @@ elementHelper.prototype.toString = function () {
|
|||
}
|
||||
|
||||
if (this._src) {
|
||||
srcString = `src="${this._src}"`;
|
||||
srcString = ` src="${this._src}"`;
|
||||
}
|
||||
|
||||
if (this._alt) {
|
||||
altString = `alt="${this._alt}"`;
|
||||
altString = ` alt="${this._alt}"`;
|
||||
}
|
||||
|
||||
if (this._content) {
|
||||
contentString = markdown.renderInline(this._content);
|
||||
}
|
||||
|
||||
return `<${this.element}${classString}${idString}${hrefString}${srcString}>${contentString}</${this.element}>`;
|
||||
return `<${this.element}${classString}${idString}${hrefString}${srcString}${altString}>${contentString}</${this.element}>`;
|
||||
};
|
||||
|
||||
var a_proto = Object.freeze(new elementHelper("a"));
|
||||
|
|
22
lib/oneOf.js
22
lib/oneOf.js
|
@ -114,7 +114,7 @@ var oneOf = function (...ary) {
|
|||
},
|
||||
|
||||
randomly (system) {
|
||||
var rng = (system) ? system.random : Math.random,
|
||||
var rng = (system) ? system.rnd.random : Math.random,
|
||||
last;
|
||||
|
||||
if (ary.length<2) {
|
||||
|
@ -122,19 +122,29 @@ var oneOf = function (...ary) {
|
|||
"attempted to make randomly() iterator with a 1-length array");
|
||||
}
|
||||
return stringish(function () {
|
||||
var i;
|
||||
var i, offset;
|
||||
if (last === undefined) {
|
||||
i = Math.floor(rng() * ary.length)
|
||||
} else {
|
||||
/*
|
||||
Let offset be a random number between 1 and the length of the
|
||||
array, minus one. We jump offset items ahead on the array,
|
||||
wrapping around to the beginning. This gives us a random item
|
||||
other than the one we just chose.
|
||||
*/
|
||||
|
||||
do {
|
||||
i = Math.floor(rng() * ary.length);
|
||||
} while (i === last);
|
||||
offset = Math.floor(rng() * (ary.length -1) + 1);
|
||||
i = (last + offset) % ary.length;
|
||||
}
|
||||
|
||||
last = i;
|
||||
return ary[i];
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
trulyAtRandom (system) {
|
||||
var rng = (system) ? system.random : Math.random;
|
||||
var rng = (system) ? system.rnd.random : Math.random;
|
||||
return stringish(function () {
|
||||
return ary[Math.floor(rng() * ary.length)];
|
||||
});
|
||||
|
|
|
@ -238,5 +238,5 @@ RaconteurSituation.prototype.act = function (character, system, action) {
|
|||
|
||||
module.exports = function (name, spec) {
|
||||
spec.name = name;
|
||||
undum.game.situations[name] = new RaconteurSituation(spec);
|
||||
return (undum.game.situations[name] = new RaconteurSituation(spec));
|
||||
};
|
|
@ -22,6 +22,12 @@
|
|||
"gulp-less": "~3.0.2",
|
||||
"gulp-sourcemaps": "^1.5.1",
|
||||
"gulp-util": "^3.0.4",
|
||||
"jasmine-core": "^2.2.0",
|
||||
"karma": "^0.12.31",
|
||||
"karma-babel-preprocessor": "^5.0.1",
|
||||
"karma-browserify": "^4.1.2",
|
||||
"karma-chrome-launcher": "^0.1.7",
|
||||
"karma-jasmine": "^0.3.5",
|
||||
"lodash": "^3.6.0",
|
||||
"vinyl-buffer": "^1.0.0",
|
||||
"vinyl-source-stream": "~1.1.0",
|
||||
|
|
68
spec/elementsSpec.js
Normal file
68
spec/elementsSpec.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
var elements = require('raconteur/elements.js');
|
||||
|
||||
var a = elements.a, span = elements.span;
|
||||
|
||||
describe('elementHelper', function() {
|
||||
|
||||
it('stringifies as a tag', function() {
|
||||
var elem = elements.element('span');
|
||||
expect('' + elem).toBe('<span></span>')
|
||||
});
|
||||
|
||||
it('supplies monadic methods', function () {
|
||||
var elem = elements.element('span');
|
||||
var elem_ = elem.class('foo').id('my_span');
|
||||
expect('' + elem_).toBe('<span class="foo" id="my_span"></span>');
|
||||
});
|
||||
|
||||
it('allows redefining previously set attributes', function () {
|
||||
var elem = elements.element('span').content('foo');
|
||||
expect('' + elem).toBe('<span>foo</span>');
|
||||
expect('' + elem.content('bar')).toBe('<span>bar</span>');
|
||||
expect('' + elem).toBe('<span>foo</span>');
|
||||
});
|
||||
|
||||
it('adds classes with class()', function () {
|
||||
expect('' + span().class('foo').class('bar'))
|
||||
.toBe('<span class="foo bar"></span>');
|
||||
});
|
||||
|
||||
it('redefines classes with class()', function () {
|
||||
expect('' + span().class('foo').classes(['bar', 'baz']))
|
||||
.toBe('<span class="bar baz"></span>');
|
||||
});
|
||||
|
||||
it('allows setting most tag attributes', function () {
|
||||
expect('' +
|
||||
a('content').class('class').id('id').url('ref').src('src').alt('alt'))
|
||||
.toBe('<a class="class" id="id" href="ref" src="src" alt="alt">content</a>')
|
||||
});
|
||||
|
||||
it('is immutable', function() {
|
||||
|
||||
var span = elements.element('span');
|
||||
var shouldBreak = function () {
|
||||
span._content = "foo";
|
||||
};
|
||||
|
||||
expect(shouldBreak).toThrowError();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('a', function() {
|
||||
|
||||
it('creates an <a> element', function() {
|
||||
expect('' + a('foo').url('http://example.com'))
|
||||
.toBe('<a href="http://example.com">foo</a>');
|
||||
});
|
||||
|
||||
it('supplies shorthand for common action links', function (){
|
||||
expect('' + a('foo').action('bar'))
|
||||
.toBe('<a class="action" href="./bar">foo</a>');
|
||||
|
||||
expect('' + a('foo').writer('bar'))
|
||||
.toBe('<a class="writer" href="./_writer_bar">foo</a>');
|
||||
});
|
||||
|
||||
});
|
93
spec/oneOfSpec.js
Normal file
93
spec/oneOfSpec.js
Normal file
|
@ -0,0 +1,93 @@
|
|||
var oneOf = require('raconteur/oneOf.js');
|
||||
|
||||
describe('oneOf', function() {
|
||||
var oneOfObj;
|
||||
|
||||
beforeEach(function () {
|
||||
oneOfObj = oneOf('foo', 'bar', 'baz');
|
||||
});
|
||||
|
||||
it('creates an object that supplies certain methods', function () {
|
||||
expect(typeof oneOfObj).toBe('object');
|
||||
expect(oneOfObj.cycling).toBeDefined;
|
||||
expect(oneOfObj.stopping).toBeDefined;
|
||||
expect(oneOfObj.randomly).toBeDefined;
|
||||
expect(oneOfObj.trulyAtRandom).toBeDefined;
|
||||
expect(oneOfObj.inRandomOrder).toBeDefined;
|
||||
});
|
||||
|
||||
it('produces functions with those methods', function () {
|
||||
expect(typeof oneOfObj.cycling()).toBe('function');
|
||||
expect(typeof oneOfObj.stopping()).toBe('function');
|
||||
expect(typeof oneOfObj.randomly()).toBe('function');
|
||||
expect(typeof oneOfObj.trulyAtRandom()).toBe('function');
|
||||
expect(typeof oneOfObj.inRandomOrder()).toBe('function');
|
||||
});
|
||||
|
||||
it('allows stringifying those functions directly', function () {
|
||||
expect('' + oneOfObj.cycling()).toBe('foo');
|
||||
});
|
||||
|
||||
it('creates a closure that cycles', function () {
|
||||
var cycler = oneOfObj.cycling();
|
||||
expect(cycler(), cycler(), cycler(), cycler())
|
||||
.toBe('foo', 'bar', 'baz', 'foo', 'bar', 'baz');
|
||||
});
|
||||
|
||||
it('is agnostic about values', function () {
|
||||
var cycler = oneOf('foo', 1, null, {}).cycling();
|
||||
expect(cycler(), cycler(), cycler(), cycler())
|
||||
.toBe('foo', 1, null, {});
|
||||
});
|
||||
|
||||
it('creates a closure that stops', function () {
|
||||
var stopper = oneOfObj.stopping();
|
||||
expect(stopper(), stopper(), stopper(), stopper())
|
||||
.toBe('foo', 'bar', 'baz', 'baz');
|
||||
});
|
||||
|
||||
describe('using random numbers', function () {
|
||||
/* This expects a System object supplying system.rnd.random(); */
|
||||
var randomStub;
|
||||
|
||||
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
randomStub = {
|
||||
rnd: {
|
||||
random: (function () {
|
||||
var i = 0,
|
||||
outputs = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9];
|
||||
return function () {
|
||||
if (i >= outputs.length) i = 0;
|
||||
return outputs[i];
|
||||
}
|
||||
})()
|
||||
}
|
||||
};
|
||||
|
||||
oneOfObj = oneOf('foo', 'bar', 'baz');
|
||||
spyOn(randomStub.rnd, 'random').and.callThrough();
|
||||
});
|
||||
|
||||
it('creates a closure that returns a random item', function () {
|
||||
var snippet = oneOfObj.trulyAtRandom(randomStub);
|
||||
expect(snippet(), snippet(), snippet()).toBe('foo', 'foo', 'foo');
|
||||
expect(randomStub.rnd.random).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('will not return the same item twice with randomly()', function () {
|
||||
var snippet = oneOfObj.randomly(randomStub);
|
||||
expect(snippet() !== snippet()).toBe(true);
|
||||
});
|
||||
|
||||
it('can cycle through a random list', function () {
|
||||
var snippet = oneOfObj.inRandomOrder(randomStub);
|
||||
var snippets = [snippet(), snippet(), snippet(), snippet()];
|
||||
expect(snippets[0]).toBe(snippets[3]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
50
spec/situationSpec.js
Normal file
50
spec/situationSpec.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
var situation = require('raconteur/situation.js');
|
||||
|
||||
describe ('situation', function () {
|
||||
var test_situation = situation('test-situation', {
|
||||
content: "This is the content of the *testing* situation.",
|
||||
choices: ['#foo']
|
||||
});
|
||||
|
||||
var system_spy;
|
||||
|
||||
beforeEach(function () {
|
||||
system_spy = {
|
||||
write: function () {return;},
|
||||
getSituationIdChoices: function () {return;},
|
||||
writeChoices: function () {return;}
|
||||
};
|
||||
|
||||
spyOn(system_spy, 'write');
|
||||
spyOn(system_spy, 'getSituationIdChoices').and.returnValue(['foo', 'foo-bar']);
|
||||
spyOn(system_spy, 'writeChoices');
|
||||
});
|
||||
|
||||
it('has a name', function () {
|
||||
expect(test_situation.name).toBe('test-situation');
|
||||
});
|
||||
|
||||
it('parses its content as markdown', function () {
|
||||
test_situation.enter({}, system_spy, '');
|
||||
|
||||
expect(system_spy.write)
|
||||
.toHaveBeenCalledWith("<p>This is the content of the <em>testing</em> situation.</p>\n");
|
||||
});
|
||||
|
||||
it('is agnostic about whether content is a string or a function', function () {
|
||||
test_situation.content = function () {return "Foo and bar."};
|
||||
test_situation.enter({}, system_spy, '');
|
||||
|
||||
expect(system_spy.write)
|
||||
.toHaveBeenCalledWith("<p>Foo and bar.</p>\n");
|
||||
});
|
||||
|
||||
it('generates a list of choices', function () {
|
||||
test_situation.enter({}, system_spy, '');
|
||||
|
||||
expect(system_spy.getSituationIdChoices)
|
||||
.toHaveBeenCalledWith(['#foo'], undefined, undefined);
|
||||
expect(system_spy.writeChoices).toHaveBeenCalledWith(['foo', 'foo-bar']);
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in a new issue