mirror of
https://github.com/wassname/cardsforscience.git
synced 2026-06-27 17:15:11 +08:00
Updated tests to simulate rules
This commit is contained in:
@@ -81,6 +81,9 @@
|
||||
"karma-chrome-launcher": "^0.2.2",
|
||||
"karma-firefox-launcher": "^0.1.7",
|
||||
"karma-jasmine": "^0.3.7",
|
||||
"karma-jasmine-html-reporter": "^0.2.0",
|
||||
"karma-jasmine-html-reporter-livereload": "^1.0.0",
|
||||
"karma-jasmine-style-specrunner-reporter": "^1.0.3",
|
||||
"karma-junit-reporter": "^0.3.8",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^1.7.0",
|
||||
|
||||
+20
-2
@@ -91,13 +91,15 @@ var Game = module.exports =(function (Helpers, GameObjects, ObjectStorage,Rules,
|
||||
// deal new initial cards that follow the rule
|
||||
this.lastCards.splice(0,this.lastCards.length);
|
||||
this.lastCards.push(_.sample(this.cards));
|
||||
for (var i = 0; i < 52; i++) {
|
||||
var error,i;
|
||||
for (i = 0; i < 52; i++) {
|
||||
if (this.lastCards.length>2) break; // stop here
|
||||
var card = _.sample(this.cards);
|
||||
var res;
|
||||
try{
|
||||
res = this.rule.test(card,this.lastCards,this.cards);
|
||||
} catch(e){
|
||||
error=e;
|
||||
// in case of an error just add a random card
|
||||
// this is probobly because it is looking back 2 or 3 cards
|
||||
// yet we only have 1
|
||||
@@ -105,7 +107,23 @@ var Game = module.exports =(function (Helpers, GameObjects, ObjectStorage,Rules,
|
||||
}
|
||||
if (res) this.lastCards.push(_.sample(this.cards));
|
||||
}
|
||||
if (this.lastCards.length<3) console.error('Could not deal cards for rule',this.rule.key,this.rule.options);
|
||||
if (this.lastCards.length<3) {
|
||||
console.warn(
|
||||
'Could not deal cards for rule after:',
|
||||
i,
|
||||
this.rule.key,
|
||||
this.rule.options,
|
||||
this.rule.describe(),
|
||||
_.map(this.lastCards,'key'),
|
||||
error?error.message:''
|
||||
);
|
||||
// feck, just deal 3 random then
|
||||
this.lastCards.splice(0,this.lastCards.length);
|
||||
this.lastCards.push(_.sample(this.cards));
|
||||
this.lastCards.push(_.sample(this.cards));
|
||||
this.lastCards.push(_.sample(this.cards));
|
||||
|
||||
}
|
||||
// this.lastCards.push.apply(this.lastCards,_.sampleSize(this.cards,3));
|
||||
|
||||
this.ruleInfo.splice(0,this.ruleInfo.length);
|
||||
|
||||
+27
-7
@@ -15,6 +15,21 @@ if (!chai){
|
||||
*/
|
||||
var Rules = module.exports = (function functionName(_,chai) {
|
||||
|
||||
var Simulation = function(rules,cards){
|
||||
this.results=[];
|
||||
this.cards=cards;
|
||||
this.rules=rules;
|
||||
};
|
||||
Simulation.prototype.run = function () {
|
||||
var allPromises = [];
|
||||
for (var i = 0; i < this.rules.length; i++) {
|
||||
var rule = this.rules[i];
|
||||
var promises = rule.simulate();
|
||||
allPromises.push(promises);
|
||||
}
|
||||
return Promise.all(allPromises).then(function(data){return _.concat(data);});
|
||||
};
|
||||
|
||||
|
||||
/** Generate all combination of arguments from array using functional programming instead of recursive
|
||||
* @param {Object} opts - An array or arrays with keys describing options [['Ben','Jade','Darren'],['Smith','Miller']]
|
||||
@@ -306,21 +321,24 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
$.extend(this.state, state);
|
||||
};
|
||||
Rule.prototype.simulateOne = function (options,cards,n) {
|
||||
var self = this;
|
||||
// return new Promise(function(resolve, reject) {
|
||||
if (!n) n=52*2;
|
||||
var t0=new Date();
|
||||
var rights=[];
|
||||
var wrongs=[];
|
||||
var errors=[];
|
||||
var lastCards = _.sampleSize(cards,3);
|
||||
this.setOptions(options);
|
||||
self.setOptions(options);
|
||||
for (var i = 0; i < n; i++) {
|
||||
var res=undefined;
|
||||
var error=undefined;
|
||||
var card = _.sample(cards);
|
||||
|
||||
try{
|
||||
var res = this.testAndTell(card,lastCards,cards);
|
||||
var res = self.testAndTell(card,lastCards,cards);
|
||||
} catch(e){
|
||||
console.error('simulateOne',err);
|
||||
error=e;
|
||||
}
|
||||
|
||||
@@ -339,6 +357,7 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
}
|
||||
}
|
||||
var ratioRight = rights.length/(rights.length+wrongs.length);
|
||||
if (isNaN(ratioRight)) ratioRight = 0;
|
||||
var ok = ratioRight>0.1&&ratioRight<0.66;
|
||||
return {
|
||||
wrongs:wrongs,
|
||||
@@ -347,9 +366,9 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
rights:rights,
|
||||
error:errors.length,
|
||||
errors:errors,
|
||||
key:this.key,
|
||||
description:this.describe(),
|
||||
options:this.options,
|
||||
key:self.key,
|
||||
description:self.describe(),
|
||||
options:self.options,
|
||||
n:n,
|
||||
time:new Date()-t0,
|
||||
ok:ok,
|
||||
@@ -360,8 +379,8 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
Rule.prototype.simulate = function (cards) {
|
||||
var results = [];
|
||||
for (var i = 0; i < this.optionsPossible.length; i++) {
|
||||
var res = this.simulateOne(this.optionsPossible[i],cards);
|
||||
results.push(res);
|
||||
var result = this.simulateOne(this.optionsPossible[i],cards);
|
||||
results.push(result);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
@@ -656,6 +675,7 @@ var Rules = module.exports = (function functionName(_,chai) {
|
||||
return {
|
||||
Rule: Rule,
|
||||
rules: rules,
|
||||
Simulation: Simulation,
|
||||
};
|
||||
|
||||
|
||||
|
||||
+11
-87
@@ -2,100 +2,24 @@
|
||||
|
||||
/* http://docs.angularjs.org/guide/dev_guide.e2e-testing */
|
||||
|
||||
describe('PhoneCat App', function() {
|
||||
|
||||
it('should redirect index.html to index.html#/phones', function() {
|
||||
browser.get('app/index.html');
|
||||
browser.getLocationAbsUrl().then(function(url) {
|
||||
expect(url).toEqual('/phones');
|
||||
});
|
||||
});
|
||||
describe('cards for science', function() {
|
||||
|
||||
|
||||
describe('Phone list view', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
browser.get('app/index.html#/phones');
|
||||
browser.get('index.html');
|
||||
});
|
||||
|
||||
|
||||
it('should filter the phone list as a user types into the search box', function() {
|
||||
|
||||
var phoneList = element.all(by.repeater('phone in phones'));
|
||||
var query = element(by.model('query'));
|
||||
|
||||
expect(phoneList.count()).toBe(20);
|
||||
|
||||
query.sendKeys('nexus');
|
||||
expect(phoneList.count()).toBe(1);
|
||||
|
||||
query.clear();
|
||||
query.sendKeys('motorola');
|
||||
expect(phoneList.count()).toBe(8);
|
||||
});
|
||||
|
||||
|
||||
it('should be possible to control phone order via the drop down select box', function() {
|
||||
|
||||
var phoneNameColumn = element.all(by.repeater('phone in phones').column('phone.name'));
|
||||
var query = element(by.model('query'));
|
||||
|
||||
function getNames() {
|
||||
return phoneNameColumn.map(function(elm) {
|
||||
return elm.getText();
|
||||
});
|
||||
}
|
||||
|
||||
query.sendKeys('tablet'); //let's narrow the dataset to make the test assertions shorter
|
||||
|
||||
expect(getNames()).toEqual([
|
||||
"Motorola XOOM\u2122 with Wi-Fi",
|
||||
"MOTOROLA XOOM\u2122"
|
||||
]);
|
||||
|
||||
element(by.model('orderProp')).element(by.css('option[value="name"]')).click();
|
||||
|
||||
expect(getNames()).toEqual([
|
||||
"MOTOROLA XOOM\u2122",
|
||||
"Motorola XOOM\u2122 with Wi-Fi"
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
it('should render phone specific links', function() {
|
||||
var query = element(by.model('query'));
|
||||
query.sendKeys('nexus');
|
||||
element.all(by.css('.phones li a')).first().click();
|
||||
browser.getLocationAbsUrl().then(function(url) {
|
||||
expect(url).toEqual('/phones/nexus-s');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Phone detail view', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
browser.get('app/index.html#/phones/nexus-s');
|
||||
});
|
||||
|
||||
|
||||
it('should display nexus-s page', function() {
|
||||
expect(element(by.binding('phone.name')).getText()).toBe('Nexus S');
|
||||
});
|
||||
|
||||
|
||||
it('should display the first phone image as the main phone image', function() {
|
||||
expect(element(by.css('img.phone.active')).getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
|
||||
});
|
||||
|
||||
|
||||
it('should swap main image if a thumbnail image is clicked on', function() {
|
||||
element(by.css('.phone-thumbs li:nth-child(3) img')).click();
|
||||
expect(element(by.css('img.phone.active')).getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/);
|
||||
|
||||
element(by.css('.phone-thumbs li:nth-child(1) img')).click();
|
||||
expect(element(by.css('img.phone.active')).getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
|
||||
});
|
||||
// it('should filter the phone list as a user types into the search box', function() {
|
||||
//
|
||||
// var lastCards = element.all(by.css('#lastCards .card'));
|
||||
// expect(lastCards.count()).toBe(3);
|
||||
//
|
||||
// var query = element(by.repeater('r in rc.cards'));
|
||||
// query.click();
|
||||
// expect(lastCards.count()).toBe(4);
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
+10
-9
@@ -29,7 +29,15 @@ module.exports = function (config) {
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
reporters: ['progress','html','junit'],
|
||||
reporters: ['dots','html'],
|
||||
|
||||
htmlReporter: {
|
||||
outputFile: 'tests/units.html',
|
||||
|
||||
// Optional
|
||||
pageTitle: 'Unit Tests',
|
||||
subPageTitle: 'A sample project description'
|
||||
},
|
||||
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
@@ -50,12 +58,9 @@ module.exports = function (config) {
|
||||
require('karma-ng-html2js-preprocessor'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-firefox-launcher'),
|
||||
"karma-jasmine-html-reporter-livereload" // displays html summary on debug page
|
||||
],
|
||||
|
||||
junitReporter: {
|
||||
outputFile: 'test_out/unit.xml',
|
||||
suite: 'unit'
|
||||
},
|
||||
|
||||
preprocessors: {
|
||||
// './build/clientapp.bundle.js': ['webpack','sourcemap'],
|
||||
@@ -80,10 +85,6 @@ module.exports = function (config) {
|
||||
'/json/': '/base/json/'
|
||||
},
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
reporters: ['progress'],
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
|
||||
@@ -12,7 +12,7 @@ exports.config = {
|
||||
|
||||
chromeOnly: true,
|
||||
|
||||
baseUrl: 'http://localhost:8000/',
|
||||
baseUrl: 'http://localhost:8080/',
|
||||
|
||||
framework: 'jasmine',
|
||||
|
||||
|
||||
+57
-45
@@ -17,27 +17,27 @@ describe('Rules', function () {
|
||||
|
||||
describe('Rule', function () {
|
||||
it('should test false on false', function () {
|
||||
var rule = new Rule('1',function(){return false;},{},{},[]);
|
||||
var rule = new Rule('1','1',function(){return false;},{},{},[]);
|
||||
var res = rule.test(card,lastCards,allCards);
|
||||
expect(res).toBe(false);
|
||||
});
|
||||
it('should test false on assertion error', function () {
|
||||
var rule = new Rule('2',function(){return chai.expect(1).to.equal(0);},{},{},[]);
|
||||
var rule = new Rule('2','2',function(){return chai.expect(1).to.equal(0);},{},{},[]);
|
||||
var res = rule.test(card,lastCards,allCards);
|
||||
expect(res).toBe(false);
|
||||
});
|
||||
it('should test true on assertion', function () {
|
||||
var rule = new Rule('3',function(){return chai.expect(1).to.equal(1);},{},{},[]);
|
||||
var rule = new Rule('3','3',function(){return chai.expect(1).to.equal(1);},{},{},[]);
|
||||
var res = rule.test(card,lastCards,allCards);
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
it('should test true on true', function () {
|
||||
var rule = new Rule('4',function(){return true;},{},{},[]);
|
||||
var rule = new Rule('4','4',function(){return true;},{},{},[]);
|
||||
var res = rule.test(card,lastCards,allCards);
|
||||
expect(res).toBe(true);
|
||||
});
|
||||
it('should throw test on error', function () {
|
||||
var rule = new Rule('5',function(){throw new Error('test');return true;},{},{},[]);
|
||||
var rule = new Rule('5','5',function(){throw new Error('test');return true;},{},{},[]);
|
||||
expect(function(){
|
||||
rule.test(card,lastCards,allCards);
|
||||
}).toThrow();
|
||||
@@ -45,31 +45,18 @@ describe('Rules', function () {
|
||||
});
|
||||
describe('Each rule', function () {
|
||||
Rules.rules.forEach(function(rule){
|
||||
describe('rule: "'+rule.describe()+'"', function () {
|
||||
it('should test', function () {
|
||||
var res = rule.test(card,lastCards,allCards);
|
||||
Boolean(res);
|
||||
});
|
||||
it('should describe itself', function () {
|
||||
var desc = rule.describe();
|
||||
expect(typeof desc).toBe('string');
|
||||
expect(desc).not.toContain(/[{}]+/);
|
||||
});
|
||||
it('should describeOptions', function () {
|
||||
var desc = rule.describeOptions();
|
||||
expect(typeof desc).toBe('string');
|
||||
expect(desc).not.toContain(/[{}]+/);
|
||||
});
|
||||
describe('rule: "'+rule.key+'"', function () {
|
||||
|
||||
it('should describeVariations', function () {
|
||||
var desc = rule.describeVariations();
|
||||
expect(desc instanceof Array).toBe(true);
|
||||
expect(desc).not.toContain(/[{}]+/);
|
||||
});
|
||||
it('should genHints', function () {
|
||||
var hints = rule.genHints();
|
||||
expect(hints instanceof Array).toBe(true);
|
||||
expect(hints.length).toBeGreaterThan(0);
|
||||
expect(hints.join('')).not.toContain(/[{}]+/);
|
||||
|
||||
it('should describeOptions', function () {
|
||||
var desc = rule.describeOptions();
|
||||
expect(typeof desc).toBe('string');
|
||||
expect(desc).not.toContain(/[{}]+/);
|
||||
});
|
||||
it('should set options', function () {
|
||||
var opts1 = rule.options;
|
||||
@@ -84,31 +71,56 @@ describe('Rules', function () {
|
||||
expect(opts).not.toEqual(opts1);
|
||||
});
|
||||
|
||||
|
||||
// now check each rule permutation
|
||||
var options=Object.keys(rule.optionDesc);
|
||||
options.forEach(function(option){
|
||||
var vals = rule.optionDesc[option].possibleVals;
|
||||
var def = rule.optionDefaults[option];
|
||||
describe('option: '+option, function () {
|
||||
for (var i = 0; i < vals.length; i++) {
|
||||
it('should test with val: '+vals[i],function(){
|
||||
var options={};
|
||||
options[option]=vals[i];
|
||||
rule.setOptions(options);
|
||||
var res = rule.test(card,lastCards,allCards);
|
||||
expect(typeof res).toBe('boolean');
|
||||
});
|
||||
}
|
||||
|
||||
it('default should be in possible vals '+option+' = '+vals[i],function(){
|
||||
for (var option in rule.optionDefaults) {
|
||||
if (rule.optionDefaults.hasOwnProperty(option)) {
|
||||
var def = rule.optionDefaults[option];
|
||||
var vals = rule.optionDesc[option].possibleVals;
|
||||
it('defaults should be in possible vals '+option,function(){
|
||||
expect(vals).toEqual(jasmine.arrayContaining([def]));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// now check each rule permutation
|
||||
rule.optionsPossible.forEach(function(options){
|
||||
|
||||
describe('rule: "'+rule.describe()+'"', function () {
|
||||
beforeEach(function () {
|
||||
rule.setOptions(options);
|
||||
});
|
||||
it('should describe itself', function () {
|
||||
var desc = rule.describe();
|
||||
expect(typeof desc).toBe('string');
|
||||
expect(desc).not.toContain(/[{}]+/);
|
||||
});
|
||||
it('should test', function () {
|
||||
var res = rule.test(card,lastCards,allCards);
|
||||
Boolean(res);
|
||||
});
|
||||
it('should genHints', function () {
|
||||
var hints = rule.genHints();
|
||||
expect(hints instanceof Array).toBe(true);
|
||||
expect(hints.length).toBeGreaterThan(0);
|
||||
expect(hints.join('')).not.toContain(/[{}]+/);
|
||||
});
|
||||
describe('simulation',function(){
|
||||
|
||||
it('should have more than 10% right and less than 60%',function(){
|
||||
var simulation=rule.simulateOne(options,allCards,52*2);
|
||||
expect(simulation).not.toEqual(undefined);
|
||||
expect(simulation.ratioRight).toBeLessThan(0.6);
|
||||
expect(simulation.ratioRight).toBeGreaterThan(0.1);
|
||||
expect(simulation.error).toBe(0);
|
||||
// if (simulation.wrong){
|
||||
// expect(_.uniq(simulation.wrongs)[0].length).toBeGreaterThan(0);
|
||||
// }
|
||||
});
|
||||
});
|
||||
// it should give reasons
|
||||
// it should not give errors
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user