Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: revert "fix: cannot create root construct in python" #2499

Merged
merged 3 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 2 additions & 25 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 0 additions & 12 deletions src/construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -465,18 +465,6 @@ export class Construct implements IConstruct {
return x && typeof x === 'object' && x[CONSTRUCT_SYM];
}

/**
* Creates a new root construct node.
*
* @param id The scoped construct ID. Must be unique amongst siblings. If
* the ID includes a path separator (`/`), then it will be replaced by double
* dash `--`.
*/
public static createRoot(id?: string): Construct {
return new Construct(undefined as any, id ?? '');
}


/**
* The tree node.
*/
Expand Down
72 changes: 36 additions & 36 deletions test/construct.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { Construct, ConstructOrder, DependencyGroup, Dependable, IConstruct } fr
// tslint:disable:max-line-length

test('the "Root" construct is a special construct which can be used as the root of the tree', () => {
const root = Construct.createRoot();
const root = new Root();
const node = root.node;
expect(node.id).toBe('');
expect(node.scope).toBeUndefined();
expect(node.children.length).toBe(0);
});

test('an empty string is a valid name for the root construct', () => {
const root = Construct.createRoot();
const root = new Root();
expect(root.node.id).toEqual('');

expect(() => new Construct(root, '')).toThrow(/Only root constructs/);
Expand All @@ -32,7 +32,7 @@ test('construct.name returns the name of the construct', () => {
});

test('construct id can use any character except the path separator', () => {
const root = Construct.createRoot();
const root = new Root();
expect(() => new Construct(root, 'valid')).not.toThrow();
expect(() => new Construct(root, 'ValiD')).not.toThrow();
expect(() => new Construct(root, 'Va123lid')).not.toThrow();
Expand All @@ -48,7 +48,7 @@ test('construct id can use any character except the path separator', () => {
});

test('if construct id contains path seperators, they will be replaced by double-dash', () => {
const root = Construct.createRoot();
const root = new Root();
const c = new Construct(root, 'Boom/Boom/Bam');
expect(c.node.id).toBe('Boom--Boom--Bam');
});
Expand All @@ -59,7 +59,7 @@ test('if "undefined" is forcefully used as an "id", it will be treated as an emp
});

test('node.addr returns an opaque app-unique address for any construct', () => {
const root = Construct.createRoot();
const root = new Root();

const child1 = new Construct(root, 'This is the first child');
const child2 = new Construct(child1, 'Second level');
Expand All @@ -76,7 +76,7 @@ test('node.addr returns an opaque app-unique address for any construct', () => {

test('node.addr excludes "default" from the address calculation', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
const c1 = new Construct(root, 'c1');

// WHEN:
Expand All @@ -97,23 +97,23 @@ test('node.addr excludes "default" from the address calculation', () => {
});

test('construct.getChildren() returns an array of all children', () => {
const root = Construct.createRoot();
const root = new Root();
const child = new Construct(root, 'Child1');
new Construct(root, 'Child2');
expect(child.node.children.length).toBe(0);
expect(root.node.children.length).toBe(2);
});

test('construct.findChild(name) can be used to retrieve a child from a parent', () => {
const root = Construct.createRoot();
const child = new Construct(root, 'Construct');
const root = new Root();
const child = new Construct(root, 'Contruct');
expect(root.node.tryFindChild(child.node.id)).toBe(child);
expect(root.node.tryFindChild('NotFound')).toBeUndefined();
});

test('construct.getChild(name) can be used to retrieve a child from a parent', () => {
const root = Construct.createRoot();
const child = new Construct(root, 'Construct');
const root = new Root();
const child = new Construct(root, 'Contruct');
expect(root.node.findChild(child.node.id)).toBe(child);
expect(() => root.node.findChild('NotFound')).toThrow(/No child with id: 'NotFound'/);
});
Expand Down Expand Up @@ -158,7 +158,7 @@ test('construct.getAllContext can be used to read the full context of a root nod
};

// WHEN
const t = Construct.createRoot();
const t = new Root();
for (const [k, v] of Object.entries(context)) {
t.node.setContext(k, v);
}
Expand Down Expand Up @@ -196,7 +196,7 @@ test('construct.tryGetContext(key) can be used to read a value from context defi

// tslint:disable-next-line:max-line-length
test('construct.setContext(k,v) sets context at some level and construct.tryGetContext(key) will return the lowermost value defined in the stack', () => {
const root = Construct.createRoot();
const root = new Root();
const highChild = new Construct(root, 'highChild');
highChild.node.setContext('c1', 'root');
highChild.node.setContext('c2', 'root');
Expand Down Expand Up @@ -229,7 +229,7 @@ test('construct.setContext(k,v) sets context at some level and construct.tryGetC
});

test('construct.setContext(key, value) can only be called before adding any children', () => {
const root = Construct.createRoot();
const root = new Root();
new Construct(root, 'child1');
expect(() => root.node.setContext('k', 'v')).toThrow(/Cannot set context after children have been added: child1/);
});
Expand Down Expand Up @@ -265,7 +265,7 @@ test('construct can not be created with the name of a sibling', () => {
});

test('addMetadata(type, data) can be used to attach metadata to constructs', () => {
const root = Construct.createRoot();
const root = new Root();
const con = new Construct(root, 'MyConstruct');
expect(con.node.metadata).toEqual([]);

Expand All @@ -285,7 +285,7 @@ test('addMetadata(type, data) can be used to attach metadata to constructs', ()
});

test('addMetadata() respects the "stackTrace" option', () => {
const root = Construct.createRoot();
const root = new Root();
const con = new Construct(root, 'Foo');

con.node.addMetadata('foo', 'bar1', { stackTrace: true });
Expand All @@ -297,7 +297,7 @@ test('addMetadata() respects the "stackTrace" option', () => {
});

test('addMetadata(type, undefined/null) is ignored', () => {
const root = Construct.createRoot();
const root = new Root();
const con = new Construct(root, 'Foo');
const node = con.node;
node.addMetadata('Null', null);
Expand All @@ -316,7 +316,7 @@ test('addMetadata(type, undefined/null) is ignored', () => {
});

test('multiple children of the same type, with explicit names are welcome', () => {
const root = Construct.createRoot();
const root = new Root();
new MyBeautifulConstruct(root, 'mbc1');
new MyBeautifulConstruct(root, 'mbc2');
new MyBeautifulConstruct(root, 'mbc3');
Expand Down Expand Up @@ -392,15 +392,15 @@ test('node.addValidation() can be implemented to perform validation, node.valida

test('node.validate() returns an empty array if the construct does not implement IValidation', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();

// THEN
expect(root.node.validate()).toStrictEqual([]);
});

test('node.addValidation() can be used to add a validation function to a construct', () => {
// GIVEN
const construct = Construct.createRoot();
const construct = new Root();
construct.node.addValidation({ validate: () => ['error1', 'error2'] });
construct.node.addValidation({ validate: () => ['error3'] });

Expand All @@ -409,7 +409,7 @@ test('node.addValidation() can be used to add a validation function to a constru

test('construct.lock() protects against adding children anywhere under this construct (direct or indirect)', () => {

const root = Construct.createRoot();
const root = new Root();

const c0a = new Construct(root, 'c0a');
const c0b = new Construct(root, 'c0b');
Expand Down Expand Up @@ -461,38 +461,38 @@ test('"root" returns the root construct', () => {

describe('defaultChild', () => {
test('returns the child with id "Resource"', () => {
const root = Construct.createRoot();
const root = new Root();
new Construct(root, 'child1');
const defaultChild = new Construct(root, 'Resource');
new Construct(root, 'child2');

expect(root.node.defaultChild).toBe(defaultChild);
});
test('returns the child with id "Default"', () => {
const root = Construct.createRoot();
const root = new Root();
new Construct(root, 'child1');
const defaultChild = new Construct(root, 'Default');
new Construct(root, 'child2');

expect(root.node.defaultChild).toBe(defaultChild);
});
test('can override defaultChild', () => {
const root = Construct.createRoot();
const root = new Root();
new Construct(root, 'Resource');
const defaultChild = new Construct(root, 'OtherResource');
root.node.defaultChild = defaultChild;

expect(root.node.defaultChild).toBe(defaultChild);
});
test('returns "undefined" if there is no default', () => {
const root = Construct.createRoot();
const root = new Root();
new Construct(root, 'child1');
new Construct(root, 'child2');

expect(root.node.defaultChild).toBeUndefined();
});
test('fails if there are both "Resource" and "Default"', () => {
const root = Construct.createRoot();
const root = new Root();
new Construct(root, 'child1');
new Construct(root, 'Default');
new Construct(root, 'child2');
Expand All @@ -507,7 +507,7 @@ describe('dependencies', () => {

test('addDependency() defines a dependency between two scopes', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
const consumer = new Construct(root, 'consumer');
const producer1 = new Construct(root, 'producer1');
const producer2 = new Construct(root, 'producer2');
Expand All @@ -522,7 +522,7 @@ describe('dependencies', () => {

test('are deduplicated', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
const consumer = new Construct(root, 'consumer');
const producer = new Construct(root, 'producer');

Expand All @@ -539,7 +539,7 @@ describe('dependencies', () => {

test('DependencyGroup can represent a group of disjoined producers', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
const group = new DependencyGroup(new Construct(root, 'producer1'), new Construct(root, 'producer2'));
const consumer = new Construct(root, 'consumer');

Expand All @@ -553,7 +553,7 @@ describe('dependencies', () => {

test('Dependable.implement() can be used to implement IDependable on any object', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
const producer = new Construct(root, 'producer');
const consumer = new Construct(root, 'consumer');

Expand All @@ -575,7 +575,7 @@ describe('dependencies', () => {

test('dependencyRoots are only resolved when node dependencies are evaluated', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
const c1 = new Construct(root, 'c1');
const c2 = new Construct(root, 'c2');
const c3 = new Construct(root, 'c3');
Expand All @@ -594,7 +594,7 @@ describe('dependencies', () => {

test('DependencyGroup can also include other IDependables', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
const c1 = new Construct(root, 'c1');

// WHEN
Expand All @@ -614,7 +614,7 @@ describe('dependencies', () => {

test('tryRemoveChild()', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
new Construct(root, 'child1');
new Construct(root, 'child2');

Expand All @@ -629,7 +629,7 @@ test('tryRemoveChild()', () => {

test('toString()', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
const child = new Construct(root, 'child');
const grand = new Construct(child, 'grand');

Expand All @@ -641,7 +641,7 @@ test('toString()', () => {

test('Construct.isConstruct returns true for constructs', () => {
// GIVEN
const root = Construct.createRoot();
const root = new Root();
class Subclass extends Construct {};
const subclass = new Subclass(root, 'subclass');
const someRandomObject = {};
Expand All @@ -659,7 +659,7 @@ test('Construct.isConstruct returns true for constructs', () => {
});

function createTree(context?: any) {
const root = Construct.createRoot();
const root = new Root();
const highChild = new Construct(root, 'HighChild');
if (context) {
Object.keys(context).forEach(key => highChild.node.setContext(key, context[key]));
Expand Down
Loading