From eb66b6904dfd7085241c1e9ba5916f1792c0a17c Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sun, 22 Mar 2020 12:40:58 +0300 Subject: [PATCH] Restore tests --- src/Daemon.ts | 75 ++++++------------------------------ src/Move.ts | 1 - src/Predictor.ts | 24 ++++-------- src/Supervisor.ts | 9 ----- tests/DaemonTest.ts | 90 ++++++++++++++++++++++---------------------- tests/JourlanTest.ts | 49 +++++++++++++----------- tools/node | 11 ++++-- tools/npm | 11 ++++-- tools/tsc | 4 +- 9 files changed, 110 insertions(+), 164 deletions(-) diff --git a/src/Daemon.ts b/src/Daemon.ts index aad50ae..1a30521 100644 --- a/src/Daemon.ts +++ b/src/Daemon.ts @@ -7,30 +7,15 @@ function create_key(steps: number[]): string { } class Daemon { - /** - * @type {Number} - */ - base; + base: number; - /** - * @type {Number} - */ - humanCount; + humanCount: number; - /** - * @type {Number} - */ - robotCount; + robotCount: number; - /** - * @type {Number} - */ - epsilon; + epsilon: number; - /** - * @type {Object} - */ - weights = {}; + weights: { [key: string]: number } = {}; constructor( base: number, @@ -62,69 +47,31 @@ class Daemon { return proposals.indexOf(maxWeight); } - /** - * @param {Journal} journal - * @param {Number} humanValue - */ - adjust(journal, humanValue) { + adjust(journal: Journal, humanValue: number) { const steps = this._getStepSlice(journal); const adjustmentWeight = this._getAdjustmentWeight(journal.length); this._adjustWeight([...steps, humanValue], adjustmentWeight); } - /** - * @param {Journal} journal - * - * @returns {Number[]} - */ - private _getStepSlice(journal) { + private _getStepSlice(journal: Journal): number[] { return journal.getLastMovements(this.humanCount, this.robotCount); } - /** - * @param {Number} stepNumber - * - * @returns {Number} - * - * @private - */ - private _getAdjustmentWeight(stepNumber) { + private _getAdjustmentWeight(stepNumber: number): number { return Math.pow(1 + this.epsilon, stepNumber); } - /** - * @param {Number[]} steps - * - * @returns {Number} - * - * @private - */ private _getWeight(steps: number[]): number { const key = create_key(steps); - const weight = this.weights[key]; - return weight as number; + return key in this.weights ? this.weights[key] : 0; } - /** - * @param {Number[]} steps - * @param {Number} value - * - * @returns {Number} - * - * @private - */ - private _setWeight(steps, value) { + private _setWeight(steps: number[], value: number): void { const key = create_key(steps); this.weights[key] = value; } - /** - * @param {Number[]} steps - * @param {Number} weight - * - * @private - */ - private _adjustWeight(steps, weight) { + private _adjustWeight(steps: number[], weight: number): void { const currentWeight = this._getWeight(steps); const newWeight = currentWeight + weight; this._setWeight(steps, newWeight); diff --git a/src/Move.ts b/src/Move.ts index f409c29..28bf5c3 100644 --- a/src/Move.ts +++ b/src/Move.ts @@ -3,7 +3,6 @@ */ class Move { public human: number; - public robot: number; constructor(human: number, robot: number) { diff --git a/src/Predictor.ts b/src/Predictor.ts index fe3b397..b8bbcca 100644 --- a/src/Predictor.ts +++ b/src/Predictor.ts @@ -18,22 +18,22 @@ export default class Predictor { /** * @type {Number} */ - base; + base: number; /** * @type {Number} */ - score; + score: number; /** * @type {Journal} */ - journal; + journal: Journal; /** * @type {Supervisor} */ - supervisor; + supervisor: Supervisor; /** * @param {Object} config @@ -46,13 +46,8 @@ export default class Predictor { this.supervisor = new Supervisor(daemons, config.supervisor_epsilon); } - /** - * @param {Number|String} humanValue - * - * @returns {Number} - */ - pass(humanValue) { - const value = parseInt(humanValue, 10); + pass(humanValue: number): number { + const value = humanValue; if (value < 0 || value >= this.base) { throw new Error(`Passed value must be in [0, ${this.base})`); } @@ -70,7 +65,7 @@ export default class Predictor { * * @private */ - _createDaemons(daemonConfigs) { + private _createDaemons(daemonConfigs) { return daemonConfigs.map(config => { return new Daemon( this.base, @@ -81,10 +76,7 @@ export default class Predictor { }); } - /** - * @returns {Number} - */ - stepCount() { + stepCount(): number { return this.journal.length; } } diff --git a/src/Supervisor.ts b/src/Supervisor.ts index 45ee0f8..468c075 100644 --- a/src/Supervisor.ts +++ b/src/Supervisor.ts @@ -21,11 +21,6 @@ class Supervisor { this.epsilon = epsilon; } - /** - * @param {Journal} journal - * - * @returns {Number} - */ predict(journal: Journal): number { const predictions = this._createPredictions(journal); const ordered = this._sortPredictions(predictions); @@ -33,10 +28,6 @@ class Supervisor { return ordered[0].value; } - /** - * @param {Journal} journal - * @param {Number} humanValue - */ adjust(journal: Journal, humanValue) { const predictions = this._createPredictions(journal); for (const prediction of predictions) { diff --git a/tests/DaemonTest.ts b/tests/DaemonTest.ts index 18f2a66..be08a69 100644 --- a/tests/DaemonTest.ts +++ b/tests/DaemonTest.ts @@ -4,49 +4,51 @@ import { expect } from 'chai'; import Daemon from '../src/Daemon'; import Journal from '../src/Journal'; -// it('Get prediction for beginning', function() { -// const m = new Journal(); -// const d = new Daemon(2, 1, 1); -// const predicted = d.predict(m); -// expect(predicted).to.equals(0); -// }); +describe('Daemon', function() { + it('Get prediction for beginning', function() { + const journal = new Journal(); + const daemon = new Daemon(2, 1, 1); + const predicted = daemon.predict(journal); + expect(predicted).to.equals(0); + }); -it('Can get power', function() { - const d = new Daemon(2, 5, 8); - expect(d.power).to.eqls(13); + it('Can get power', function() { + const d = new Daemon(2, 5, 8); + expect(d.power).to.eqls(13); + }); + + it('Daemon 1-1', function() { + const journal = new Journal(); + const daemon = new Daemon(2, 1, 1, 0.1); + + const steps = [ + { + prediction: 0, + human: 1, + }, + { + prediction: 0, + human: 1, + }, + { + prediction: 1, + human: 1, + }, + { + prediction: 0, + human: 1, + }, + { + prediction: 1, + human: 1, + }, + ]; + + steps.forEach(step => { + const prediction = daemon.predict(journal); + expect(prediction).to.eqls(step.prediction); + daemon.adjust(journal, step.human); + journal.makeMove(step.human, step.prediction); + }); + }); }); - -// it('Daemon 1-1', function() { -// const m = new Journal(); -// const d = new Daemon(2, 1, 1); -// -// const steps = [ -// { -// prediction: 0, -// human: 1, -// }, -// { -// prediction: 0, -// human: 1, -// }, -// { -// prediction: 1, -// human: 1, -// }, -// { -// prediction: 0, -// human: 1, -// }, -// { -// prediction: 1, -// human: 1, -// }, -// ]; -// -// steps.forEach(step => { -// const prediction = d.predict(m); -// expect(prediction).to.eqls(step.prediction); -// d.adjust(m, step.human); -// m.makeMove(step.human, step.prediction); -// }); -// }); diff --git a/tests/JourlanTest.ts b/tests/JourlanTest.ts index 0a1ec86..8475827 100644 --- a/tests/JourlanTest.ts +++ b/tests/JourlanTest.ts @@ -4,29 +4,34 @@ import { expect } from 'chai'; import Journal from '../src/Journal'; import Move from '../src/Move'; -it('Create with empty constructor', function() { - const m = new Journal(); - expect(m.getLastMovements(5, 5)).to.eqls([]); -}); +describe('Journal', function() { + it('Create with empty constructor', function() { + const journal = new Journal(); + expect(journal.length).to.equals(0); + expect(journal.getLastMovements(5, 5)).to.eqls([]); + }); -it('Constructor with human steps', function() { - const m = new Journal([new Move(1, 1)]); - expect(m.getLastMovements(5, 5)).to.eqls([1, 1]); -}); + it('Constructor with human steps', function() { + const journal = new Journal([new Move(1, 1)]); + expect(journal.length).equals(1); + expect(journal.getLastMovements(5, 5)).to.eqls([1, 1]); + }); -it('Make steps', function() { - const m = new Journal(); - m.makeMove(1, 0); - expect(m.getLastMovements(5, 5)).to.eqls([0, 1]); -}); + it('Make steps', function() { + const journal = new Journal(); + journal.makeMove(1, 0); + journal.makeMove(1, 1); + expect(journal.length).to.equals(2); + expect(journal.getLastMovements(2, 2)).to.eqls([0, 1, 1, 1]); + }); -it('Get slice', function() { - const m = new Journal([ - new Move(1, 1), - new Move(0, 1), - new Move(0, 1), - new Move(1, 0), - ]); - - expect(m.getLastMovements(2, 2)).to.eqls([1, 0, 0, 1]); + it('Get slice', function() { + const m = new Journal([ + new Move(1, 1), + new Move(0, 1), + new Move(0, 1), + new Move(1, 0), + ]); + expect(m.getLastMovements(2, 2)).to.eqls([1, 0, 0, 1]); + }); }); diff --git a/tools/node b/tools/node index b6efc02..a506b9f 100755 --- a/tools/node +++ b/tools/node @@ -4,13 +4,18 @@ set -eu source .env +TTY= +if [ -t 1 ] ; then + TTY=--tty +fi + docker run \ --rm \ --interactive \ - --tty \ + ${TTY} \ --init \ --user "$(id -u):$(id -g)" \ - --volume "$PWD:/srv/app" \ - --workdir /srv/app \ + --volume "$PWD:/app" \ + --workdir /app \ ${NODE_IMAGE} \ node "$@" diff --git a/tools/npm b/tools/npm index b5c6d17..90262ec 100755 --- a/tools/npm +++ b/tools/npm @@ -9,14 +9,19 @@ CONTAINER_CACHE_DIR=/tmp/.npm mkdir -p ${HOST_CACHE_DIR} +TTY= +if [ -t 1 ] ; then + TTY=--tty +fi + docker run \ --rm \ --interactive \ - --tty \ + ${TTY} \ --init \ --user "$UID:$(id -g)" \ - --volume "$PWD:/srv/app" \ + --volume "$PWD:/app" \ --env npm_config_cache="${CONTAINER_CACHE_DIR}" \ - --workdir /srv/app \ + --workdir /app \ ${NODE_IMAGE} \ npm "$@" diff --git a/tools/tsc b/tools/tsc index fa3024e..03853c5 100755 --- a/tools/tsc +++ b/tools/tsc @@ -10,7 +10,7 @@ docker run \ --tty \ --init \ --user "$(id -u):$(id -g)" \ - --volume "$PWD:/srv/app" \ - --workdir /srv/app \ + --volume "$PWD:/app" \ + --workdir /app \ ${NODE_IMAGE} \ ./node_modules/.bin/tsc "$@"