diff --git a/src/TerraformGenerator.ts b/src/TerraformGenerator.ts index e49bff6..a65dd32 100644 --- a/src/TerraformGenerator.ts +++ b/src/TerraformGenerator.ts @@ -3,7 +3,7 @@ import fs from 'fs'; import path from 'path'; import shell from 'shelljs'; import { Block, Comment, Resource, Data, Module, Output, Provider, Variable, Backend, Provisioner, ResourceToDataOptions, Locals, Import, ImportArgs, VariableArgs, ModuleArgs, OutputArgs } from './blocks'; -import { BlockArgs, Util } from './utils'; +import { TerraformArgs, Util } from './utils'; /** * @category TerraformGenerator @@ -42,9 +42,9 @@ export interface WriteOptions { */ export class TerraformGenerator { - readonly #arguments?: BlockArgs; + readonly #arguments?: TerraformArgs; readonly #blocks: Block[] = []; - #variables: BlockArgs = {}; + #variables: TerraformArgs = {}; /** * Construct Terraform generator. @@ -53,7 +53,7 @@ export class TerraformGenerator { * * @param args arguments */ - constructor(args?: BlockArgs) { + constructor(args?: TerraformArgs) { this.#arguments = args; } @@ -170,7 +170,7 @@ export class TerraformGenerator { * @param type type * @param args arguments */ - provider(type: string, args: BlockArgs): Provider { + provider(type: string, args: TerraformArgs): Provider { const block = new Provider(type, args); this.addBlocks(block); return block; @@ -186,7 +186,7 @@ export class TerraformGenerator { * @param args arguments * @param provisioners provisioners */ - resource(type: string, name: string, args: BlockArgs, provisioners?: Provisioner[]): Resource { + resource(type: string, name: string, args: TerraformArgs, provisioners?: Provisioner[]): Resource { const block = new Resource(type, name, args, provisioners); this.addBlocks(block); return block; @@ -201,7 +201,8 @@ export class TerraformGenerator { * use array for name mapping, position 0 = original resource's argument name, position 1 = mapped data source's argument name * @param args extra arguments */ - dataFromResource(resource: Resource, options: ResourceToDataOptions | undefined, argNames: (string | [string, string])[], args?: BlockArgs): Data { + dataFromResource( + resource: Resource, options: ResourceToDataOptions | undefined, argNames: (string | [string, string])[], args?: TerraformArgs): Data { const block = resource.toData(options, argNames, args); this.addBlocks(block); return block; @@ -216,7 +217,7 @@ export class TerraformGenerator { * @param name name * @param args arguments */ - data(type: string, name: string, args: BlockArgs): Data { + data(type: string, name: string, args: TerraformArgs): Data { const block = new Data(type, name, args); this.addBlocks(block); return block; @@ -257,7 +258,7 @@ export class TerraformGenerator { * * @param args arguments */ - locals(args: BlockArgs): Locals { + locals(args: TerraformArgs): Locals { const block = new Locals(args); this.addBlocks(block); return block; @@ -302,7 +303,7 @@ export class TerraformGenerator { * @param type type * @param args arguments */ - backend(type: string, args: BlockArgs): Backend { + backend(type: string, args: TerraformArgs): Backend { const block = new Backend(type, args); this.addBlocks(block); return block; @@ -313,7 +314,7 @@ export class TerraformGenerator { * * @param variables variables */ - addVars(variables: BlockArgs): this { + addVars(variables: TerraformArgs): this { this.#variables = { ...this.#variables, ...variables @@ -337,7 +338,7 @@ export class TerraformGenerator { /** * Get arguments. */ - getArguments(): BlockArgs | undefined { + getArguments(): TerraformArgs | undefined { return this.#arguments; } @@ -351,7 +352,7 @@ export class TerraformGenerator { /** * Get variables. */ - getVars(): BlockArgs { + getVars(): TerraformArgs { return this.#variables; } diff --git a/src/arguments/Argument.ts b/src/arguments/Argument.ts index 6239c57..758f62b 100644 --- a/src/arguments/Argument.ts +++ b/src/arguments/Argument.ts @@ -1,23 +1,26 @@ -import { Util } from '../utils'; +import { TerraformElement, Util } from '../utils'; /** * @category Argument */ -export class Argument> { +export class Argument extends TerraformElement { - readonly argument: T; + readonly #argument: T; /** * Construct argument. * * @param arg argument as string or copy from another argument object + * @param escape escape the value */ constructor(arg: T) { + super(); + if (!arg || (typeof arg === 'string' && !arg.trim())) { - throw new Error('Argument cannot be empty.'); + throw new Error('Argument cannot be undefined.'); } - this.argument = arg; + this.#argument = arg; } /** @@ -26,11 +29,7 @@ export class Argument> { * @param name attribute name */ attr(name: string): Argument { - name = name.trim(); - if (this.argument instanceof Argument) { - return this.argument.attr(name); - } - return new Argument(`${this.argument}.${name}`); + return new Argument(`${this.#argument}.${name.trim()}`); } /** @@ -39,10 +38,7 @@ export class Argument> { * @param idx element index */ element(idx: number): Argument { - if (this.argument instanceof Argument) { - return this.argument.element(idx); - } - return new Argument(`${this.argument}[${idx}]`); + return new Argument(`${this.#argument}[${idx}]`); } /** @@ -50,14 +46,8 @@ export class Argument> { * * Use this method when argument is used as an interpolation in another Terraform argument or code. */ - toTerraform(): string { - let str = ''; - if (this.argument instanceof Argument) { - str += this.argument.toTerraform(); - } else { - str += this.argument; - } - return Util.escape(str); + override toTerraform(): string { + return Util.escape(this.#argument); } /** @@ -80,4 +70,4 @@ export class Argument> { * * @category Argument */ -export const arg = >(arg: T): Argument => new Argument(arg); +export const arg = (arg: T): Argument => new Argument(arg); diff --git a/src/arguments/Attribute.ts b/src/arguments/Attribute.ts index 0a3a85d..4e74fd4 100644 --- a/src/arguments/Attribute.ts +++ b/src/arguments/Attribute.ts @@ -18,10 +18,10 @@ export class Attribute extends Argument { static #constructArgument(block: Block, attrName: string): string { if (!block) { - throw new Error('Attribute block cannot be null.'); + throw new Error('Attribute block cannot be undefined.'); } if (!attrName?.trim()) { - throw new Error('Attribute name cannot be empty.'); + throw new Error('Attribute name cannot be undefined.'); } return `${block.asArgument().toTerraform()}.${attrName.trim()}`; diff --git a/src/arguments/Function.ts b/src/arguments/Function.ts index 528c691..d0bb445 100644 --- a/src/arguments/Function.ts +++ b/src/arguments/Function.ts @@ -18,7 +18,7 @@ export class Function extends Argument { static #constructArgument(fn: string, ...args: any[]): string { if (!fn.trim()) { - throw new Error('Function name cannot be empty.'); + throw new Error('Function name cannot be undefined.'); } if (args.filter(arg => arg == null).length > 0) { throw new Error(`Invalid function argument: ${args}`); diff --git a/src/arguments/List.ts b/src/arguments/List.ts new file mode 100644 index 0000000..64550a0 --- /dev/null +++ b/src/arguments/List.ts @@ -0,0 +1,36 @@ +import { Util } from '../utils'; +import { Argument } from '.'; + +/** + * @category Argument + */ +export class List extends Argument { + + /** + * Construct list. + * + * @param elements list elements + */ + constructor(...elements: any[]) { + super(List.#constructArgument(elements)); + } + + static #constructArgument(elements: any[]): string { + let str = '[\n'; + elements.forEach((element, i) => { + str += `${Util.argumentValueToString(element)}${i < elements.length - 1 ? ',' : ''}\n`; + }); + str += ']'; + return str; + } + +} + +/** + * Convenient function to construct new [[List]]. + * + * @param elements list elements + * + * @category Argument + */ +export const list = (...elements: any[]): List => new List(...elements); diff --git a/src/arguments/Map.ts b/src/arguments/Map.ts new file mode 100644 index 0000000..c842663 --- /dev/null +++ b/src/arguments/Map.ts @@ -0,0 +1,34 @@ +import { TerraformArgs, Util } from '../utils'; +import { Argument } from '.'; + +/** + * @category Argument + */ +export class Map extends Argument { + + readonly arguments: TerraformArgs; + + /** + * Construct map. + * + * @param args map values + */ + constructor(args: TerraformArgs) { + super(Map.#constructArgument(args)); + this.arguments = args; + } + + static #constructArgument(args: TerraformArgs): string { + return Util.argumentValueToString(args)!; + } + +} + +/** + * Convenient function to construct new [[Map]]. + * + * @param args map values + * + * @category Argument + */ +export const map = (args: TerraformArgs): Map => new Map(args); diff --git a/src/arguments/index.ts b/src/arguments/index.ts index 5861959..f6514bc 100644 --- a/src/arguments/index.ts +++ b/src/arguments/index.ts @@ -2,3 +2,5 @@ export * from './Argument'; export * from './Attribute'; export * from './Function'; export * from './Heredoc'; +export * from './List'; +export * from './Map'; diff --git a/src/blocks/Backend.ts b/src/blocks/Backend.ts index 22392b8..6f5b9ae 100644 --- a/src/blocks/Backend.ts +++ b/src/blocks/Backend.ts @@ -1,5 +1,5 @@ import { Argument, Attribute } from '../arguments'; -import { BlockArgs } from '../utils'; +import { TerraformArgs, Util } from '../utils'; import { Block } from '.'; /** @@ -17,7 +17,7 @@ export class Backend extends Block { * @param type type * @param args arguments */ - constructor(type: string, args: BlockArgs) { + constructor(type: string, args: TerraformArgs) { super('backend', [type], args, undefined, true); this.type = type; @@ -28,7 +28,7 @@ export class Backend extends Block { } override attr(_name: string): Attribute { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } } diff --git a/src/blocks/Block.ts b/src/blocks/Block.ts index c92cdd9..d51a143 100644 --- a/src/blocks/Block.ts +++ b/src/blocks/Block.ts @@ -1,10 +1,10 @@ import { Argument, Attribute } from '../arguments'; -import { BlockArgs, Util } from '../utils'; +import { TerraformArgs, TerraformElement, Util } from '../utils'; /** * @category Block */ -export abstract class Block { +export abstract class Block extends TerraformElement { readonly blockType: string; readonly blockNames: string[]; @@ -20,6 +20,8 @@ export abstract class Block { * @param args arguments */ constructor(type: string, names: string[], args: Args, innerBlocks?: Block[], insideTerraformBlock = false) { + super(); + this.#validateIdentifier(type); names.forEach(name => { this.#validateIdentifier(name); @@ -104,10 +106,7 @@ export abstract class Block { return this; } - /** - * To Terraform representation. - */ - toTerraform(): string { + override toTerraform(): string { let str = this.blockType; this.blockNames.forEach(name => { str += ` "${name}"`; diff --git a/src/blocks/Comment.ts b/src/blocks/Comment.ts index 5174d30..1c69bd6 100644 --- a/src/blocks/Comment.ts +++ b/src/blocks/Comment.ts @@ -1,4 +1,5 @@ import { Argument, Attribute } from '../arguments'; +import { Util } from '../utils'; import { Block } from '.'; /** @@ -24,11 +25,11 @@ export class Comment extends Block> { } override asArgument(): Argument { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } override attr(_name: string): Attribute { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } } diff --git a/src/blocks/Data.ts b/src/blocks/Data.ts index 7e4d041..8fbf369 100644 --- a/src/blocks/Data.ts +++ b/src/blocks/Data.ts @@ -1,5 +1,5 @@ import { Argument, Attribute } from '../arguments'; -import { BlockArgs } from '../utils'; +import { TerraformArgs } from '../utils'; import { Block } from '.'; /** @@ -19,7 +19,7 @@ export class Data extends Block { * @param name name * @param args arguments */ - constructor(type: string, name: string, args: BlockArgs) { + constructor(type: string, name: string, args: TerraformArgs) { super('data', [type, name], args); this.type = type; diff --git a/src/blocks/Import.ts b/src/blocks/Import.ts index 06ddfa8..d944079 100644 --- a/src/blocks/Import.ts +++ b/src/blocks/Import.ts @@ -1,4 +1,5 @@ import { Argument, Attribute } from '../arguments'; +import { Util } from '../utils'; import { Block, Resource } from '.'; /** @@ -27,11 +28,11 @@ export class Import extends Block { } override asArgument(): Argument { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } override attr(_name: string): Attribute { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } } diff --git a/src/blocks/Locals.ts b/src/blocks/Locals.ts index 94750ef..0487e14 100644 --- a/src/blocks/Locals.ts +++ b/src/blocks/Locals.ts @@ -1,5 +1,5 @@ import { Argument, Attribute } from '../arguments'; -import { BlockArgs } from '../utils'; +import { TerraformArgs, Util } from '../utils'; import { Block } from '.'; /** @@ -14,16 +14,16 @@ export class Locals extends Block { * * @param args arguments */ - constructor(args: BlockArgs) { + constructor(args: TerraformArgs) { super('locals', [], args); } override asArgument(): Argument { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } override attr(_name: string): Attribute { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } arg(name: string): Argument { diff --git a/src/blocks/Module.ts b/src/blocks/Module.ts index a0fde91..df951e8 100644 --- a/src/blocks/Module.ts +++ b/src/blocks/Module.ts @@ -1,11 +1,11 @@ import { Argument, Attribute } from '../arguments'; -import { BlockArgs } from '../utils'; +import { TerraformArgs } from '../utils'; import { Block } from '.'; /** * @category Block */ -export interface ModuleArgs extends BlockArgs { +export interface ModuleArgs extends TerraformArgs { source: string; version?: string; } diff --git a/src/blocks/Output.ts b/src/blocks/Output.ts index a0f9a61..57ad66f 100644 --- a/src/blocks/Output.ts +++ b/src/blocks/Output.ts @@ -1,5 +1,5 @@ import { Argument, Attribute } from '../arguments'; -import { BlockArgs } from '../utils'; +import { TerraformArgs, Util } from '../utils'; import { Block, Resource } from '.'; /** @@ -9,7 +9,7 @@ export interface OutputArgs { value: any; description?: string; sensitive?: boolean; - precondition?: BlockArgs; + precondition?: TerraformArgs; depends_on?: Resource[]; } @@ -35,11 +35,11 @@ export class Output extends Block { } override asArgument(): Argument { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } override attr(_name: string): Attribute { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } } diff --git a/src/blocks/Provider.ts b/src/blocks/Provider.ts index 7869469..2f02063 100644 --- a/src/blocks/Provider.ts +++ b/src/blocks/Provider.ts @@ -1,5 +1,5 @@ import { Argument, Attribute } from '../arguments'; -import { BlockArgs } from '../utils'; +import { TerraformArgs, Util } from '../utils'; import { Block } from '.'; /** @@ -17,7 +17,7 @@ export class Provider extends Block { * @param type type * @param args arguments */ - constructor(type: string, args: BlockArgs) { + constructor(type: string, args: TerraformArgs) { super('provider', [type], args); this.type = type; @@ -31,7 +31,7 @@ export class Provider extends Block { } override attr(_name: string): Attribute { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } } diff --git a/src/blocks/Provisioner.ts b/src/blocks/Provisioner.ts index c6ac669..1a5b4af 100644 --- a/src/blocks/Provisioner.ts +++ b/src/blocks/Provisioner.ts @@ -1,4 +1,5 @@ import { Argument, Attribute } from '../arguments'; +import { Util } from '../utils'; import { Block } from '.'; /** @@ -37,11 +38,11 @@ export class Provisioner extends Block { } override asArgument(): Argument { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } override attr(_name: string): Attribute { - throw new Error('Inaccessible method.'); + throw Util.inaccessibleMethod(); } } diff --git a/src/blocks/Resource.ts b/src/blocks/Resource.ts index daf81dd..dd8f74e 100644 --- a/src/blocks/Resource.ts +++ b/src/blocks/Resource.ts @@ -1,6 +1,5 @@ -import { Argument, Attribute } from '../arguments'; -import { Map } from '../types'; -import { BlockArgs } from '../utils'; +import { Argument, Attribute, Map } from '../arguments'; +import { TerraformArgs } from '../utils'; import { Block, Data, Provisioner } from '.'; /** @@ -35,7 +34,7 @@ export class Resource extends Block { * @param args arguments * @param provisioners provisioners */ - constructor(type: string, name: string, args?: BlockArgs, provisioners?: Provisioner[]) { + constructor(type: string, name: string, args?: TerraformArgs, provisioners?: Provisioner[]) { super('resource', [type, name], args || {}, provisioners); this.type = type; @@ -75,7 +74,7 @@ export class Resource extends Block { * use array for name mapping, position 0 = original resource's argument name, position 1 = mapped data source's argument name * @param args extra arguments */ - toData(options: ResourceToDataOptions | undefined, argNames: (string | [string, string])[], args?: BlockArgs): Data { + toData(options: ResourceToDataOptions | undefined, argNames: (string | [string, string])[], args?: TerraformArgs): Data { const type = options?.type ?? this.type; const name = options?.name ?? this.name; diff --git a/src/blocks/Variable.ts b/src/blocks/Variable.ts index ea9f391..568572f 100644 --- a/src/blocks/Variable.ts +++ b/src/blocks/Variable.ts @@ -1,5 +1,5 @@ import { Argument, Attribute } from '../arguments'; -import { BlockArgs } from '../utils'; +import { TerraformArgs } from '../utils'; import { Block } from '.'; /** @@ -11,7 +11,7 @@ export interface VariableArgs { description?: string; sensitive?: boolean; nullable?: boolean; - validation?: BlockArgs; + validation?: TerraformArgs; } /** diff --git a/src/index.ts b/src/index.ts index 8ce696c..d776dad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -export { BlockArgs } from './utils'; +export { TerraformElement, TerraformArgs } from './utils'; export { TerraformGenerator, WriteOptions } from './TerraformGenerator'; @@ -21,10 +21,7 @@ export { Argument, arg, Attribute, attr, Function, fn, - Heredoc, heredoc -} from './arguments'; - -export { + Heredoc, heredoc, List, list, Map, map -} from './types'; +} from './arguments'; diff --git a/src/types/List.ts b/src/types/List.ts deleted file mode 100644 index b3db5d6..0000000 --- a/src/types/List.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @category Type - */ -export class List { - - readonly elements: any[]; - - /** - * Construct list. - * - * @param elements list elements - */ - constructor(...elements: any[]) { - this.elements = elements; - } - -} - -/** - * Convenient function to construct new [[List]]. - * - * @param elements list elements - * - * @category Type - */ -export const list = (...elements: any[]): List => new List(...elements); diff --git a/src/types/Map.ts b/src/types/Map.ts deleted file mode 100644 index 7103d7b..0000000 --- a/src/types/Map.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { BlockArgs } from '../utils'; - -/** - * @category Type - */ -export class Map { - - readonly arguments: BlockArgs; - - /** - * Construct map. - * - * @param args map values - */ - constructor(args: BlockArgs) { - this.arguments = args; - } - -} - -/** - * Convenient function to construct new [[Map]]. - * - * @param args map values - * - * @category Type - */ -export const map = (args: BlockArgs): Map => new Map(args); diff --git a/src/types/index.ts b/src/types/index.ts deleted file mode 100644 index b47dd0f..0000000 --- a/src/types/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './List'; -export * from './Map'; diff --git a/src/utils/TerraformElement.ts b/src/utils/TerraformElement.ts new file mode 100644 index 0000000..01109fb --- /dev/null +++ b/src/utils/TerraformElement.ts @@ -0,0 +1,8 @@ +export abstract class TerraformElement { + + /** + * To Terraform representation. + */ + abstract toTerraform(): string; + +} diff --git a/src/utils/Util.ts b/src/utils/Util.ts index be25161..608fb0d 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -1,7 +1,5 @@ -import { Argument } from '../arguments'; import { Block } from '../blocks'; -import { Map, List } from '../types'; -import { BlockArgs } from '.'; +import { TerraformArgs, TerraformElement } from '.'; export class Util { @@ -23,7 +21,7 @@ export class Util { return str; } - static argumentsToString(args?: BlockArgs): string { + static argumentsToString(args?: TerraformArgs): string { let str = ''; for (const key in args) { str += this.argumentToString(key, args[key]); @@ -32,9 +30,7 @@ export class Util { } static isObjectArgument(value: any): boolean { - if (['string', 'number', 'boolean'].indexOf(typeof value) >= 0 || - value instanceof Block || value instanceof Argument || - value instanceof Map || value instanceof List) { + if (['string', 'number', 'boolean'].indexOf(typeof value) >= 0 || value instanceof TerraformElement) { return false; } if (typeof value === 'object') { @@ -90,26 +86,13 @@ export class Util { } if (value instanceof Block) { - return this.argumentValueToString(value.asArgument()); + return value.asArgument().toTerraform(); } - if (value instanceof Argument) { + if (value instanceof TerraformElement) { return value.toTerraform(); } - if (value instanceof Map) { - return this.argumentValueToString(value.arguments); - } - - if (value instanceof List) { - let str = '[\n'; - value.elements.forEach((element, i) => { - str += `${this.argumentValueToString(element)}${i < value.elements.length - 1 ? ',' : ''}\n`; - }); - str += ']'; - return str; - } - if (['string', 'number', 'boolean'].indexOf(typeof value) >= 0) { return JSON.stringify(value); } @@ -135,4 +118,8 @@ export class Util { throw new Error(`Invalid value: ${value}`); } + static inaccessibleMethod() { + return new Error('Inaccessible method.'); + } + } diff --git a/src/utils/index.ts b/src/utils/index.ts index e9770d8..0f1f502 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,2 +1,3 @@ export * from './types'; +export * from './TerraformElement'; export * from './Util'; diff --git a/src/utils/types.ts b/src/utils/types.ts index 669fcce..2f79209 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -1 +1 @@ -export type BlockArgs = Record; +export type TerraformArgs = Record; diff --git a/test/arguments/Argument.test.ts b/test/arguments/Argument.test.ts index 5465964..b9aced5 100644 --- a/test/arguments/Argument.test.ts +++ b/test/arguments/Argument.test.ts @@ -1,32 +1,30 @@ import { attr } from '..'; import { Argument, arg } from '../../src/arguments'; -import { Util } from '../../src/utils'; test('Argument invalid args', () => { expect(() => new Argument(null as unknown as string)).toThrow(); }); test('Argument', () => { - expect(new Argument('x').toTerraform()).toBe(Util.escape('x')); - expect(new Argument(attr).toTerraform()).toBe(Util.escape('type.name.attr')); + expect(new Argument('x').toTerraform()).toMatchSnapshot(); }); test('arg', () => { - expect(arg('x').toTerraform()).toBe(Util.escape('x')); - expect(arg(attr).toTerraform()).toBe(Util.escape('type.name.attr')); + expect(arg('x').toTerraform()).toMatchSnapshot(); + expect(attr.toTerraform()).toMatchSnapshot(); }); test('.attr', () => { - expect(arg('x').attr('y').toTerraform()).toBe(Util.escape('x.y')); - expect(arg(attr).attr('y').toTerraform()).toBe(Util.escape('type.name.attr.y')); + expect(arg('x').attr('y').toTerraform()).toMatchSnapshot(); + expect(attr.attr('y').toTerraform()).toMatchSnapshot(); }); test('.element', () => { - expect(arg('x').element(0).toTerraform()).toBe(Util.escape('x[0]')); - expect(arg(attr).element(0).toTerraform()).toBe(Util.escape('type.name.attr[0]')); + expect(arg('x').element(0).toTerraform()).toMatchSnapshot(); + expect(attr.element(0).toTerraform()).toMatchSnapshot(); }); test('interpolation', () => { - expect(`prefix-${arg('x')}-suffix`).toBe(Util.escape('prefix-${x}-suffix')); - expect(`prefix-${arg(attr)}-suffix`).toBe(Util.escape('prefix-${type.name.attr}-suffix')); + expect(`prefix-${arg('x')}-suffix`).toMatchSnapshot(); + expect(`prefix-${attr}-suffix`).toMatchSnapshot(); }); diff --git a/test/arguments/Attribute.test.ts b/test/arguments/Attribute.test.ts index 0931f14..1da0e1f 100644 --- a/test/arguments/Attribute.test.ts +++ b/test/arguments/Attribute.test.ts @@ -1,7 +1,6 @@ import { resource } from '..'; import { Attribute, attr } from '../../src/arguments'; import { Block } from '../../src/blocks'; -import { Util } from '../../src/utils'; test('Attribute invalid args', () => { expect(() => new Attribute(null as unknown as Block, null as unknown as string)).toThrow(); @@ -12,9 +11,9 @@ test('Attribute invalid args', () => { }); test('Attribute', () => { - expect(new Attribute(resource, 'x').toTerraform()).toBe(Util.escape('type.name.x')); + expect(new Attribute(resource, 'x').toTerraform()).toMatchSnapshot(); }); test('attr', () => { - expect(attr(resource, 'x').toTerraform()).toBe(Util.escape('type.name.x')); + expect(attr(resource, 'x').toTerraform()).toMatchSnapshot(); }); diff --git a/test/arguments/Function.test.ts b/test/arguments/Function.test.ts index 3b2e968..710f639 100644 --- a/test/arguments/Function.test.ts +++ b/test/arguments/Function.test.ts @@ -1,6 +1,5 @@ import { attr } from '..'; import { Function, fn } from '../../src/arguments'; -import { Util } from '../../src/utils'; test('Function invalid args', () => { expect(() => new Function(null as unknown as string)).toThrow(); @@ -8,21 +7,21 @@ test('Function invalid args', () => { }); test('Function', () => { - expect(new Function('fn').toTerraform()).toBe(Util.escape('fn()')); - expect(new Function('fn', 'x', 'y', 'z').toTerraform()).toBe(Util.escape('fn("x", "y", "z")')); - expect(new Function('fn', 1, 2, 3).toTerraform()).toBe(Util.escape('fn(1, 2, 3)')); - expect(new Function('fn', true, false, true).toTerraform()).toBe(Util.escape('fn(true, false, true)')); - expect(new Function('fn', 'x', 2, true).toTerraform()).toBe(Util.escape('fn("x", 2, true)')); - expect(new Function('fn', 'x', attr).toTerraform()).toBe(Util.escape('fn("x", type.name.attr)')); - expect(new Function('fn', 'x', { a: 1, b: '2' }).toTerraform()).toBe(Util.escape('fn("x", {\na = 1\nb = "2"\n})')); + expect(new Function('fn').toTerraform()).toMatchSnapshot(); + expect(new Function('fn', 'x', 'y', 'z').toTerraform()).toMatchSnapshot(); + expect(new Function('fn', 1, 2, 3).toTerraform()).toMatchSnapshot(); + expect(new Function('fn', true, false, true).toTerraform()).toMatchSnapshot(); + expect(new Function('fn', 'x', 2, true).toTerraform()).toMatchSnapshot(); + expect(new Function('fn', 'x', attr).toTerraform()).toMatchSnapshot(); + expect(new Function('fn', 'x', { a: 1, b: '2' }).toTerraform()).toMatchSnapshot(); }); test('fn', () => { - expect(fn('fn').toTerraform()).toBe(Util.escape('fn()')); - expect(fn('fn', 'x', 'y', 'z').toTerraform()).toBe(Util.escape('fn("x", "y", "z")')); - expect(fn('fn', 1, 2, 3).toTerraform()).toBe(Util.escape('fn(1, 2, 3)')); - expect(fn('fn', true, false, true).toTerraform()).toBe(Util.escape('fn(true, false, true)')); - expect(fn('fn', 'x', 2, true).toTerraform()).toBe(Util.escape('fn("x", 2, true)')); - expect(fn('fn', 'x', attr).toTerraform()).toBe(Util.escape('fn("x", type.name.attr)')); - expect(fn('fn', 'x', { a: 1, b: '2' }).toTerraform()).toBe(Util.escape('fn("x", {\na = 1\nb = "2"\n})')); + expect(fn('fn').toTerraform()).toMatchSnapshot(); + expect(fn('fn', 'x', 'y', 'z').toTerraform()).toMatchSnapshot(); + expect(fn('fn', 1, 2, 3).toTerraform()).toMatchSnapshot(); + expect(fn('fn', true, false, true).toTerraform()).toMatchSnapshot(); + expect(fn('fn', 'x', 2, true).toTerraform()).toMatchSnapshot(); + expect(fn('fn', 'x', attr).toTerraform()).toMatchSnapshot(); + expect(fn('fn', 'x', { a: 1, b: '2' }).toTerraform()).toMatchSnapshot(); }); diff --git a/test/arguments/Heredoc.test.ts b/test/arguments/Heredoc.test.ts index fb80492..51886f7 100644 --- a/test/arguments/Heredoc.test.ts +++ b/test/arguments/Heredoc.test.ts @@ -1,28 +1,11 @@ import { Heredoc, heredoc } from '../../src/arguments'; -import { Util } from '../../src/utils'; test('Heredoc', () => { - expect(new Heredoc('x').toTerraform()).toBe(Util.escape(`< { - expect(heredoc('x').toTerraform()).toBe(Util.escape(`< { + expect(new List('x', 'y', 'z').toTerraform()).toMatchSnapshot(); + expect(new List(1, 2, 3).toTerraform()).toMatchSnapshot(); + expect(new List(true, false, true).toTerraform()).toMatchSnapshot(); + expect(new List('x', 2, true).toTerraform()).toMatchSnapshot(); + expect(new List(arg1, arg2, arg3, arg4).toTerraform()).toMatchSnapshot(); +}); + +test('list', () => { + expect(list('x', 'y', 'z').toTerraform()).toMatchSnapshot(); + expect(list(1, 2, 3).toTerraform()).toMatchSnapshot(); + expect(list(true, false, true).toTerraform()).toMatchSnapshot(); + expect(list('x', 2, true).toTerraform()).toMatchSnapshot(); + expect(list(arg1, arg2, arg3, arg4).toTerraform()).toMatchSnapshot(); +}); diff --git a/test/arguments/Map.test.ts b/test/arguments/Map.test.ts new file mode 100644 index 0000000..cfca48b --- /dev/null +++ b/test/arguments/Map.test.ts @@ -0,0 +1,10 @@ +import { arg4 } from '..'; +import { Map, map } from '../../src/arguments'; + +test('Map', () => { + expect(new Map(arg4).toTerraform()).toMatchSnapshot(); +}); + +test('list', () => { + expect(map(arg4).toTerraform()).toMatchSnapshot(); +}); diff --git a/test/arguments/__snapshots__/Argument.test.ts.snap b/test/arguments/__snapshots__/Argument.test.ts.snap new file mode 100644 index 0000000..162153a --- /dev/null +++ b/test/arguments/__snapshots__/Argument.test.ts.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`.attr 1`] = `"x.y"`; + +exports[`.attr 2`] = `"type.name.attr.y"`; + +exports[`.element 1`] = `"x[0]"`; + +exports[`.element 2`] = `"type.name.attr[0]"`; + +exports[`Argument 1`] = `"x"`; + +exports[`arg 1`] = `"x"`; + +exports[`arg 2`] = `"type.name.attr"`; + +exports[`interpolation 1`] = `"prefix-\${x}-suffix"`; + +exports[`interpolation 2`] = `"prefix-\${type.name.attr}-suffix"`; diff --git a/test/arguments/__snapshots__/Attribute.test.ts.snap b/test/arguments/__snapshots__/Attribute.test.ts.snap new file mode 100644 index 0000000..57324d7 --- /dev/null +++ b/test/arguments/__snapshots__/Attribute.test.ts.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Attribute 1`] = `"type.name.x"`; + +exports[`attr 1`] = `"type.name.x"`; diff --git a/test/arguments/__snapshots__/Function.test.ts.snap b/test/arguments/__snapshots__/Function.test.ts.snap new file mode 100644 index 0000000..25b2924 --- /dev/null +++ b/test/arguments/__snapshots__/Function.test.ts.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Function 1`] = `"fn()"`; + +exports[`Function 2`] = `"fn(&tfgquot;x&tfgquot;, &tfgquot;y&tfgquot;, &tfgquot;z&tfgquot;)"`; + +exports[`Function 3`] = `"fn(1, 2, 3)"`; + +exports[`Function 4`] = `"fn(true, false, true)"`; + +exports[`Function 5`] = `"fn(&tfgquot;x&tfgquot;, 2, true)"`; + +exports[`Function 6`] = `"fn(&tfgquot;x&tfgquot;, type.name.attr)"`; + +exports[`Function 7`] = ` +"fn(&tfgquot;x&tfgquot;, { +a = 1 +b = &tfgquot;2&tfgquot; +})" +`; + +exports[`fn 1`] = `"fn()"`; + +exports[`fn 2`] = `"fn(&tfgquot;x&tfgquot;, &tfgquot;y&tfgquot;, &tfgquot;z&tfgquot;)"`; + +exports[`fn 3`] = `"fn(1, 2, 3)"`; + +exports[`fn 4`] = `"fn(true, false, true)"`; + +exports[`fn 5`] = `"fn(&tfgquot;x&tfgquot;, 2, true)"`; + +exports[`fn 6`] = `"fn(&tfgquot;x&tfgquot;, type.name.attr)"`; + +exports[`fn 7`] = ` +"fn(&tfgquot;x&tfgquot;, { +a = 1 +b = &tfgquot;2&tfgquot; +})" +`; diff --git a/test/arguments/__snapshots__/Heredoc.test.ts.snap b/test/arguments/__snapshots__/Heredoc.test.ts.snap new file mode 100644 index 0000000..c949f23 --- /dev/null +++ b/test/arguments/__snapshots__/Heredoc.test.ts.snap @@ -0,0 +1,33 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Heredoc 1`] = ` +"< { const backend = new Backend('name', arg4); expect(backend.toTerraform()).toMatchSnapshot(); - expect(backend.asArgument().toTerraform()).toBe(Util.escape('"name"')); + expect(backend.asArgument().toTerraform()).toMatchSnapshot(); expect(() => backend.attr('attr')).toThrow(); }); diff --git a/test/blocks/Data.test.ts b/test/blocks/Data.test.ts index 4fc9f32..77dce78 100644 --- a/test/blocks/Data.test.ts +++ b/test/blocks/Data.test.ts @@ -1,10 +1,9 @@ import { arg4 } from '..'; import { Data } from '../../src/blocks'; -import { Util } from '../../src/utils'; test('Data', () => { const data = new Data('type', 'name', arg4); expect(data.toTerraform()).toMatchSnapshot(); - expect(data.asArgument().toTerraform()).toBe(Util.escape('data.type.name')); - expect(data.attr('attr').toTerraform()).toBe(Util.escape('data.type.name.attr')); + expect(data.asArgument().toTerraform()).toMatchSnapshot(); + expect(data.attr('attr').toTerraform()).toMatchSnapshot(); }); diff --git a/test/blocks/Locals.test.ts b/test/blocks/Locals.test.ts index 7850b95..b339fac 100644 --- a/test/blocks/Locals.test.ts +++ b/test/blocks/Locals.test.ts @@ -1,11 +1,10 @@ import { arg4 } from '..'; import { Locals } from '../../src/blocks'; -import { Util } from '../../src/utils'; test('Locals', () => { const locals = new Locals(arg4); expect(locals.toTerraform()).toMatchSnapshot(); expect(() => locals.asArgument()).toThrow(); expect(() => locals.attr('attr')).toThrow(); - expect(locals.arg('arg').toTerraform()).toBe(Util.escape('local.arg')); + expect(locals.arg('arg').toTerraform()).toMatchSnapshot(); }); diff --git a/test/blocks/Module.test.ts b/test/blocks/Module.test.ts index 70f9054..14d66dd 100644 --- a/test/blocks/Module.test.ts +++ b/test/blocks/Module.test.ts @@ -1,6 +1,5 @@ import { arg4 } from '..'; import { Module } from '../../src/blocks'; -import { Util } from '../../src/utils'; test('Module', () => { const module = new Module('name', { @@ -9,6 +8,6 @@ test('Module', () => { ...arg4 }); expect(module.toTerraform()).toMatchSnapshot(); - expect(module.asArgument().toTerraform()).toBe(Util.escape('module.name')); - expect(module.attr('attr').toTerraform()).toBe(Util.escape('module.name.attr')); + expect(module.asArgument().toTerraform()).toMatchSnapshot(); + expect(module.attr('attr').toTerraform()).toMatchSnapshot(); }); diff --git a/test/blocks/Provider.test.ts b/test/blocks/Provider.test.ts index 7c5f8c2..9c511c4 100644 --- a/test/blocks/Provider.test.ts +++ b/test/blocks/Provider.test.ts @@ -1,6 +1,5 @@ import { arg4 } from '..'; import { Provider } from '../../src/blocks'; -import { Util } from '../../src/utils'; test('Provider', () => { const provider = new Provider('name', arg4); @@ -12,6 +11,6 @@ test('Provider', () => { test('Provider alias', () => { const provider = new Provider('name', { ...arg4, alias: 'alias' }); expect(provider.toTerraform()).toMatchSnapshot(); - expect(provider.asArgument().toTerraform()).toBe(Util.escape('name.alias')); + expect(provider.asArgument().toTerraform()).toMatchSnapshot(); expect(() => provider.attr('attr')).toThrow(); }); diff --git a/test/blocks/Resource.test.ts b/test/blocks/Resource.test.ts index 2217f7f..ce95606 100644 --- a/test/blocks/Resource.test.ts +++ b/test/blocks/Resource.test.ts @@ -1,20 +1,19 @@ import { arg4 } from '..'; +import { Map } from '../../src/arguments'; import { Resource } from '../../src/blocks'; -import { map } from '../../src/types'; -import { Util } from '../../src/utils'; test('Resource', () => { const resource = new Resource('type', 'name', arg4); expect(resource.toTerraform()).toMatchSnapshot(); - expect(resource.asArgument().toTerraform()).toBe(Util.escape('type.name')); - expect(resource.attr('attr').toTerraform()).toBe(Util.escape('type.name.attr')); + expect(resource.asArgument().toTerraform()).toMatchSnapshot(); + expect(resource.attr('attr').toTerraform()).toMatchSnapshot(); }); describe('toData', () => { const resource = new Resource('type', 'name', { arg: 'arg', - tags: map({ + tags: new Map({ a: 'a', b: 'b' }) diff --git a/test/blocks/Variable.test.ts b/test/blocks/Variable.test.ts index 7bd7dfc..3114185 100644 --- a/test/blocks/Variable.test.ts +++ b/test/blocks/Variable.test.ts @@ -1,6 +1,5 @@ import { Argument } from '../../src/arguments'; import { Variable } from '../../src/blocks'; -import { Util } from '../../src/utils'; test('Variable', () => { const variable = new Variable('name', { @@ -8,6 +7,6 @@ test('Variable', () => { default: 'value' }); expect(variable.toTerraform()).toMatchSnapshot(); - expect(variable.asArgument().toTerraform()).toBe(Util.escape('var.name')); - expect(variable.attr('attr').toTerraform()).toBe(Util.escape('var.name.attr')); + expect(variable.asArgument().toTerraform()).toMatchSnapshot(); + expect(variable.attr('attr').toTerraform()).toMatchSnapshot(); }); diff --git a/test/blocks/__snapshots__/Backend.test.ts.snap b/test/blocks/__snapshots__/Backend.test.ts.snap index 2efc041..618f22c 100644 --- a/test/blocks/__snapshots__/Backend.test.ts.snap +++ b/test/blocks/__snapshots__/Backend.test.ts.snap @@ -40,13 +40,12 @@ type.name.attr, type.name ] arg11 = arg -arg12 = type.name.attr -arg13 = < { const getTagName = (type: string, name?: string, tier?: string): string => `${type}-${project}-${configs.env}${tier ? `-${tier}` : ''}${name ? `-${name}` : ''}`; -const getTags = (type: string, name?: string, tier?: string): Map => new Map({ +const getTags = (type: string, name?: string, tier?: string): Map => map({ name: getTagName(type, name, tier), project, env: configs.env @@ -267,13 +267,13 @@ const createTerraformGenerator = (): TerraformGenerator => { // Output tfg.output('vpc', { - value: new Map({ + value: map({ cidr: vpc.attr('cidr_block') }) }); tfg.output('subnets', { - value: new Map({ + value: map({ publicSubnets: publicSubnets.map(subnet => subnet.attr('cidr_block')), webSubnets: webSubnets.map(subnet => subnet.attr('cidr_block')), appSubnets: appSubnets.map(subnet => subnet.attr('cidr_block')), diff --git a/test/tfg/Others.test.ts b/test/tfg/Others.test.ts index 8d9ea45..acfb7f8 100644 --- a/test/tfg/Others.test.ts +++ b/test/tfg/Others.test.ts @@ -1,9 +1,8 @@ import fs from 'fs'; import path from 'path'; -import { arg } from '../../src/arguments'; +import { arg, map } from '../../src/arguments'; import { Provisioner } from '../../src/blocks'; import { TerraformGenerator } from '../../src/TerraformGenerator'; -import { map } from '../../src/types'; const createTerraformGenerator = (): TerraformGenerator => { const tfg = new TerraformGenerator();