From 7512e648bf41572bc774865cb7ecc8dd3842c3a2 Mon Sep 17 00:00:00 2001 From: XIAOLONG LI <1491skdpf89@gmail.com> Date: Sun, 22 Jun 2025 10:21:11 -0400 Subject: [PATCH 1/5] Update json-to-hcl.test.ts Added test for variable bool and string default value. --- packages/cdktf/test/json-to-hcl.test.ts | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/cdktf/test/json-to-hcl.test.ts b/packages/cdktf/test/json-to-hcl.test.ts index 67c369b600..09739958f5 100644 --- a/packages/cdktf/test/json-to-hcl.test.ts +++ b/packages/cdktf/test/json-to-hcl.test.ts @@ -1099,6 +1099,42 @@ test("string type", () => { `); }); +test("string variable default", () => { + const app = Testing.app(); + const stack = new TerraformStack(app, "test"); + + new TerraformVariable(stack, "test-string-variable-default", { + type: "string", + default: false + }); + expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` + " + + variable "test-variable" { + type = string + default = false + }" + `); +}); + +test("bool variable default", () => { + const app = Testing.app(); + const stack = new TerraformStack(app, "test"); + + new TerraformVariable(stack, "test-bool-variable-default", { + type: "bool", + default: false + }); + expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` + " + + variable "test-variable" { + type = bool + default = false + }" + `); +}); + test("number type", () => { const app = Testing.app(); const stack = new TerraformStack(app, "test"); From f7a726a721a5657927a2a0f6e3f482b0bd603c19 Mon Sep 17 00:00:00 2001 From: XIAOLONG LI <1491skdpf89@gmail.com> Date: Sun, 22 Jun 2025 10:34:54 -0400 Subject: [PATCH 2/5] Update json-to-hcl.test.ts Added sensitive = false --- packages/cdktf/test/json-to-hcl.test.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/cdktf/test/json-to-hcl.test.ts b/packages/cdktf/test/json-to-hcl.test.ts index 09739958f5..11eec75dcf 100644 --- a/packages/cdktf/test/json-to-hcl.test.ts +++ b/packages/cdktf/test/json-to-hcl.test.ts @@ -1103,7 +1103,7 @@ test("string variable default", () => { const app = Testing.app(); const stack = new TerraformStack(app, "test"); - new TerraformVariable(stack, "test-string-variable-default", { + new TerraformVariable(stack, "test-variable", { type: "string", default: false }); @@ -1121,7 +1121,7 @@ test("bool variable default", () => { const app = Testing.app(); const stack = new TerraformStack(app, "test"); - new TerraformVariable(stack, "test-bool-variable-default", { + new TerraformVariable(stack, "test-variable", { type: "bool", default: false }); @@ -1135,6 +1135,24 @@ test("bool variable default", () => { `); }); +test("string variable sensitive", () => { + const app = Testing.app(); + const stack = new TerraformStack(app, "test"); + + new TerraformVariable(stack, "test-variable", { + type: "string", + sensitive: false + }); + expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` + " + + variable "test-variable" { + type = string + sensitive = false + }" + `); +}); + test("number type", () => { const app = Testing.app(); const stack = new TerraformStack(app, "test"); From 75bb9ff459e0642534abc73fe4a024367c0fb1df Mon Sep 17 00:00:00 2001 From: XIAOLONG LI <1491skdpf89@gmail.com> Date: Sun, 22 Jun 2025 10:49:37 -0400 Subject: [PATCH 3/5] sensitive false at json-to-hcl.test.ts sensitive false --- packages/cdktf/test/json-to-hcl.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/cdktf/test/json-to-hcl.test.ts b/packages/cdktf/test/json-to-hcl.test.ts index 11eec75dcf..dd8b3046d1 100644 --- a/packages/cdktf/test/json-to-hcl.test.ts +++ b/packages/cdktf/test/json-to-hcl.test.ts @@ -363,6 +363,23 @@ describe("output", () => { `); }); + test("sensitive output false", async () => { + const app = Testing.app(); + const stack = new TerraformStack(app, "test"); + + new TerraformOutput(stack, "test-output", { + value: 1, + sensitive: false, + }); + expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` + " + + output "test-output" { + value = 1 + sensitive = false + }" + `); + }); test("map keys with invalid identifier chars", async () => { const app = Testing.app(); const stack = new TerraformStack(app, "test"); From 56e8d1d201c7f3cdeea299859ad5b85b36c0a722 Mon Sep 17 00:00:00 2001 From: XIAOLONG LI <1491skdpf89@gmail.com> Date: Sun, 22 Jun 2025 15:43:20 -0400 Subject: [PATCH 4/5] Update render.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handle falsy primitives (false, 0, "") 1. at the top-level (early check), 2. and inside the type === "simple" block with the fallback This ensures values like false don’t silently get dropped. --- packages/cdktf/lib/hcl/render.ts | 33 +++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/packages/cdktf/lib/hcl/render.ts b/packages/cdktf/lib/hcl/render.ts index 7331fd2539..2d36697f51 100644 --- a/packages/cdktf/lib/hcl/render.ts +++ b/packages/cdktf/lib/hcl/render.ts @@ -600,15 +600,24 @@ export function renderAttributes(attributes: any): string { // // We might have some attributes that don't have type information // just try to guess them + + // Handle primitive values and falsy values explicitly + if (v === undefined) { + return undefined; + } + if (v === null) { + return `${name} = null`; + } + if (typeof v === "boolean") { + return `${name} = ${v}`; + } if (typeof v === "string" || typeof v === "number") { return `${name} = ${renderFuzzyJsonExpression(v)}`; - } else if (typeof v === "boolean") { - return `${name} = ${v}`; - } else if (Array.isArray(v)) { + } + if (Array.isArray(v)) { return `${name} = ${renderFuzzyJsonExpression(v)}`; - } else if (v === null) { - return `${name} = null`; - } else if ( + } + if ( typeof v === "object" && // eslint-disable-next-line no-prototype-builtins !v.hasOwnProperty("value") && @@ -621,9 +630,7 @@ ${renderSimpleAttributes(v)} }`; } return `${name} = ${renderFuzzyJsonExpression(v)}`; - } else if (v === undefined) { - return undefined; - } + } // Referencing both isBlock and is_block, because sometimes we pass through a snake case filter // within attributes. @@ -677,6 +684,14 @@ ${renderAttributes(value)} // In either case, we should try to not output [object Object] here // and try a best approximation. Though, it would not work for // blocks + if ( + typeof value === "string" || + typeof value === "number" || + typeof value === "boolean" || + value === null + ) { + return `${name} = ${renderFuzzyJsonExpression(value)}`; + } if (typeof value === "object") { return ` # Warning: The following attribute is of an unexpected type. Either there's a problem with the provider From 13c3813e3ee4aa5f826105a9bcb61e7336c9486c Mon Sep 17 00:00:00 2001 From: XIAOLONG LI <1491skdpf89@gmail.com> Date: Sun, 22 Jun 2025 15:58:33 -0400 Subject: [PATCH 5/5] Update json-to-hcl.test.ts Added unit tests for: false 0 "" null --- packages/cdktf/test/json-to-hcl.test.ts | 65 +++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/packages/cdktf/test/json-to-hcl.test.ts b/packages/cdktf/test/json-to-hcl.test.ts index dd8b3046d1..e9a4131f51 100644 --- a/packages/cdktf/test/json-to-hcl.test.ts +++ b/packages/cdktf/test/json-to-hcl.test.ts @@ -1124,6 +1124,8 @@ test("string variable default", () => { type: "string", default: false }); + const hcl = Testing.synthHcl(stack); + expect(hcl).toContain('default = false'); expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` " @@ -1142,6 +1144,8 @@ test("bool variable default", () => { type: "bool", default: false }); + const hcl = Testing.synthHcl(stack); + expect(hcl).toContain("default = false"); // assume CDKTF standard output formatting has space around the equals sign. expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` " @@ -1160,6 +1164,8 @@ test("string variable sensitive", () => { type: "string", sensitive: false }); + const hcl = Testing.synthHcl(stack); + expect(hcl).toContain("sensitive = false"); expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` " @@ -1170,6 +1176,65 @@ test("string variable sensitive", () => { `); }); +test("number variable default zero", () => { + const app = Testing.app(); + const stack = new TerraformStack(app, "test"); + + const hcl = Testing.synthHcl(stack); + expect(hcl).toContain("default = 0"); + new TerraformVariable(stack, "test-variable", { + type: "number", + default: 0 + }); + expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` + " + + variable "test-variable" { + type = number + default = 0 + }" + `); +}); + +test("string variable default empty", () => { + const app = Testing.app(); + const stack = new TerraformStack(app, "test"); + + new TerraformVariable(stack, "test-variable", { + type: "string", + default: "" + }); + const hcl = Testing.synthHcl(stack); + expect(hcl).toContain('default = ""'); + expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` + " + + variable "test-variable" { + type = string + default = "" + }" + `); +}); + +test("variable default null", () => { + const app = Testing.app(); + const stack = new TerraformStack(app, "test"); + + new TerraformVariable(stack, "test-variable", { + type: "string", + default: null, + }); + const hcl = Testing.synthHcl(stack); + expect(hcl).toContain('default = null'); + expect(Testing.synthHcl(stack)).toMatchInlineSnapshot(` + " + variable "test-variable" { + type = string + default = null + }" + `); +}); + test("number type", () => { const app = Testing.app(); const stack = new TerraformStack(app, "test");