Skip to content

Commit

Permalink
update devtools-connector tests to be compatible with new storage sta…
Browse files Browse the repository at this point in the history
…ck (PolymerLabs#4015)

* update devtools-connector tests to be compatible with new storage stack

* move storageKeyForTest to testing util
  • Loading branch information
galganif authored Nov 13, 2019
1 parent 2fa23a3 commit cfd32ad
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 25 deletions.
14 changes: 12 additions & 2 deletions src/devtools-connector/arc-stores-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {Manifest} from '../runtime/manifest.js';
import {SingletonStorageProvider, CollectionStorageProvider} from '../runtime/storage/storage-provider-base.js';
import {Type} from '../runtime/type.js';
import {StorageKey} from '../runtime/storageNG/storage-key.js';
import {Store} from '../runtime/storageNG/store.js';
import {UnifiedStore} from '../runtime/storageNG/unified-store.js';

type Result = {
Expand Down Expand Up @@ -96,8 +97,17 @@ export class ArcStoresFetcher {
return (store as CollectionStorageProvider).toList();
} else if ((store as SingletonStorageProvider).get) {
return (store as SingletonStorageProvider).get();
} else {
return `(don't know how to dereference)`;
} else if (store instanceof Store) {
// tslint:disable-next-line: no-any
const crdtData = await (await (store as Store<any>).activate()).serializeContents();
if (crdtData.values) {
if (Object.values(crdtData.values).length === 1) {
// Single value, extract the value only (discard the version).
return Object.values(crdtData.values)[0]['value'];
}
}
return crdtData;
}
return `(don't know how to dereference)`;
}
}
51 changes: 30 additions & 21 deletions src/devtools-connector/tests/arc-stores-fetcher-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import {FakeSlotComposer} from '../../runtime/testing/fake-slot-composer.js';
import {StubLoader} from '../../runtime/testing/stub-loader.js';
import {Manifest} from '../../runtime/manifest.js';
import {Runtime} from '../../runtime/runtime.js';
import {VolatileSingleton} from '../../runtime/storage/volatile-storage.js';
import {SingletonType} from '../../runtime/type.js';
import {singletonHandleForTest, storageKeyPrefixForTest} from '../../runtime/testing/handle-for-test.js';
import {Flags} from '../../runtime/flags.js';

