Skip to content
This repository has been archived by the owner on Aug 3, 2022. It is now read-only.

Commit

Permalink
Merge branch 'scoring-fix'
Browse files Browse the repository at this point in the history
  • Loading branch information
brew committed Oct 27, 2016
2 parents fa8421d + 1618e36 commit 710bb2d
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 21 deletions.
15 changes: 13 additions & 2 deletions census/models/entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,30 @@ module.exports = function(sequelize, DataTypes) {
}
],
instanceMethods: {
_getAnswerValueForQuestion: function(q) {
// Find the `value` property for the answer with `id`.
let answer = _.result(_.find(this.answers, {id: q.id}), 'value');
// Multiple-choice answers need special treatment to get the checked
// answers.
if (q.type === 'multiple') {
answer = _.filter(answer, option => option.checked);
answer = _.map(answer, option => option.description);
}
return answer;
},
isOpenForQuestions: function(questions) {
// Only interested in 'open' questions.
let openQuestions = _.filter(questions, q => q.openquestion);
// We must have some Open Questions to be an Open entry.
if (openQuestions.length === 0)
return false;
// All Open Questions must pass for the answers in this entry.
return _.all(openQuestions, q => q.pass(_.get(this.answers[q.id], 'value')));
return _.all(openQuestions, q => q.pass(this._getAnswerValueForQuestion(q)));
},
scoreForQuestions: function(questions) {
var scores = [];
_.each(questions, q => {
let answer = _.get(this.answers[q.id], 'value');
let answer = this._getAnswerValueForQuestion(q);
scores.push(q.scoreForAnswer(answer));
});
return _.sum(scores);
Expand Down
31 changes: 22 additions & 9 deletions census/models/question.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,30 @@ module.exports = function(sequelize, DataTypes) {
return returnScore;
},
pass: function(answer) {
/* Determine whether the provided answer passes the question. */
/*
Determine whether the provided answer passes the question. Ways of
passing are defined in the score config object and include:
// If config doesn't provide a way of passing, answer can't pass.
if (!_.has(this.config, 'score.passValue'))
return false;

let expected = _.get(this.config, 'score.passValue');
if (!_.isArray(expected)) {
expected = [expected];
`passValue`: a single value or array or values that the answer be
equal to.
`passAnyOption`: if true, the answer must include at least one
option found in the question.config.options array.
*/
if (_.has(this.config, 'score.passValue')) {
let expected = _.get(this.config, 'score.passValue');
if (!_.isArray(expected)) expected = [expected];
return _.includes(expected, answer);
} else if (_.has(this.config, 'score.passAnyOption') &&
_.has(this.config, 'options')) {
let expected = this.config.options;
if (!_.isArray(expected)) expected = [expected];
if (!_.isArray(answer)) answer = [answer];
return _.any(answer, o => {
return _.includes(expected, o);
});
}
return _.includes(expected, answer);
// The config doesn't provide a way of passing, answer can't pass.
return false;
},
isScored: function() {
/* Return a boolean to determine whether the question contributes to scoring.*/
Expand Down
15 changes: 13 additions & 2 deletions fixtures/entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ var datasets = require('./dataset');
var places = require('./place');
var users = require('./user');

const formatAnswers = [
{checked: true, description: 'AsciiDoc'},
{checked: true, description: 'CSV'},
{checked: false, description: 'DBF'},
{checked: false, description: 'GML'},
{checked: false, description: 'GPX'},
{checked: false, description: 'GRIB2'},
{checked: false, description: 'GeoJSON'},
{checked: true, description: 'HTML'}
];

function answers() {
return {
digital: {id: 'digital', value: true, commentValue: ''},
Expand All @@ -15,7 +26,7 @@ function answers() {
online: {id: 'online', value: false, commentValue: ''},
public: {id: 'public', value: false, commentValue: ''},
publisher: {id: 'publisher', value: 'Acme', commentValue: ''},
format: {id: 'format', value: ['CSV', 'PSF'], commentValue: ''},
format: {id: 'format', value: formatAnswers, commentValue: ''},
license: {id: 'license', value: 'http://example.com', commentValue: ''}
};
}
Expand All @@ -29,7 +40,7 @@ function currentAnswers() {
online: {id: 'online', value: true, commentValue: ''},
public: {id: 'public', value: true, commentValue: ''},
publisher: {id: 'publisher', value: 'Acme', commentValue: ''},
format: {id: 'format', value: ['CSV', 'PSF'], commentValue: ''},
format: {id: 'format', value: formatAnswers, commentValue: ''},
license: {id: 'license', value: 'http://example.com', commentValue: ''}
};
}
Expand Down
16 changes: 13 additions & 3 deletions fixtures/question.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,20 @@ var objects = [
'question': 'Format of data',
'description': 'the description',
'placeholder': 'the placeholder',
'type': 'text',
'score': 0,
'type': 'multiple',
'score': 10,
'icon': '',
'openquestion': false
'openquestion': true,
'config': {
'score': {
'weight': 10,
'passAnyOption': true
},
'options': ['XLS', 'PX', 'CSV', 'HTML', 'JSON', 'TSV', 'XML', 'RDF', 'TXT', 'AsciiDoc', 'SHP', 'SHX', 'DBF', 'WFS', 'GeoJSON', 'GPX', 'KML', 'KMZ', 'GML', 'GRIB2'],
'includeOther': false,
'orderOptions': true,
'short': true
},
}
},
{
Expand Down
26 changes: 21 additions & 5 deletions tests/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ describe('Question instance methods', function() {
});
});

it('.pass returns correctly for multiple choice value', function() {
return modelUtils.getData(this.dataOptions)
.then(data => {
expect(data).to.have.property('questions');
let formatQuestion = _.find(data.questions, {id: 'format'});
expect(formatQuestion.pass(['XML', 'CSV', 'HTML'])).to.be.true;
expect(formatQuestion.pass(['NOTOPEN', 'ANDANOTHER'])).to.be.false;
expect(formatQuestion.pass(['NOTOPEN', 'CSV'])).to.be.true;
expect(formatQuestion.pass(true)).to.be.false;
expect(formatQuestion.pass('No')).to.be.false;
expect(formatQuestion.pass(false)).to.be.false;
expect(formatQuestion.pass([])).to.be.false;
expect(formatQuestion.pass()).to.be.false;
});
});

it('.scoreForAnswer returns correctly for simple expected value', function() {
return modelUtils.getData(this.dataOptions)
.then(data => {
Expand Down Expand Up @@ -203,7 +219,7 @@ describe('Dataset instance methods', function() {
return data.dataset.score(data.entries, data.questions);
})
.then(score => {
assert.equal(score, 25);
assert.equal(score, 45);
});
});

Expand All @@ -215,7 +231,7 @@ describe('Dataset instance methods', function() {
return data.dataset.score(data.entries, data.questions);
})
.then(score => {
assert.equal(score, 15);
assert.equal(score, 25);
});
});
});
Expand Down Expand Up @@ -248,7 +264,7 @@ describe('Place instance methods', function() {
return data.place.score(data.entries, data.questions);
})
.then(score => {
assert.equal(score, 25);
assert.equal(score, 45);
});
});

Expand All @@ -260,7 +276,7 @@ describe('Place instance methods', function() {
return data.place.score(data.entries, data.questions);
})
.then(score => {
assert.equal(score, 25);
assert.equal(score, 45);
});
});
});
Expand Down Expand Up @@ -377,7 +393,7 @@ describe('Data access layer', function() {
with: {Entry: true, Dataset: true, Place: true, Question: true}
};
return modelUtils.getData(dataOptions).then(function(data) {
expect(data.questions).to.have.length(9);
expect(data.questions).to.have.length(10);
});
});

Expand Down

0 comments on commit 710bb2d

Please sign in to comment.