GlobalSpec.js 6.17 KB
/**
 * Created by Techniv on 30/11/2016.
 */
var assert = require('assert');
var RelativePlacement = require('../../relative-placement');

describe('RelativePlacement global', () => {
    it('should provide RelativePlacement constructor', () => {
        assert.ok(RelativePlacement instanceof Function, 'provide constructor');
        assert.ok(RelativePlacement.prototype.addCandidate instanceof Function, 'provide "addCandidate" function in prototype');
        assert.ok(RelativePlacement.prototype.addCandidates instanceof Function, 'provide "addCandidates" function in prototype');
        assert.ok(RelativePlacement.prototype.addVote instanceof Function, 'provide "addVote" function in prototype');
        assert.ok(RelativePlacement.prototype.addVotes instanceof Function, 'provide "addVotes" function in prototype');
        assert.ok(RelativePlacement.prototype.getResult instanceof Function, 'provide "getResult" function in prototype');
    });

    it('should correctly instantiate RelativePlacement election', () => {
        var rp = new RelativePlacement();

        assert.deepEqual({}, rp.candidateList);
    });

    describe('Add candidates', () => {
        /** @var RelativePlacement */
        var election;

        beforeEach(()=> election = new RelativePlacement());

        it('should add a candidate', () => {
            assert.equal(0, election.numberOfCandidates);
            election.addCandidate('foo');
            assert.equal(1, election.numberOfCandidates);
            assert.deepEqual({
                name: 'foo',
                votes:[],
                placements: [],
                cumulativePlacement: []
            }, election.candidateList['foo']);
        });

        it('should add some candidates', () => {
            assert.equal(0, election.numberOfCandidates);
            election.addCandidates(['foo', 'bar']);
            assert.equal(2, election.numberOfCandidates);

            assert.deepEqual({
                name: 'foo',
                votes:[],
                placements: [],
                cumulativePlacement: []
            }, election.candidateList['foo']);
            assert.deepEqual({
                name: 'bar',
                votes:[],
                placements: [],
                cumulativePlacement: []
            }, 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;
        var candidates = ['A','B','C'];

        beforeEach(()=> {
            election = new RelativePlacement();
            election.addCandidates(candidates);
        });

        it('should add a vote to each candidates', () => {
            var vote = candidates;
            election.addVote(vote);
            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');
        });

        it('should lock candidate after add the first vote', () => {
            election.addVote(candidates);
            assert.throws(()=>election.addCandidate('D'));
        });
    });

    describe('Get result', () => {
        /** @var RelativePlacement */
        var election;
        var candidates = ['A','B','C'];

        beforeEach(()=> {
            election = new RelativePlacement();
            election.addCandidates(candidates);
            election.addVote(candidates);
        });

        it('should return an array', () => {
            assert.ok(election.getResult() instanceof Array);
        });

        it('should return only all candidates', () => {
            var result = election.getResult();

            assert.equal(result.length, candidates.length);
            assert.ok(candidates.every(name => result.indexOf(name) != -1));
            assert.ok(result.every(name => candidates.indexOf(name) != -1));
        });
    });
});