Skip to content

Commit

Permalink
fix: fixing override indice bug, and adding e2e test
Browse files Browse the repository at this point in the history
  • Loading branch information
alharris-at committed Nov 4, 2021
1 parent cbd96c9 commit c8500bf
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 138 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ MockComponentRenderer {
},
},
"node": StudioNode {
"children": Array [],
"component": Object {
"componentType": "Button",
"name": "MyButton",
Expand All @@ -27,11 +26,7 @@ MockComponentRenderer {
},
},
},
"elementIndex": 0,
"parent": StudioNode {
"children": Array [
[Circular],
],
"component": Object {
"componentType": "View",
"name": "MyView",
Expand All @@ -41,22 +36,6 @@ MockComponentRenderer {
},
},
"parent": StudioNode {
"children": Array [
StudioNode {
"children": Array [],
"component": Object {
"componentType": "Button",
"name": "MyButton",
"properties": Object {
"value": Object {
"value": "Confirm",
},
},
},
"elementIndex": 0,
"parent": [Circular],
},
],
"component": Object {
"componentType": "View",
"name": "MyView",
Expand Down
73 changes: 39 additions & 34 deletions packages/studio-ui-codegen/lib/__tests__/studio-node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,44 +64,41 @@ describe('StudioNode', () => {

describe('getOverrideKey', () => {
test('returns for parent', () => {
const rootComponent = new StudioNode(createSimpleComponentForType('Flex'));
new StudioNode(createSimpleComponentForType('Button'), rootComponent);
const rootComponent = createStudioNodeOfType('Flex', createStudioNodeOfType('Button'));

expect(rootComponent.getOverrideKey()).toEqual('Flex');
});

test('returns only one child', () => {
const rootComponent = new StudioNode(createSimpleComponentForType('Flex'));
const childComponent = new StudioNode(createSimpleComponentForType('Button'), rootComponent);
const button1 = createStudioNodeOfType('Button');
createStudioNodeOfType('Flex', button1);

expect(childComponent.getOverrideKey()).toEqual('Flex.Button[0]');
expect(button1.getOverrideKey()).toEqual('Flex.Button[0]');
});

test('returns index 0 for first of multiple elements', () => {
const rootComponent = new StudioNode(createSimpleComponentForType('Flex'));
const firstChildComponent = new StudioNode(createSimpleComponentForType('Button'), rootComponent);
new StudioNode(createSimpleComponentForType('Button'), rootComponent);
new StudioNode(createSimpleComponentForType('Tooltip'), rootComponent);
const button1 = createStudioNodeOfType('Button');
createStudioNodeOfType('Flex', button1, createStudioNodeOfType('Button'), createStudioNodeOfType('Tooltip'));

expect(firstChildComponent.getOverrideKey()).toEqual('Flex.Button[0]');
expect(button1.getOverrideKey()).toEqual('Flex.Button[0]');
});

test('returns index 0 for first of element of type', () => {
const rootComponent = new StudioNode(createSimpleComponentForType('Flex'));
new StudioNode(createSimpleComponentForType('Button'), rootComponent);
new StudioNode(createSimpleComponentForType('Button'), rootComponent);
const firstTooltipChildComponent = new StudioNode(createSimpleComponentForType('Tooltip'), rootComponent);
const button1 = createStudioNodeOfType('Button');
const button2 = createStudioNodeOfType('Button');
const tooltip1 = createStudioNodeOfType('Tooltip');
createStudioNodeOfType('Flex', button1, button2, tooltip1);

expect(firstTooltipChildComponent.getOverrideKey()).toEqual('Flex.Tooltip[0]');
expect(tooltip1.getOverrideKey()).toEqual('Flex.Tooltip[0]');
});

test('returns index 1 for second of element of type', () => {
const rootComponent = new StudioNode(createSimpleComponentForType('Flex'));
new StudioNode(createSimpleComponentForType('Button'), rootComponent);
const secondChildComponent = new StudioNode(createSimpleComponentForType('Button'), rootComponent);
new StudioNode(createSimpleComponentForType('Tooltip'), rootComponent);
const button1 = createStudioNodeOfType('Button');
const button2 = createStudioNodeOfType('Button');
const tooltip1 = createStudioNodeOfType('Tooltip');
createStudioNodeOfType('Flex', button1, button2, tooltip1);

expect(secondChildComponent.getOverrideKey()).toEqual('Flex.Button[1]');
expect(button2.getOverrideKey()).toEqual('Flex.Button[1]');
});

/**
Expand All @@ -119,27 +116,35 @@ describe('StudioNode', () => {
* </Flex>
*/
test('returns for deeply nested elements', () => {
const rootComponent = new StudioNode(createSimpleComponentForType('Flex'));
new StudioNode(createSimpleComponentForType('Flex'), rootComponent);
new StudioNode(createSimpleComponentForType('Flex'), rootComponent);
const thirdChildComponentOfType = new StudioNode(createSimpleComponentForType('Flex'), rootComponent);
new StudioNode(createSimpleComponentForType('Tooltip'), rootComponent);
new StudioNode(createSimpleComponentForType('Button'), rootComponent);
new StudioNode(createSimpleComponentForType('Button'), thirdChildComponentOfType);
const secondSubChildOfType = new StudioNode(createSimpleComponentForType('Button'), thirdChildComponentOfType);
const firstSubSubChild = new StudioNode(createSimpleComponentForType('Tooltip'), secondSubChildOfType);

expect(thirdChildComponentOfType.getOverrideKey()).toEqual('Flex.Flex[2]');
const firstSubSubChild = createStudioNodeOfType('Tooltip');

const firstSubChildOfType = createStudioNodeOfType('Button');
const secondSubChildOfType = createStudioNodeOfType('Button', firstSubSubChild);

const flex1 = createStudioNodeOfType('Flex');
const flex2 = createStudioNodeOfType('Flex');
const flex3 = createStudioNodeOfType('Flex', firstSubChildOfType, secondSubChildOfType);
const flex4 = createStudioNodeOfType('Flex');
const tooltip1 = createStudioNodeOfType('Tooltip');
const button1 = createStudioNodeOfType('Button');

createStudioNodeOfType('Flex', flex1, flex2, flex3, flex4, tooltip1, button1);

expect(flex3.getOverrideKey()).toEqual('Flex.Flex[2]');
expect(secondSubChildOfType.getOverrideKey()).toEqual('Flex.Flex[2].Button[1]');
expect(firstSubSubChild.getOverrideKey()).toEqual('Flex.Flex[2].Button[1].Tooltip[0]');
});
});
});

const createSimpleComponentForType = (type: string): StudioComponentChild => {
return {
const createStudioNodeOfType = (type: string, ...children: StudioNode[]): StudioNode => {
const node = new StudioNode({
componentType: type,
name: type,
properties: {},
};
children: children.map((child) => child.component as StudioComponentChild),
});
// eslint-disable-next-line no-return-assign, no-param-reassign
children.forEach((child) => (child.parent = node));
return node;
};
23 changes: 11 additions & 12 deletions packages/studio-ui-codegen/lib/studio-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,9 @@ export class StudioNode {

parent?: StudioNode;

children: StudioNode[];

elementIndex?: number;

constructor(component: StudioComponent | StudioComponentChild, parent?: StudioNode) {
this.component = component;
this.parent = parent;
this.children = [];
if (this.parent) {
this.elementIndex = this.parent.children.filter(
(childNode) => this.component.componentType === childNode.component.componentType,
).length;
this.parent.children.push(this);
}
}

isRoot(): boolean {
Expand All @@ -47,6 +36,16 @@ export class StudioNode {
return [this];
}

getOverrideIndex(): number {
if (this.parent === undefined || this.parent.component.children === undefined) {
return -1;
}

return this.parent.component.children
.filter((child: StudioComponentChild) => child.componentType === this.component.componentType)
.findIndex((child: StudioComponentChild) => child === this.component);
}

/**
* Build the override path for a given element walking from the node to tree root, providing an index
* for all but the top-level components.
Expand All @@ -61,7 +60,7 @@ export class StudioNode {
*/
getOverrideKey(): string {
const [parentElement, ...childElements] = this.getComponentPathToRoot().reverse();
const childPath = childElements.map((node) => `${node.component.componentType}[${node.elementIndex}]`);
const childPath = childElements.map((node) => `${node.component.componentType}[${node.getOverrideIndex()}]`);
return [parentElement.component.componentType, ...childPath].join('.');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,15 @@ describe('Generated Components', () => {
});
});

describe('Overrides', () => {
it('renders overrides with the correct indices', () => {
cy.visit('http://localhost:3000/component-tests');
cy.get('#componentWithNestedOverrides').should('have.css', 'background-color', 'rgb(255, 0, 0)');
cy.get('#componentWithNestedOverrides #ChildFlex3').should('have.css', 'background-color', 'rgb(0, 128, 0)');
cy.get('#componentWithNestedOverrides #ChildChildFlex1').should('have.css', 'background-color', 'rgb(0, 0, 255)');
});
});

describe('Generated Themes', () => {
it('Successfully decorates the app', () => {
cy.visit('http://localhost:3000/component-tests');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { DataStore } from 'aws-amplify';
import { User } from './models';
import CollectionWithBindingItemsName from './ui-components/CollectionWithBindingItemsName';
import ComponentWithBoundPropertyConditional from './ui-components/ComponentWithBoundPropertyConditional';
import ComponentWithNestedOverrides from './ui-components/ComponentWithNestedOverrides';
/* eslint-enable import/extensions */

export default function ComponentTests() {
Expand Down Expand Up @@ -221,6 +222,17 @@ export default function ComponentTests() {
<CustomParent />
<CustomParentAndChildren />
</div>
<div id="overrides">
<h2>Overrides</h2>
<ComponentWithNestedOverrides
id="componentWithNestedOverrides"
overrides={{
Flex: { backgroundColor: 'red' },
'Flex.Flex[2]': { backgroundColor: 'green' },
'Flex.Flex[1].Flex[0]': { backgroundColor: 'blue' },
}}
/>
</div>
</AmplifyProvider>
);
}
1 change: 1 addition & 0 deletions packages/test-generator/lib/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export * from './complex-tests';
export * from './collections';
export * from './custom';
export * from './operators';
export * from './overrides';
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"id": "1234-5678-9010",
"componentType": "Flex",
"name": "ComponentWithNestedOverrides",
"properties": {
"padding": {
"value": "10px"
}
},
"children": [
{
"name": "ChildFlex1",
"componentType": "Flex",
"properties": {
"id": {
"value": "ChildFlex1"
},
"children": {
"value": "ChildFlex1"
},
"padding": {
"value": "10px"
}
}
},
{
"name": "ChildFlex2",
"componentType": "Flex",
"properties": {
"id": {
"value": "ChildFlex2"
},
"padding": {
"value": "10px"
}
},
"children": [
{
"name": "ChildChildFlex1",
"componentType": "Flex",
"properties": {
"id": {
"value": "ChildChildFlex1"
},
"children": {
"value": "ChildChildFlex1"
},
"padding": {
"value": "10px"
}
}
},
{
"name": "ChildChildFlex2",
"componentType": "Flex",
"properties": {
"id": {
"value": "ChildChildFlex2"
},
"children": {
"value": "ChildChildFlex2"
},
"padding": {
"value": "10px"
}
}
}
]
},
{
"name": "ChildFlex3",
"componentType": "Flex",
"properties": {
"id": {
"value": "ChildFlex3"
},
"children": {
"value": "ChildFlex3"
},
"padding": {
"value": "10px"
}
}
}
]
}
16 changes: 16 additions & 0 deletions packages/test-generator/lib/components/overrides/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
export { default as ComponentWithNestedOverrides } from './componentWithNestedOverrides.json';

0 comments on commit c8500bf

Please sign in to comment.