describe('ArcStoresFetcher', () => {
before(() => DevtoolsForTests.ensureStub());
Expand All @@ -26,11 +28,12 @@ describe('ArcStoresFetcher', () => {
schema Foo
Text value`);
const runtime = new Runtime(new StubLoader({}), FakeSlotComposer, context);
const arc = runtime.newArc('demo', 'volatile://', {inspectorFactory: devtoolsArcInspectorFactory});
const arc = runtime.newArc('demo', storageKeyPrefixForTest(), {inspectorFactory: devtoolsArcInspectorFactory});

const foo = arc.context.findSchemaByName('Foo').entityClass();
const fooStore = await arc.createStore(foo.type, 'fooStoreName', 'fooStoreId', ['awesome', 'arcs']);
await (fooStore as VolatileSingleton).set({value: 'persistence is useful'});
const fooStore = await arc.createStore(new SingletonType(foo.type), 'fooStoreName', 'fooStoreId', ['awesome', 'arcs']);
const fooHandle = await singletonHandleForTest(arc, fooStore);
await fooHandle.set(new foo({value: 'persistence is useful'}));

assert.isEmpty(DevtoolsForTests.channel.messages.filter(
m => m.messageType === 'fetch-stores-result'));
Expand All @@ -46,31 +49,37 @@ describe('ArcStoresFetcher', () => {

// Location in the schema file is stored in the type and used by some tools.
// We don't assert on it in this test.
delete results[0].messageBody.arcStores[0].type.entitySchema.fields.value.location;
delete results[0].messageBody.arcStores[0].type.innerType.entitySchema.fields.value.location;

const sessionId = arc.idGeneratorForTesting.currentSessionIdForTesting;
const entityId = Flags.useNewStorageStack ?
'!' + sessionId + ':demo:test-proxy2:3' :
'!' + sessionId + ':fooStoreId:1';

assert.deepEqual(results[0].messageBody, {
arcStores: [{
id: 'fooStoreId',
name: 'fooStoreName',
tags: ['awesome', 'arcs'],
storage: `volatile://${arc.id.toString()}^^volatile-0`,
storage: fooStore.storageKey,
type: {
tag: 'Entity',
entitySchema: {
description: {},
fields: {
value: {
kind: 'schema-primitive',
type: 'Text'
}
},
names: ['Foo']
}
innerType: {
tag: 'Entity',
entitySchema: {
description: {},
fields: {
value: {
kind: 'schema-primitive',
type: 'Text'
}
},
names: ['Foo']
}
},
tag: 'Singleton',
},
description: undefined,
value: {
value: 'persistence is useful'
}
value: {id: entityId, rawData: {value: 'persistence is useful'}}
}],
// Context stores from manifests have been moved to a temporary StorageStub implementation,
// StorageStub does not allow for fetching value. Let's add a test for context store after
Expand Down Expand Up @@ -98,7 +107,7 @@ describe('ArcStoresFetcher', () => {
P
foo = foo`);
const runtime = new Runtime(loader, FakeSlotComposer, context);
const arc = runtime.newArc('demo', 'volatile://', {inspectorFactory: devtoolsArcInspectorFactory});
const arc = runtime.newArc('demo', storageKeyPrefixForTest(), {inspectorFactory: devtoolsArcInspectorFactory});

const recipe = arc.context.recipes[0];
recipe.normalize();
Expand Down
3 changes: 2 additions & 1 deletion src/devtools-connector/tests/devtools-arc-inspector-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {MockSlotComposer} from '../../runtime/testing/mock-slot-composer.js';
import {StubLoader} from '../../runtime/testing/stub-loader.js';
import {Manifest} from '../../runtime/manifest.js';
import {Runtime} from '../../runtime/runtime.js';
import {storageKeyPrefixForTest} from '../../runtime/testing/handle-for-test.js';

describe('DevtoolsArcInspector', () => {
before(() => DevtoolsForTests.ensureStub());
Expand All @@ -38,7 +39,7 @@ describe('DevtoolsArcInspector', () => {
P
foo = foo`);
const runtime = new Runtime(loader, MockSlotComposer, context);
const arc = runtime.newArc('demo', 'volatile://', {inspectorFactory: devtoolsArcInspectorFactory});
const arc = runtime.newArc('demo', storageKeyPrefixForTest(), {inspectorFactory: devtoolsArcInspectorFactory});

const foo = arc.context.findSchemaByName('Foo').entityClass();
const fooStore = await arc.createStore(foo.type, undefined, 'fooStore');
Expand Down
7 changes: 6 additions & 1 deletion src/runtime/arc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {compareComparables} from './recipe/comparable.js';
import {SlotComposer} from './slot-composer.js';
import {StorageProviderBase, SingletonStorageProvider} from './storage/storage-provider-base.js';
import {StorageProviderFactory} from './storage/storage-provider-factory.js';
import {ArcType, CollectionType, EntityType, InterfaceType, RelationType, Type, TypeVariable, SingletonType, ReferenceType} from './type.js';
import {ArcType, CollectionType, EntityType, InterfaceType, RelationType, ReferenceType, SingletonType, Type, TypeVariable} from './type.js';
import {PecFactory} from './particle-execution-context.js';
import {InterfaceInfo} from './interface-info.js';
import {Mutex} from './mutex.js';
Expand Down Expand Up @@ -569,6 +569,11 @@ constructor({id, context, pecFactories, slotComposer, loader, storageKey, storag
if (typeof storageKey === 'string') {
throw new Error(`Can't use string storage keys with the new storage stack.`);
}
// Wrap entity types in a singleton.
if (type.isEntity) {
// TODO: Once recipes can handle singleton types this conversion can be removed.
type = new SingletonType(type);
}
store = new Store({storageKey, exists: Exists.MayExist, type, id, name});
} else {
if (typeof storageKey !== 'string') {
Expand Down
1 change: 1 addition & 0 deletions src/runtime/storageNG/unified-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export abstract class UnifiedStore implements Comparable<UnifiedStore>, OldStore

// Series of StoreInfo getters to make migration easier.
get id() { return this.storeInfo.id; }
get apiChannelMappingId() { return this.id; }
get name() { return this.storeInfo.name; }
get type() { return this.storeInfo.type; }
get originalId() { return this.storeInfo.originalId; }
Expand Down
15 changes: 15 additions & 0 deletions src/runtime/testing/handle-for-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import {CRDTSingletonTypeRecord} from '../crdt/crdt-singleton.js';
import {Manifest} from '../manifest.js';
import {SerializedEntity} from '../storage-proxy.js';
import {Entity} from '../entity.js';
import {VolatileStorageKey} from '../../runtime/storageNG/drivers/volatile.js';
import {StorageKey} from '../../runtime/storageNG/storage-key.js';
import {ArcId} from '../../runtime/id.js';


/**
* Creates a singleton handle for a store for testing purposes. Returns an
Expand Down Expand Up @@ -74,6 +78,17 @@ export async function collectionHandleForTest(arcOrManifest: Arc | Manifest, sto
}
}

/**
* Creates a storage key prefix for a store for testing purposes. Returns an
* appropriate string or NG storage key type depending on the storage migration flag.
*/
export function storageKeyPrefixForTest(): string|((arcId: ArcId) => StorageKey) {
if (Flags.useNewStorageStack) {
return arcId => new VolatileStorageKey(arcId, '');
}
return 'volatile://';
}

async function createStorageProxyForTest<T extends CRDTTypeRecord>(
arcOrManifest: Arc | Manifest, store: UnifiedStore): Promise<StorageProxy<T>> {
const activeStore = await store.activate();
Expand Down
7 changes: 7 additions & 0 deletions src/runtime/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ export abstract class Type {
return false;
}

get isEntity(): boolean {
return false;
}

collectionOf() {
return new CollectionType(this);
Expand Down Expand Up @@ -315,6 +318,10 @@ export class SingletonType<T extends Type> extends Type {
return true;
}

getEntitySchema(): Schema {
return this.innerType.getEntitySchema();
}

toString(options = undefined): string {
return `![${this.innerType.toString(options)}]`;
}
Expand Down

0 comments on commit cfd32ad

Please sign in to comment.