@@ -16,144 +16,240 @@ import (
1616
1717type formTypeTestCase struct {
1818 name string
19- config string
19+ config formTypeCheck
2020 assert paramAssert
2121 expectError * regexp.Regexp
2222}
2323
2424type paramAssert struct {
25- Default string
26- FormType string
27- Type string
25+ FormType provider.ParameterFormType
26+ Type provider.OptionType
2827 Styling string
2928}
3029
3130type formTypeCheck struct {
32- formType provider.ParameterFormType
33- optionType provider.OptionType
34- optionsExist bool
31+ formType provider.ParameterFormType
32+ optionType provider.OptionType
33+ options bool
34+ }
35+
36+ func (c formTypeCheck ) String () string {
37+ return fmt .Sprintf ("%s_%s_%t" , c .formType , c .optionType , c .options )
3538}
3639
3740func TestValidateFormType (t * testing.T ) {
3841 t .Parallel ()
3942
4043 //formTypesChecked := make(map[provider.ParameterFormType]map[provider.OptionType]map[bool]struct{})
41- formTypesChecked := make (map [formTypeCheck ]struct {})
44+ formTypesChecked := make (map [string ]struct {})
4245
43- const paramName = "test_me"
46+ obvious := func (expected provider.ParameterFormType , opts formTypeCheck ) formTypeTestCase {
47+ ftname := opts .formType
48+ if ftname == "" {
49+ ftname = "default"
50+ }
51+ return formTypeTestCase {
52+ name : fmt .Sprintf ("%s_%s_%t" ,
53+ ftname ,
54+ opts .optionType ,
55+ opts .options ,
56+ ),
57+ config : opts ,
58+ assert : paramAssert {
59+ FormType : expected ,
60+ Type : opts .optionType ,
61+ Styling : "" ,
62+ },
63+ expectError : nil ,
64+ }
65+ }
4466
4567 cases := []formTypeTestCase {
4668 {
4769 // When nothing is specified
4870 name : "defaults" ,
49- config : ezconfig (paramName , ezconfigOpts {}),
50- assert : paramAssert {
51- Default : "" ,
52- FormType : "input" ,
53- Type : "string" ,
54- Styling : "" ,
55- },
56- },
57- {
58- name : "string radio" ,
59- config : ezconfig (paramName , ezconfigOpts {Options : []string {"foo" }}),
71+ config : formTypeCheck {},
6072 assert : paramAssert {
61- Default : "" ,
62- FormType : "radio" ,
63- Type : "string" ,
73+ FormType : provider .ParameterFormTypeInput ,
74+ Type : provider .OptionTypeString ,
6475 Styling : "" ,
6576 },
6677 },
78+ // String
79+ obvious (provider .ParameterFormTypeRadio , formTypeCheck {
80+ options : true ,
81+ optionType : provider .OptionTypeString ,
82+ }),
83+ obvious (provider .ParameterFormTypeRadio , formTypeCheck {
84+ options : true ,
85+ optionType : provider .OptionTypeString ,
86+ formType : provider .ParameterFormTypeRadio ,
87+ }),
88+ obvious (provider .ParameterFormTypeDropdown , formTypeCheck {
89+ options : true ,
90+ optionType : provider .OptionTypeString ,
91+ formType : provider .ParameterFormTypeDropdown ,
92+ }),
93+ obvious (provider .ParameterFormTypeInput , formTypeCheck {
94+ options : false ,
95+ optionType : provider .OptionTypeString ,
96+ }),
97+ obvious (provider .ParameterFormTypeTextArea , formTypeCheck {
98+ options : false ,
99+ optionType : provider .OptionTypeString ,
100+ formType : provider .ParameterFormTypeTextArea ,
101+ }),
102+ // Numbers
103+ obvious (provider .ParameterFormTypeRadio , formTypeCheck {
104+ options : true ,
105+ optionType : provider .OptionTypeNumber ,
106+ }),
107+ obvious (provider .ParameterFormTypeRadio , formTypeCheck {
108+ options : true ,
109+ optionType : provider .OptionTypeNumber ,
110+ formType : provider .ParameterFormTypeRadio ,
111+ }),
112+ obvious (provider .ParameterFormTypeDropdown , formTypeCheck {
113+ options : true ,
114+ optionType : provider .OptionTypeNumber ,
115+ formType : provider .ParameterFormTypeDropdown ,
116+ }),
117+ obvious (provider .ParameterFormTypeInput , formTypeCheck {
118+ options : false ,
119+ optionType : provider .OptionTypeNumber ,
120+ }),
121+ obvious (provider .ParameterFormTypeSlider , formTypeCheck {
122+ options : false ,
123+ optionType : provider .OptionTypeNumber ,
124+ formType : provider .ParameterFormTypeSlider ,
125+ }),
126+ // booleans
127+ obvious (provider .ParameterFormTypeRadio , formTypeCheck {
128+ options : true ,
129+ optionType : provider .OptionTypeBoolean ,
130+ }),
131+ obvious (provider .ParameterFormTypeCheckbox , formTypeCheck {
132+ options : false ,
133+ optionType : provider .OptionTypeBoolean ,
134+ }),
135+ obvious (provider .ParameterFormTypeCheckbox , formTypeCheck {
136+ options : false ,
137+ optionType : provider .OptionTypeBoolean ,
138+ formType : provider .ParameterFormTypeCheckbox ,
139+ }),
140+ obvious (provider .ParameterFormTypeSwitch , formTypeCheck {
141+ options : false ,
142+ optionType : provider .OptionTypeBoolean ,
143+ formType : provider .ParameterFormTypeSwitch ,
144+ }),
67145 }
68146
69- for _ , c := range cases {
70- t .Run (c .name , func (t * testing.T ) {
71- t .Parallel ()
72- if c .assert .Styling == "" {
73- c .assert .Styling = "{}"
74- }
147+ // TabledCases runs through all the manual test cases
148+ t .Run ("TabledCases" , func (t * testing.T ) {
149+ for _ , c := range cases {
150+ t .Run (c .name , func (t * testing.T ) {
151+ t .Parallel ()
152+ if c .assert .Styling == "" {
153+ c .assert .Styling = "{}"
154+ }
75155
76- formTypesChecked [formTypeTest (t , paramName , c )] = struct {}{}
77- })
78- }
156+ formTypeTest (t , c )
157+ formTypesChecked [c .config .String ()] = struct {}{}
158+ })
159+ }
160+ })
79161
80- // TODO: assume uncovered cases should fail
162+ // AssumeErrorCases assumes any uncovered test will return an error.
163+ // This ensures all valid test case paths are covered.
81164 t .Run ("AssumeErrorCases" , func (t * testing.T ) {
82- t .Skip ()
83165 // requiredChecks loops through all possible form_type and option_type
84166 // combinations.
85167 requiredChecks := make ([]formTypeCheck , 0 )
86168 //requiredChecks := make(map[provider.ParameterFormType][]provider.OptionType)
87- for _ , ft := range provider .ParameterFormTypes () {
169+ for _ , ft := range append ( provider .ParameterFormTypes (), "" ) {
88170 //requiredChecks[ft] = make([]provider.OptionType, 0)
89171 for _ , ot := range provider .OptionTypes () {
90172 requiredChecks = append (requiredChecks , formTypeCheck {
91- formType : ft ,
92- optionType : ot ,
93- optionsExist : false ,
173+ formType : ft ,
174+ optionType : ot ,
175+ options : false ,
94176 })
95177 requiredChecks = append (requiredChecks , formTypeCheck {
96- formType : ft ,
97- optionType : ot ,
98- optionsExist : true ,
178+ formType : ft ,
179+ optionType : ot ,
180+ options : true ,
99181 })
100- //requiredChecks[ft] = append(requiredChecks[ft], ot)
101182 }
102183 }
103184
104185 for _ , check := range requiredChecks {
105- _ , alreadyChecked := formTypesChecked [check ]
186+ _ , alreadyChecked := formTypesChecked [check . String () ]
106187 if alreadyChecked {
107188 continue
108189 }
109190
110- // Assume it will fail
191+ ftName := check .formType
192+ if ftName == "" {
193+ ftName = "default"
194+ }
195+ fc := formTypeTestCase {
196+ name : fmt .Sprintf ("%s_%s_%t" ,
197+ ftName ,
198+ check .optionType ,
199+ check .options ,
200+ ),
201+ config : check ,
202+ assert : paramAssert {},
203+ expectError : regexp .MustCompile ("is not supported" ),
204+ }
111205
112- }
206+ t .Run (fc .name , func (t * testing.T ) {
207+ t .Parallel ()
113208
114- //checkedFormTypes := make([]provider.ParameterFormType, 0)
115- //for ft, ot := range formTypesChecked {
116- // checkedFormTypes = append(checkedFormTypes, ft)
117- // var _ = ot
118- //}
119- //
120- //// Fist check all form types have at least 1 test.
121- //require.ElementsMatch(t, provider.ParameterFormTypes(), checkedFormTypes, "some form types are missing tests")
122- //
123- //// Then check each form type has tried with each option type
124- //for expectedFt, expectedOptionTypes := range requiredChecks {
125- // actual := formTypesChecked[expectedFt]
126- //
127- // assert.Equalf(t, expectedOptionTypes, maps.Keys(actual), "some option types are missing for form type %s", expectedFt)
128- //
129- // // Also check for a true/false
130- // for _, expectedOptionType := range expectedOptionTypes {
131- // assert.Equalf(t, []bool{true, false}, maps.Keys(actual[expectedOptionType]), "options should be both present and absent for form type %q, option type %q", expectedFt, expectedOptionType)
132- // }
133- //}
134- })
135- }
209+ tcText := fmt .Sprintf (`
210+ obvious(%s, ezconfigOpts{
211+ Options: %t,
212+ OptionType: %q,
213+ FormType: %q,
214+ }),
215+ ` , "<expected_form_type>" , check .options , check .optionType , check .formType )
216+ t .Logf ("To construct this test case:\n %s" , tcText )
217+ formTypeTest (t , fc )
218+ })
136219
137- type ezconfigOpts struct {
138- Options []string
139- FormType string
140- OptionType string
141- Default string
220+ }
221+ })
142222}
143223
144- func ezconfig (paramName string , cfg ezconfigOpts ) string {
224+ func ezconfig (paramName string , cfg formTypeCheck ) string {
145225 var body strings.Builder
146- if cfg .Default != "" {
147- body .WriteString (fmt .Sprintf ("default = %q\n " , cfg .Default ))
226+ //if cfg.Default != "" {
227+ // body.WriteString(fmt.Sprintf("default = %q\n", cfg.Default))
228+ //}
229+ if cfg .formType != "" {
230+ body .WriteString (fmt .Sprintf ("form_type = %q\n " , cfg .formType ))
148231 }
149- if cfg .FormType != "" {
150- body .WriteString (fmt .Sprintf ("form_type = %q\n " , cfg .FormType ))
232+ if cfg .optionType != "" {
233+ body .WriteString (fmt .Sprintf ("type = %q\n " , cfg .optionType ))
151234 }
152- if cfg .OptionType != "" {
153- body .WriteString (fmt .Sprintf ("type = %q\n " , cfg .OptionType ))
235+
236+ var options []string
237+ if cfg .options {
238+ switch cfg .optionType {
239+ case provider .OptionTypeString :
240+ options = []string {"foo" }
241+ case provider .OptionTypeBoolean :
242+ options = []string {"true" , "false" }
243+ case provider .OptionTypeNumber :
244+ options = []string {"1" }
245+ case provider .OptionTypeListString :
246+ options = []string {`["red", "blue"]` }
247+ default :
248+ panic (fmt .Sprintf ("unknown option type %q when generating options" , cfg .optionType ))
249+ }
154250 }
155251
156- for i , opt := range cfg . Options {
252+ for i , opt := range options {
157253 body .WriteString ("option {\n " )
158254 body .WriteString (fmt .Sprintf ("name = \" val_%d\" \n " , i ))
159255 body .WriteString (fmt .Sprintf ("value = %q\n " , opt ))
@@ -174,42 +270,43 @@ func coderParamHCL(paramName string, body string) string {
174270 ` , paramName , paramName , body )
175271}
176272
177- func formTypeTest (t * testing.T , paramName string , c formTypeTestCase ) formTypeCheck {
178- var check formTypeCheck
273+ func formTypeTest (t * testing.T , c formTypeTestCase ) {
274+ const paramName = "test_param"
275+
276+ checkFn := func (state * terraform.State ) error {
277+ require .Len (t , state .Modules , 1 )
278+ require .Len (t , state .Modules [0 ].Resources , 1 )
279+
280+ key := strings .Join ([]string {"data" , "coder_parameter" , paramName }, "." )
281+ param := state .Modules [0 ].Resources [key ]
282+
283+ //assert.Equal(t, c.assert.Default, param.Primary.Attributes["default"], "default value")
284+ assert .Equal (t , string (c .assert .FormType ), param .Primary .Attributes ["form_type" ], "form_type" )
285+ assert .Equal (t , string (c .assert .Type ), param .Primary .Attributes ["type" ], "type" )
286+ assert .JSONEq (t , c .assert .Styling , param .Primary .Attributes ["styling" ], "styling" )
287+
288+ //ft := provider.ParameterFormType(param.Primary.Attributes["form_type"])
289+ //ot := provider.OptionType(param.Primary.Attributes["type"])
290+
291+ // Option blocks are not stored in a very friendly format
292+ // here.
293+ //options := param.Primary.Attributes["option.0.name"] != ""
294+
295+ return nil
296+ }
297+ if c .expectError != nil {
298+ checkFn = nil
299+ }
300+
179301 resource .Test (t , resource.TestCase {
180302 IsUnitTest : true ,
181303 ProviderFactories : coderFactory (),
182304 Steps : []resource.TestStep {
183305 {
184- Config : c .config ,
185- Check : func (state * terraform.State ) error {
186- require .Len (t , state .Modules , 1 )
187- require .Len (t , state .Modules [0 ].Resources , 1 )
188-
189- key := strings .Join ([]string {"data" , "coder_parameter" , paramName }, "." )
190- param := state .Modules [0 ].Resources [key ]
191-
192- assert .Equal (t , c .assert .Default , param .Primary .Attributes ["default" ], "default value" )
193- assert .Equal (t , c .assert .FormType , param .Primary .Attributes ["form_type" ], "form_type" )
194- assert .Equal (t , c .assert .Type , param .Primary .Attributes ["type" ], "type" )
195- assert .JSONEq (t , c .assert .Styling , param .Primary .Attributes ["styling" ], "styling" )
196-
197- ft := provider .ParameterFormType (param .Primary .Attributes ["form_type" ])
198- ot := provider .OptionType (param .Primary .Attributes ["type" ])
199-
200- // Option blocks are not stored in a very friendly format
201- // here.
202- optionsExist := param .Primary .Attributes ["option.0.name" ] != ""
203- check = formTypeCheck {
204- formType : ft ,
205- optionType : ot ,
206- optionsExist : optionsExist ,
207- }
208-
209- return nil
210- },
306+ Config : ezconfig (paramName , c .config ),
307+ Check : checkFn ,
308+ ExpectError : c .expectError ,
211309 },
212310 },
213311 })
214- return check
215312}
0 commit comments