Skip to content

Commit 7be7aed

Browse files
committed
Added default value to stateful parameters + tests. Removed un-used name property from stateless parameter options.
1 parent 79046e9 commit 7be7aed

3 files changed

Lines changed: 97 additions & 15 deletions

File tree

src/entities/resource-parameters.test.ts

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ import { TestConfig, TestResource } from './resource.test.js';
77
import { TransformParameter } from './transform-parameter.js';
88

99
class TestParameter extends StatefulParameter<TestConfig, string> {
10-
constructor(options?: StatefulParameterOptions<TestConfig>) {
11-
super(options ?? {
12-
name: 'propA'
13-
})
10+
constructor(options?: StatefulParameterOptions<string>) {
11+
super(options ?? {})
1412
}
1513

1614
applyAdd(valueToAdd: string, plan: Plan<TestConfig>): Promise<void> {
@@ -140,6 +138,51 @@ describe('Resource parameter tests', () => {
140138
expect(resourceSpy.applyModify.calledOnce).to.be.true;
141139
})
142140

141+
it('Allows stateful parameters to have default values', async () => {
142+
const statefulParameter = spy(new class extends TestParameter {
143+
constructor() {
144+
super({
145+
default: 'abc'
146+
});
147+
}
148+
149+
async refresh(): Promise<string | null> {
150+
return null;
151+
}
152+
});
153+
154+
const resource = new class extends TestResource {
155+
constructor() {
156+
super({
157+
type: 'resource',
158+
parameterOptions: {
159+
propA: { statefulParameter }
160+
},
161+
});
162+
}
163+
164+
async refresh(): Promise<any> {
165+
return null;
166+
}
167+
}
168+
169+
const plan = await resource.plan({
170+
type: 'resource',
171+
})
172+
173+
expect(statefulParameter.refresh.notCalled).to.be.true;
174+
expect(plan.currentConfig).toMatchObject({
175+
type: 'resource',
176+
propA: null,
177+
})
178+
expect(plan.desiredConfig).toMatchObject({
179+
type: 'resource',
180+
propA: 'abc',
181+
})
182+
expect(plan.changeSet.operation).to.eq(ResourceOperation.CREATE);
183+
})
184+
185+
143186
it('Filters array results in stateless mode to prevent modify from being called', async () => {
144187
const statefulParameter = new class extends TestParameter {
145188
async refresh(): Promise<any | null> {
@@ -210,7 +253,6 @@ describe('Resource parameter tests', () => {
210253
const statefulParameter = new class extends ArrayStatefulParameter<TestConfig, string> {
211254
constructor() {
212255
super({
213-
name: 'propA',
214256
isElementEqual: (desired, current) => current.includes(desired),
215257
});
216258
}
@@ -531,4 +573,44 @@ describe('Resource parameter tests', () => {
531573
expect(plan.desiredConfig.propE).to.be.lessThan(plan.desiredConfig.propF as any);
532574
expect(plan.desiredConfig.propF).to.be.lessThan(plan.desiredConfig.propD as any);
533575
})
576+
577+
it('Plans transform even for creating new resources', async () => {
578+
const transformParameterA = spy(new class extends TransformParameter<TestConfig> {
579+
async transform(value: any): Promise<Partial<TestConfig>> {
580+
return { propD: 'abc', propE: 10 }
581+
}
582+
});
583+
584+
const resource = spy(new class extends TestResource {
585+
constructor() {
586+
super({
587+
type: 'resourceType',
588+
parameterOptions: {
589+
propA: { transformParameter: transformParameterA },
590+
},
591+
});
592+
}
593+
594+
async refresh(): Promise<Partial<TestConfig> | null> {
595+
return null;
596+
}
597+
});
598+
599+
const plan = await resource.plan({
600+
type: 'resourceType',
601+
propA: 'propA',
602+
propB: 10,
603+
propC: 'propC',
604+
});
605+
expect(plan.currentConfig).toMatchObject({
606+
type: 'resourceType',
607+
propD: null,
608+
propE: null,
609+
})
610+
expect(plan.desiredConfig).toMatchObject({
611+
type: 'resourceType',
612+
propD: 'abc',
613+
propE: 10,
614+
})
615+
})
534616
})

src/entities/resource.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ export abstract class Resource<T extends StringIndexedObject> {
9595
transformParameters,
9696
} = parsedConfig;
9797

98+
// Apply transform parameters. Transform parameters turn into other parameters.
99+
// Ex: csvFile: './location' => { password: 'pass', 'username': 'user' }
98100
await this.applyTransformParameters(transformParameters, resourceParameters);
99101

100102
// Refresh resource parameters. This refreshes the parameters that configure the resource itself

src/entities/stateful-parameter.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { Plan } from './plan.js';
22
import { StringIndexedObject } from 'codify-schemas';
33

4-
export interface StatefulParameterOptions<T> {
5-
name: keyof T;
4+
export interface StatefulParameterOptions<V> {
65
isEqual?: (desired: any, current: any) => boolean;
76

87
/**
@@ -15,20 +14,19 @@ export interface StatefulParameterOptions<T> {
1514
* Set this flag to true to disable this behaviour
1615
*/
1716
disableStatelessModeArrayFiltering?: boolean;
17+
default?: V;
1818
}
1919

20-
export interface ArrayStatefulParameterOptions<T> extends StatefulParameterOptions<T> {
20+
export interface ArrayStatefulParameterOptions<V> extends StatefulParameterOptions<V> {
2121
isEqual?: (desired: any[], current: any[]) => boolean;
2222
isElementEqual?: (desired: any, current: any) => boolean;
2323
}
2424

2525

2626
export abstract class StatefulParameter<T extends StringIndexedObject, V extends T[keyof T]> {
27-
readonly name: keyof T;
28-
readonly options: StatefulParameterOptions<T>;
27+
readonly options: StatefulParameterOptions<V>;
2928

30-
protected constructor(options: StatefulParameterOptions<T>) {
31-
this.name = options.name;
29+
protected constructor(options: StatefulParameterOptions<V>) {
3230
this.options = options
3331
}
3432

@@ -41,9 +39,9 @@ export abstract class StatefulParameter<T extends StringIndexedObject, V extends
4139
}
4240

4341
export abstract class ArrayStatefulParameter<T extends StringIndexedObject, V> extends StatefulParameter<T, any>{
44-
options: ArrayStatefulParameterOptions<T>;
42+
options: ArrayStatefulParameterOptions<V>;
4543

46-
constructor(options: ArrayStatefulParameterOptions<T>) {
44+
constructor(options: ArrayStatefulParameterOptions<V>) {
4745
super(options);
4846
this.options = options;
4947
}
@@ -55,7 +53,7 @@ export abstract class ArrayStatefulParameter<T extends StringIndexedObject, V> e
5553
}
5654

5755
async applyModify(newValues: V[], previousValues: V[], allowDeletes: boolean, plan: Plan<T>): Promise<void> {
58-
const options = this.options as ArrayStatefulParameterOptions<T>;
56+
const options = this.options as ArrayStatefulParameterOptions<V>;
5957

6058
const valuesToAdd = newValues.filter((n) => !previousValues.some((p) => {
6159
if (options.isElementEqual) {

0 commit comments

Comments
 (0)