Skip to content

Commit

Permalink
refactor build-change-trail tests to use shae-ents
Browse files Browse the repository at this point in the history
- improve nx project input config
  • Loading branch information
spearwolf committed Jul 10, 2024
1 parent 3efff81 commit e556755
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 50 deletions.
10 changes: 6 additions & 4 deletions nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": ["build", "lint", "test", "e2e"],
"parallel": 5
"parallel": 8
}
}
},
"affected": {
"defaultBase": "main"
"defaultBase": "main",
"namedInputs": {
"default": ["{projectRoot}/**/*"],
"sources": ["{projectRoot}/src/**/*"]
},
"targetDefaults": {
"build": {
Expand All @@ -31,7 +33,7 @@
},
"buildNpmPkg": {
"executor": "nx:run-script",
"dependsOn": ["^build", "build"],
"dependsOn": ["^build", "build", "default"],
"options": {
"script": "buildNpmPkg"
}
Expand Down
62 changes: 33 additions & 29 deletions packages/shadow-ents-testing/test/build-change-trail.test.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,55 @@
import {expect} from '@esm-bundle/chai';
import {ComponentChangeType, ComponentContext, ContextLost} from '@spearwolf/shadow-ents';
import '@spearwolf/shadow-ents/shadow-entity.js';
import '@spearwolf/shadow-ents/shae-ent.js';
import sinon from 'sinon';
import {findElementsById} from '../src/findElementsById.js';
import {render} from '../src/render.js';

describe('build-change-trail', () => {
const cc = ComponentContext.get();

beforeEach(async () => {
render(`
<shadow-local-env id="localEnv">
<shadow-entity id="a" token="a">
<shadow-entity id="b" token="b">
<shadow-entity id="c" token="c"></shadow-entity>
<shadow-entity id="d"></shadow-entity>
</shadow-entity>
</shadow-entity>
<shadow-entity id="e" token="e">
<shadow-entity id="f" token="f"></shadow-entity>
</shadow-entity>
</shadow-local-env>`);

await Promise.all([customElements.whenDefined('shadow-local-env'), customElements.whenDefined('shadow-entity')]);
<shae-ent id="a" token="a">
<shae-ent id="b" token="b">
<shae-ent id="c" token="c"></shae-ent>
<shae-ent id="d"></shae-ent>
</shae-ent>
</shae-ent>
<shae-ent id="e" token="e">
<shae-ent id="f" token="f"></shae-ent>
</shae-ent>`);

await customElements.whenDefined('shae-ent');
});

afterEach(() => {
ComponentContext.get().clear();
cc.clear();
});

it('append e to b', () => {
const [b, e, localEnv] = findElementsById('b', 'e', 'localEnv');
const [b, e] = findElementsById('b', 'e');

let changeTrail = cc.buildChangeTrails();

let changeTrail = localEnv.getComponentContext().buildChangeTrails();
// console.log('append e to b (1st)', JSON.stringify(changeTrail, null, 2));

e.token = 'bee';

b.append(e);

changeTrail = localEnv.getComponentContext().buildChangeTrails();
changeTrail = cc.buildChangeTrails();

// console.log('append e to b (2nd)', JSON.stringify(changeTrail, null, 2));

expect(changeTrail, 'changeTrail').to.deep.equal([
// --- I) structural changes ---
{
type: ComponentChangeType.SetParent,
uuid: e.uuid,
parentUuid: b.uuid,
},
// --- II) content changes ---
{
type: ComponentChangeType.ChangeToken,
uuid: e.uuid,
Expand All @@ -53,14 +59,14 @@ describe('build-change-trail', () => {
});

it('a: set properties', () => {
const [a, localEnv] = findElementsById('a', 'localEnv');
const [a] = findElementsById('a');

localEnv.getComponentContext().buildChangeTrails();
cc.buildChangeTrails();

a.viewComponent.setProperty('foo', 'bar');
a.viewComponent.setProperty('plah', [1, 2, 3]);

const changeTrail = localEnv.getComponentContext().buildChangeTrails();
const changeTrail = cc.buildChangeTrails();

expect(changeTrail, 'changeTrail').to.deep.equal([
{
Expand All @@ -75,17 +81,17 @@ describe('build-change-trail', () => {
});

it('destroy a', () => {
const [a, b, c, d, localEnv] = findElementsById('a', 'b', 'c', 'd', 'localEnv');
const [a, b, c, d] = findElementsById('a', 'b', 'c', 'd');

localEnv.getComponentContext().buildChangeTrails();
cc.buildChangeTrails();

expect(b.parentEntity).to.equal(a);
expect(b.entParentNode).to.equal(a);

a.viewComponent.setProperty('foo', 'bar');
d.viewComponent.setProperty('plah', 'plah!');
a.remove();

const changeTrail = localEnv.getComponentContext().buildChangeTrails();
const changeTrail = cc.buildChangeTrails();

expect(changeTrail, 'changeTrail').to.deep.equal([
{
Expand All @@ -108,8 +114,7 @@ describe('build-change-trail', () => {
});

it('reCreateChanges', () => {
const [a, b, c, d, e, f, localEnv] = findElementsById('a', 'b', 'c', 'd', 'e', 'f', 'localEnv');
const cc = localEnv.getComponentContext();
const [a, b, c, d, e, f] = findElementsById('a', 'b', 'c', 'd', 'e', 'f');

const contextLostSpy = sinon.spy();
f.viewComponent.on(ContextLost, contextLostSpy);
Expand Down Expand Up @@ -163,8 +168,7 @@ describe('build-change-trail', () => {
});

it('reCreateChanges with change gap', () => {
const [a, b, c, d, e, f, localEnv] = findElementsById('a', 'b', 'c', 'd', 'e', 'f', 'localEnv');
const cc = localEnv.getComponentContext();
const [a, b, c, d, e, f] = findElementsById('a', 'b', 'c', 'd', 'e', 'f');

let changeTrail = cc.buildChangeTrails();

Expand Down
25 changes: 23 additions & 2 deletions packages/shadow-ents/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,29 @@
"options": {
"script": "test"
},
"dependsOn": ["^build"]
"dependsOn": ["^build"],
"inputs": ["sources"]
},
"build": {
"dependsOn": ["^build"],
"outputs": ["{projectRoot}/dist"],
"inputs": ["sources"]
}
},
"tags": []
"tags": [],
"namedInputs": {
"sources": [
"{workspaceRoot}/package.json",
"{workspaceRoot}/tsconfig.json",
"{projectRoot}/src/**/*.ts",
"!{projectRoot}/docs",
"{projectRoot}/bundle.mjs",
"{projectRoot}/package.json",
"{projectRoot}/package.override.json",
"{projectRoot}/tsconfig.bundle.json",
"{projectRoot}/tsconfig.json",
"{projectRoot}/tsconfig.lib.json",
"{projectRoot}/tsconfig.tests.json"
]
}
}
42 changes: 29 additions & 13 deletions packages/shadow-ents/src/elements/ShaeEntElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export class ShaeEntElement extends ShaeElement {
return this.viewComponent$.value;
}

get uuid(): string | undefined {
return this.viewComponent?.uuid;
}

get token(): string | undefined {
return this.token$.value;
}
Expand Down Expand Up @@ -73,24 +77,35 @@ export class ShaeEntElement extends ShaeElement {
#setupViewComponentEffect() {
this.#unsubscribeViewComponentEffect?.();

const [, unsubscribe] = createEffect(() => {
const context = this.componentContext$.get();
const token = this.token$.get();
const vc = this.viewComponent$.value;
const unsubscribeComponentContext = this.componentContext$.onChange((context) => {
const token = this.token$.value;

let vc = this.viewComponent$.value;

if (vc) {
if (context == null) {
this.viewComponent$.set(undefined);
} else {
// TODO make token changeable (ViewComponent)? copy properties to new instance..
this.viewComponent$.set(new ViewComponent(token, {context}));
}
vc.context = context;
} else if (context) {
this.viewComponent$.set(new ViewComponent(token, {context}));
vc = new ViewComponent(token, {context});
this.viewComponent$.set(vc);
}

this.syncShadowObjects();
});

this.#unsubscribeViewComponentEffect = unsubscribe;
const unsubscribeTokenChange = this.token$.onChange((token) => {
const vc = this.viewComponent$.value;

if (vc) {
vc.token = token;
}

this.syncShadowObjects();
});

this.#unsubscribeViewComponentEffect = () => {
unsubscribeComponentContext();
unsubscribeTokenChange();
};
}

#destroyViewComponentEffect() {
Expand Down Expand Up @@ -221,12 +236,13 @@ export class ShaeEntElement extends ShaeElement {

this.#unsubscribeFromParent?.();
this.#unsubscribeFromParent = undefined;

if (parent) {
const [, unsubscribe] = createEffect(() => {
const vc = this.viewComponent$.get();
if (vc) {
const parentVC = parent.viewComponent$.get();
vc.parent = parentVC.context === vc.context ? parentVC : undefined;
vc.parent = parentVC && parentVC.context === vc.context ? parentVC : undefined;
if (vc.parent == null) {
queueMicrotask(() => {
this.#dispatchRequestParent();
Expand Down
2 changes: 1 addition & 1 deletion packages/shadow-ents/src/view/ComponentChanges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export class ComponentChanges {
this.#transferables.clear();
}

changeToken(token: string) {
changeToken(token: string | undefined) {
if (token === this.#token) {
this.#nextToken = undefined;
} else {
Expand Down
4 changes: 4 additions & 0 deletions packages/shadow-ents/src/view/ComponentContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ export class ComponentContext {
}
}

changeToken(component: ViewComponent, token?: string) {
this.#components.get(component.uuid)?.changes.changeToken(token);
}

isChildOf(child: ViewComponent, parent: ViewComponent) {
if (this.hasComponent(parent)) {
const entry = this.#components.get(parent.uuid)!;
Expand Down
4 changes: 4 additions & 0 deletions packages/shadow-ents/src/view/LocalShadowObjectEnv.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ describe('LocalShadowObjectEnv', () => {
await env.ready();

expect(env.isReady).toBeTruthy();

env.destroy();
});

it('should sync', async () => {
Expand All @@ -44,5 +46,7 @@ describe('LocalShadowObjectEnv', () => {

expect(entity).toBeDefined();
expect(entity.getProperty('bar')).toBe(42);

env.destroy();
});
});
6 changes: 6 additions & 0 deletions packages/shadow-ents/src/view/ShadowEnv.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ describe('ShadowEnv', () => {

expect(env.view).toBeDefined();
expect(env.isReady).toBeFalsy();

env.destroy();
});

it('should be ready', async () => {
Expand All @@ -35,6 +37,8 @@ describe('ShadowEnv', () => {
await env.ready();

expect(env.isReady).toBeTruthy();

env.destroy();
});

it('should create and destroy shadow-objects', async () => {
Expand Down Expand Up @@ -79,5 +83,7 @@ describe('ShadowEnv', () => {

expect(localObjEnv.kernel.hasEntity(vc.uuid)).toBeFalsy();
expect(localObjEnv.kernel.findShadowObjects(vc.uuid)).toHaveLength(0);

env.destroy();
});
});
10 changes: 10 additions & 0 deletions packages/shadow-ents/src/view/ShadowEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,19 @@ export class ShadowEnv {
}

destroy() {
const ns = this.#comCtx?.ns;

this.envProxy?.destroy();
this.envProxy = undefined;
this.view = undefined;

if (ns) {
if (globalThis.__shadowEnvs.has(ns)) {
if (globalThis.__shadowEnvs.get(ns) === this) {
globalThis.__shadowEnvs.delete(ns);
}
}
}
}

#syncIfScheduled = () => {
Expand Down
9 changes: 8 additions & 1 deletion packages/shadow-ents/src/view/ViewComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class ViewComponentError extends Error {

export class ViewComponent extends Eventize {
readonly #uuid: string;
readonly #token: string;

#token?: string;

#context?: ComponentContext;

Expand All @@ -26,6 +27,12 @@ export class ViewComponent extends Eventize {
return this.#token;
}

set token(token: string | undefined) {
if (token === this.#token) return;
this.#token = token;
this.#context?.changeToken(this, token);
}

get parent(): ViewComponent | undefined {
return this.#parent;
}
Expand Down

0 comments on commit e556755

Please sign in to comment.