From d58c0786542db2219ccd3dc24b74babde10b3ed1 Mon Sep 17 00:00:00 2001 From: David Durschlag Date: Sat, 23 Mar 2019 13:27:07 -0400 Subject: [PATCH 1/8] feat: udtg for checking if something is a blackboard --- lib/Blackboard.ts | 11 +++++++++++ test/Blackboard.spec.ts | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 test/Blackboard.spec.ts diff --git a/lib/Blackboard.ts b/lib/Blackboard.ts index ef3f510..abc317c 100644 --- a/lib/Blackboard.ts +++ b/lib/Blackboard.ts @@ -8,3 +8,14 @@ export interface Blackboard { delete(ref: BlackboardRef): boolean; deleteAll(refs: BlackboardRef[]): BlackboardRef[]; } + +function isFunction(maybeFunction: any): maybeFunction is Function { + return maybeFunction !== null && maybeFunction !== undefined && typeof maybeFunction === 'function'; +} + +export const BLACKBOARD_METHODS = Object.freeze(['create', 'get', 'tryGet', 'put', 'delete', 'deleteAll']); + +export function isBlackboard(maybeBlackboard: any): maybeBlackboard is Blackboard { + return (maybeBlackboard !== null && maybeBlackboard !== undefined) + && !BLACKBOARD_METHODS.some((m) => !isFunction(maybeBlackboard[m])); +} diff --git a/test/Blackboard.spec.ts b/test/Blackboard.spec.ts new file mode 100644 index 0000000..6c44022 --- /dev/null +++ b/test/Blackboard.spec.ts @@ -0,0 +1,30 @@ +import {assert} from 'chai'; +import {isBlackboard, BLACKBOARD_METHODS} from '../lib/Blackboard'; + +function getMockBlackboard() { + return BLACKBOARD_METHODS.reduce((obj, meth) => (obj[meth] = () => ({}), obj), {} as any); +} + +describe('Blackboard', function() { + context('user-defined type-guard', function() { + it('succeeds when all properties are present and functions', function() { + assert.isTrue(isBlackboard(getMockBlackboard())); + }); + context('per-property checks', function() { + for (const prop of BLACKBOARD_METHODS) { + context(prop, function() { + it('fails if prop is missing', function() { + const bb: any = getMockBlackboard(); + delete bb[prop]; + assert.isFalse(isBlackboard(bb)); + }); + it('fails if prop is wrong', function() { + const bb: any = getMockBlackboard(); + bb[prop] = 'not a function'; + assert.isFalse(isBlackboard(bb)); + }); + }); + } + }); + }); +}); From 9f595c4923fe00a5058f8c0263f59a80ecb859b6 Mon Sep 17 00:00:00 2001 From: David Durschlag Date: Sat, 23 Mar 2019 15:10:51 -0400 Subject: [PATCH 2/8] feat: also add 'is' method to blackboards for reference equality checking --- lib/Blackboard.ts | 3 +- lib/InMemoryMapBlackboard.ts | 4 +++ test/InMemoryMapBlackboard.spec.ts | 57 ++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/lib/Blackboard.ts b/lib/Blackboard.ts index abc317c..8075ac7 100644 --- a/lib/Blackboard.ts +++ b/lib/Blackboard.ts @@ -2,6 +2,7 @@ import {BlackboardRef} from './BlackboardRef'; export interface Blackboard { create(ref: BlackboardRef, value: T): void; + is(ref: BlackboardRef, value: T): boolean; get(ref: BlackboardRef): T; tryGet(ref: BlackboardRef): [true, T]|[false, undefined]; put(ref: BlackboardRef, value: T): void; @@ -13,7 +14,7 @@ function isFunction(maybeFunction: any): maybeFunction is Function { return maybeFunction !== null && maybeFunction !== undefined && typeof maybeFunction === 'function'; } -export const BLACKBOARD_METHODS = Object.freeze(['create', 'get', 'tryGet', 'put', 'delete', 'deleteAll']); +export const BLACKBOARD_METHODS = Object.freeze(['create', 'get', 'tryGet', 'put', 'delete', 'deleteAll', 'is']); export function isBlackboard(maybeBlackboard: any): maybeBlackboard is Blackboard { return (maybeBlackboard !== null && maybeBlackboard !== undefined) diff --git a/lib/InMemoryMapBlackboard.ts b/lib/InMemoryMapBlackboard.ts index 64230b3..bcd028a 100644 --- a/lib/InMemoryMapBlackboard.ts +++ b/lib/InMemoryMapBlackboard.ts @@ -6,6 +6,10 @@ import {BlackboardError} from './BlackboardError'; export class InMemoryMapBlackboard implements Blackboard { private readonly state: Map, any]> = new Map(); + public is(ref: BlackboardRef, value: T) { + return this.state.has(ref.uuid) && this.state.get(ref.uuid)![1] === value; + } + public get(ref: BlackboardRef) { if (this.state.has(ref.uuid)) { return InMemoryMapBlackboard.cloneObject(this.state.get(ref.uuid)![1]); diff --git a/test/InMemoryMapBlackboard.spec.ts b/test/InMemoryMapBlackboard.spec.ts index 8233cba..b591566 100644 --- a/test/InMemoryMapBlackboard.spec.ts +++ b/test/InMemoryMapBlackboard.spec.ts @@ -25,6 +25,63 @@ describe('InMemoryMapBlackboard', function() { assert.isTrue(thrown); }); + context('is', function() { + let uut = new InMemoryMapBlackboard(); + const bbRef = new BlackboardRef('test'); + beforeEach(function() { + uut = new InMemoryMapBlackboard(); + }); + const refVals = [{}, [], new Map()]; + const valVals = ['', 'test', 3, 0, -1, true, false]; + const magicVals = [() => ({}), new Error('test')]; + context('same as stored', function() { + const testTrue = (value: any) => () => { + uut.create(bbRef, value); + assert.isTrue(uut.is(bbRef, value)); + }; + context('reference types', function() { + for (const value of refVals) { + it(`works with ${value}`, testTrue(value)); + } + }); + context('value types', function() { + for (const value of valVals) { + it(`works with ${value}`, testTrue(value)); + } + }); + context('magic types', function() { + for (const value of magicVals) { + it(`works with ${value}`, testTrue(value)); + } + }); + }); + context('get-clone', function() { + const testFalse = (value: any) => () => { + uut.create(bbRef, value); + assert.isFalse(uut.is(bbRef, uut.get(bbRef))); + }; + const testTrue = (value: any) => () => { + uut.create(bbRef, value); + assert.isTrue(uut.is(bbRef, uut.get(bbRef))); + }; + context('reference types', function() { + for (const value of refVals) { + it(`works with ${value}`, testFalse(value)); + } + }); + context('value types', function() { + for (const value of valVals) { + it(`works with ${value}`, testTrue(value)); + } + }); + context('magic types', function() { + for (const value of magicVals) { + it(`works with ${value}`, testTrue(value)); + } + }); + }); + }); + it('get', function() { const uut = new InMemoryMapBlackboard(); const bbRef = new BlackboardRef('someName'); From cca550e584091204473f11ab7da2f6ed05b8d663 Mon Sep 17 00:00:00 2001 From: David Durschlag Date: Sat, 23 Mar 2019 17:49:25 -0400 Subject: [PATCH 3/8] fix: remove submodule from CI --- .circleci/config.yml | 1 - package-lock.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 01e0801..a75c78a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,7 +22,6 @@ jobs: - run: name: Set Up Environment command: | - git submodule update --init --recursive ci_scripts/ci_tool.sh --setup_npm - persist_to_workspace: root: ./ diff --git a/package-lock.json b/package-lock.json index 35b8c3c..27f122d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "@sixriver/blackboard", + "name": "@6river/blackboard", "version": "1.0.0", "lockfileVersion": 1, "requires": true, From 2d9dd5dbe989fc0b4723c1dc03029c5899a45e91 Mon Sep 17 00:00:00 2001 From: David Durschlag Date: Sat, 23 Mar 2019 17:51:02 -0400 Subject: [PATCH 4/8] fix: remove thing from ci_scripts which is gone --- .circleci/config.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a75c78a..564ebff 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,10 +19,6 @@ jobs: key: dependency-cache-{{ checksum "package-lock.json" }} paths: - ./node_modules - - run: - name: Set Up Environment - command: | - ci_scripts/ci_tool.sh --setup_npm - persist_to_workspace: root: ./ paths: From 032aa971755532d9d25f0616ce0c6ade139444e8 Mon Sep 17 00:00:00 2001 From: David Durschlag Date: Mon, 25 Mar 2019 11:21:47 -0400 Subject: [PATCH 5/8] fix: switch npm token setting method; hopefully this works better --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 564ebff..ff90dfc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ jobs: - run: name: Set NPM auth token command: | - npm config set //registry.npmjs.org/:_authToken "${NPM_TOKEN}" + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc - run: name: npm publish via script command: | From ca62ffd85d831d523b4bd527b9301a65ea02b79d Mon Sep 17 00:00:00 2001 From: David Durschlag Date: Mon, 25 Mar 2019 11:26:45 -0400 Subject: [PATCH 6/8] feat: kick sem-rel to get a new version number, hopefully From 7dc230ac34502ec11d1f2f8832e53215888a1695 Mon Sep 17 00:00:00 2001 From: David Durschlag Date: Mon, 25 Mar 2019 13:33:45 -0400 Subject: [PATCH 7/8] fix: update cache key in case bad cache is causing issues. --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ff90dfc..6fc3562 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,14 +9,14 @@ jobs: - checkout - restore_cache: keys: - - dependency-cache-{{ checksum "package-lock.json"}} + - dependency-cache-2-{{ checksum "package-lock.json"}} - dependency-cache- - run: name: Install node dependencies command: | npm ci - save_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} + key: dependency-cache-2-{{ checksum "package-lock.json" }} paths: - ./node_modules - persist_to_workspace: From 4f2003c71652376fa3f4f0cdf80b2fd647c6f934 Mon Sep 17 00:00:00 2001 From: David Durschlag Date: Tue, 26 Mar 2019 10:02:10 -0400 Subject: [PATCH 8/8] fix: revert config changes that didn't help --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6fc3562..564ebff 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,14 +9,14 @@ jobs: - checkout - restore_cache: keys: - - dependency-cache-2-{{ checksum "package-lock.json"}} + - dependency-cache-{{ checksum "package-lock.json"}} - dependency-cache- - run: name: Install node dependencies command: | npm ci - save_cache: - key: dependency-cache-2-{{ checksum "package-lock.json" }} + key: dependency-cache-{{ checksum "package-lock.json" }} paths: - ./node_modules - persist_to_workspace: @@ -34,7 +34,7 @@ jobs: - run: name: Set NPM auth token command: | - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc + npm config set //registry.npmjs.org/:_authToken "${NPM_TOKEN}" - run: name: npm publish via script command: |