Commit 538ce78e 538ce78e9497d4c2654fc45ac40340ec1156b913 by Vincent Peybernes

Specify and implement election structure.

1 parent 0a873941
......@@ -10,12 +10,14 @@
*
* @constructor
* @property {Candidate[]} candidateList
* @property {String[]} votes
* @property {Number} numberOfCandidates
*
*/
function RelativePlacement() {
Object.defineProperties(this, {
candidateList: {value: {}},
votes: {value: []},
numberOfCandidates: {get: () => Object.keys(this.candidateList).length}
});
}
......@@ -43,15 +45,50 @@
}
};
RelativePlacement.prototype.addVote = function () {};
/**
* @name addVote
* @param {String[]} vote
* @methodOf RelativePlacement
* @this RelativePlacement
*/
RelativePlacement.prototype.addVote = function (vote) {
if(vote.length != this.numberOfCandidates)
throw new Error('The vote and the candidate list have not the same size.');
var candidates = Object.keys(this.candidateList);
var controlMask = Math.pow(2,candidates.length)-1;
var checkMask = 0;
for(let i = 0; i < vote.length; i++){
var index = candidates.indexOf(vote[i]);
if(index == -1) throw new Error('The candidate "'+vote[i]+"' is not present in candidate list.");
checkMask |= Math.pow(2, index);
}
if(checkMask != controlMask) throw new Error('Candidate must be unique in each vote.');
this.votes.push(vote);
for(let i = 0; i < vote.length; i++){
let candidate = this.candidateList[vote[i]];
candidate.votes.push(i);
}
};
RelativePlacement.prototype.addVotes = function () {};
RelativePlacement.prototype.getResult = function () {};
/**
*
* @param name
* @constructor
* @property {String} name
* @property {Number[]} votes
* @property {Number[]} placements
*/
function Candidate(name) {
Object.defineProperties(this, {
name: {value: name, enumerable: true},
votes: {value:[], enumerable: true},
placement: {value:[], enumerable: false}
placements: {value:[], enumerable: true, writable: true}
});
}
......
......@@ -32,9 +32,9 @@ describe('RelativePlacement', () => {
assert.equal(1, election.numberOfCandidates);
assert.deepEqual({
name: 'foo',
votes:[]
votes:[],
placements: []
}, election.candidateList['foo']);
assert.deepEqual([], election.candidateList['foo'].placement);
});
it('should add some candidates', () => {
......@@ -44,16 +44,86 @@ describe('RelativePlacement', () => {
assert.deepEqual({
name: 'foo',
votes:[]
votes:[],
placements: []
}, election.candidateList['foo']);
assert.deepEqual({
name: 'bar',
votes:[]
votes:[],
placements: []
}, election.candidateList['bar']);
});
it('should not add a same candidate multiple time', () => {
assert.equal(0, election.numberOfCandidates);
election.addCandidate('foo');
assert.equal(1, election.numberOfCandidates);
assert.throws(()=>{
election.addCandidate('foo');
}, (err) => {
return err instanceof Error && /already exist/.test(err.message);
},
'unexpected error'
);
assert.equal(1, election.numberOfCandidates);
});
});
describe('Add votes', () => {
var election;
beforeEach(()=> {
election = new RelativePlacement();
election.addCandidates(['A','B','C']);
});
it('should add a vote to each candidates', () => {
var vote = ['A','B','C'];
election.addVote(['A','B','C']);
for(let i = 0; i < vote.length; i++){
let candidate = election.candidateList[vote[i]];
assert.equal(candidate.votes.length, 1, 'number of candidates vote');
assert.equal(candidate.votes[0], i, 'value of candidates vote');
}
});
it('should has same sizes between candidate list and vote', () => {
assert.throws(() => {
election.addVote(['A','B']);
},
err => err instanceof Error && /same size/.test(err.message),
'smaller vote'
);
assert.equal(election.votes.length, 0, 'no vote registered');
assert.equal(election.candidateList['A'].votes.length, 0, 'no vote registered in candidate');
assert.throws(() => {
election.addVote(['A','B','C','D']);
},
err => err instanceof Error && /same size/.test(err.message),
'bigger vote'
);
assert.equal(election.votes.length, 0, 'no vote registered');
assert.equal(election.candidateList['A'].votes.length, 0, 'no vote registered in candidate');
});
it('should not has unknown candidate in vote', () => {
assert.throws(() => {
election.addVote(['A','B','D']);
},
err => err instanceof Error && /not present/.test(err.message));
assert.equal(election.votes.length, 0, 'no vote registered');
assert.equal(election.candidateList['A'].votes.length, 0, 'no vote registered in candidate');
});
it('should has an unique vote by candidate', () => {
assert.throws(() => {
election.addVote(['A','B','A']);
},
err => err instanceof Error && /unique/.test(err.message));
assert.equal(election.votes.length, 0, 'no vote registered');
assert.equal(election.candidateList['A'].votes.length, 0, 'no vote registered in candidate');
});
});
});
\ No newline at end of file
......
[
{
"comment": "The most fundamentally",
"votes":{
"A": [1,1,1],
"B": [2,2,2],
"C": [3,3,3]
},
"result": ["A","B","C"]
},
{
"votes":{
"320": [1,1,1,1,1],
"284": [2,4,2,4,3],
......