github.com/zntrio/harp/v2@v2.0.9/pkg/template/values/hcl2/convert_test.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package hcl2
    19  
    20  import (
    21  	"encoding/json"
    22  	"testing"
    23  
    24  	"github.com/hashicorp/hcl/v2"
    25  	"github.com/hashicorp/hcl/v2/hclsyntax"
    26  )
    27  
    28  // This file is mostly attributed to https://github.com/tmccombs/hcl2json
    29  
    30  const inputa = `
    31  resource "aws_elastic_beanstalk_environment" "example" {
    32  	name        = "test_environment"
    33  	application = "testing"
    34  
    35  	setting {
    36  	  namespace = "aws:autoscaling:asg"
    37  	  name      = "MinSize"
    38  	  value     = "1"
    39  	}
    40  
    41  	dynamic "setting" {
    42  	  for_each = data.consul_key_prefix.environment.var
    43  	  content {
    44  		heredoc = <<-EOF
    45  		This is a heredoc template.
    46  		It references ${local.other.3}
    47  		EOF
    48  		simple = "${4 - 2}"
    49  		cond = test3 > 2 ? 1: 0
    50  		heredoc2 = <<EOF
    51  			Another heredoc, that
    52  			doesn't remove indentation
    53  			${local.other.3}
    54  			%{if true ? false : true}"gotcha"\n%{else}4%{endif}
    55  		EOF
    56  		loop = "This has a for loop: %{for x in local.arr}x,%{endfor}"
    57  		namespace = "aws:elasticbeanstalk:application:environment"
    58  		name      = setting.key
    59  		value     = setting.value
    60  	  }
    61  	}
    62    }`
    63  
    64  const outputa = `{
    65  	"resource": {
    66  		"aws_elastic_beanstalk_environment": {
    67  			"example": {
    68  				"application": "testing",
    69  				"dynamic": {
    70  					"setting": {
    71  						"content": {
    72  							"cond": "${test3 \u003e 2 ? 1: 0}",
    73  							"heredoc": "This is a heredoc template.\nIt references ${local.other.3}\n",
    74  							"heredoc2": "\t\t\tAnother heredoc, that\n\t\t\tdoesn't remove indentation\n\t\t\t${local.other.3}\n\t\t\t%{if true ? false : true}\"gotcha\"\\n%{else}4%{endif}\n",
    75  							"loop": "This has a for loop: %{for x in local.arr}x,%{endfor}",
    76  							"name": "${setting.key}",
    77  							"namespace": "aws:elasticbeanstalk:application:environment",
    78  							"simple": "${4 - 2}",
    79  							"value": "${setting.value}"
    80  						},
    81  						"for_each": "${data.consul_key_prefix.environment.var}"
    82  					}
    83  				},
    84  				"name": "test_environment",
    85  				"setting": {
    86  					"name": "MinSize",
    87  					"namespace": "aws:autoscaling:asg",
    88  					"value": "1"
    89  				}
    90  			}
    91  		}
    92  	}
    93  }`
    94  
    95  const inputb = `
    96  provider "aws" {
    97      version             = "=2.46.0"
    98      alias                  = "one"
    99  }
   100  `
   101  
   102  const outputb = `{
   103  	"provider": {
   104  		"aws": {
   105  			"alias": "one",
   106  			"version": "=2.46.0"
   107  		}
   108  	}
   109  }`
   110  
   111  const inputc = `
   112  provider "aws" {
   113      version             = "=2.46.0"
   114      alias                  = "one"
   115  }
   116  provider "aws" {
   117      version             = "=2.47.0"
   118      alias                  = "two"
   119  }
   120  `
   121  
   122  const outputc = `{
   123  	"provider": {
   124  		"aws": [
   125  			{
   126  				"alias": "one",
   127  				"version": "=2.46.0"
   128  			},
   129  			{
   130  				"alias": "two",
   131  				"version": "=2.47.0"
   132  			}
   133  		]
   134  	}
   135  }`
   136  
   137  // Test that conversion works as expected.
   138  func TestConversion(t *testing.T) {
   139  	testTable := map[string]struct {
   140  		input  string
   141  		output string
   142  	}{
   143  		"simple-resources": {input: inputa, output: outputa},
   144  		"single-provider":  {input: inputb, output: outputb},
   145  		"two-providers":    {input: inputc, output: outputc},
   146  	}
   147  	for name, tc := range testTable {
   148  		bytes := []byte(tc.input)
   149  		conf, diags := hclsyntax.ParseConfig(bytes, "test", hcl.Pos{Byte: 0, Line: 1, Column: 1})
   150  		if diags.HasErrors() {
   151  			t.Errorf("Failed to parse config: %v", diags)
   152  		}
   153  		converted, err := convertFile(conf)
   154  		if err != nil {
   155  			t.Errorf("Unable to convert from hcl: %v", err)
   156  		}
   157  
   158  		jb, err := json.MarshalIndent(converted, "", "\t")
   159  		if err != nil {
   160  			t.Errorf("Failed to serialize to json: %v", err)
   161  		}
   162  		computedJSON := string(jb)
   163  
   164  		if computedJSON != tc.output {
   165  			t.Errorf("For test %s\nExpected:\n%s\n\nGot:\n%s", name, tc.output, computedJSON)
   166  		}
   167  	}
   168  }