1
2
3
4 package filters_test
5
6 import (
7 "bytes"
8 "io"
9 "os"
10 "path/filepath"
11 "strings"
12 "testing"
13
14 "github.com/stretchr/testify/assert"
15 "github.com/stretchr/testify/require"
16 "sigs.k8s.io/kustomize/kyaml/kio"
17 . "sigs.k8s.io/kustomize/kyaml/kio/filters"
18 "sigs.k8s.io/kustomize/kyaml/kio/filters/testyaml"
19 "sigs.k8s.io/kustomize/kyaml/yaml"
20 )
21
22 func TestFormatInput_FixYaml1_1Compatibility(t *testing.T) {
23 y := `
24 apiVersion: apps/v1
25 kind: Deployment
26 metadata:
27 name: foo
28 labels:
29 foo: on
30 foo2: hello1
31 annotations:
32 bar: 1
33 bar2: hello2
34 spec:
35 template:
36 spec:
37 containers:
38 - name: nginx
39 image: nginx:1.0.0
40 args:
41 - on
42 - 1
43 - hello
44 ports:
45 - name: http
46 targetPort: 80
47 containerPort: 80
48 `
49
50
51 expected := `apiVersion: apps/v1
52 kind: Deployment
53 metadata:
54 name: foo
55 labels:
56 foo: "on"
57 foo2: hello1
58 annotations:
59 bar: "1"
60 bar2: hello2
61 spec:
62 template:
63 spec:
64 containers:
65 - name: nginx
66 image: nginx:1.0.0
67 args:
68 - "on"
69 - "1"
70 - hello
71 ports:
72 - name: http
73 targetPort: 80
74 containerPort: 80
75 `
76
77 buff := &bytes.Buffer{}
78 err := kio.Pipeline{
79 Inputs: []kio.Reader{&kio.ByteReader{Reader: strings.NewReader(y)}},
80 Filters: []kio.Filter{FormatFilter{
81 UseSchema: true,
82 }},
83 Outputs: []kio.Writer{kio.ByteWriter{Writer: buff}},
84 }.Execute()
85 require.NoError(t, err)
86 assert.Equal(t, expected, buff.String())
87 }
88
89 func TestFormat_UnsortedInput_No_Schema(t *testing.T) {
90 y := `
91 apiVersion: apps/v1
92 spec:
93 template:
94 spec:
95 containers:
96 - name: nginx
97 image: nginx:1.0.0
98 args:
99 - on
100 - 1
101 - hello
102 ports:
103 - name: http
104 targetPort: 80
105 containerPort: 80
106 kind: Deployment
107 metadata:
108 name: foo
109 labels:
110 foo: on
111 foo2: hello1
112 annotations:
113 bar: 1
114 bar2: hello2
115 `
116
117
118 expected := `apiVersion: apps/v1
119 kind: Deployment
120 metadata:
121 name: foo
122 labels:
123 foo: on
124 foo2: hello1
125 annotations:
126 bar: 1
127 bar2: hello2
128 spec:
129 template:
130 spec:
131 containers:
132 - name: nginx
133 image: nginx:1.0.0
134 args:
135 - on
136 - 1
137 - hello
138 ports:
139 - name: http
140 targetPort: 80
141 containerPort: 80
142 `
143
144 buff := &bytes.Buffer{}
145 err := kio.Pipeline{
146 Inputs: []kio.Reader{&kio.ByteReader{Reader: strings.NewReader(y)}},
147 Filters: []kio.Filter{FormatFilter{}},
148 Outputs: []kio.Writer{kio.ByteWriter{Writer: buff}},
149 }.Execute()
150 require.NoError(t, err)
151 assert.Equal(t, expected, buff.String())
152 }
153
154 func TestFormatInput_PostprocessStyle(t *testing.T) {
155 y := `
156 apiVersion: v1
157 kind: Foo
158 metadata:
159 name: foo
160 spec:
161 notBoolean: "true"
162 notBoolean2: "on"
163 isBoolean: on
164 isBoolean2: true
165 notInt: "12345"
166 isInt: 12345
167 isString1: hello world
168 isString2: "hello world"
169 `
170
171
172 expected := `apiVersion: v1
173 kind: Foo
174 metadata:
175 name: foo
176 spec:
177 isBoolean: on
178 isBoolean2: true
179 isInt: 12345
180 isString1: hello world
181 isString2: hello world
182 notBoolean: "true"
183 notBoolean2: "on"
184 notInt: "12345"
185 `
186
187 buff := &bytes.Buffer{}
188 err := kio.Pipeline{
189 Inputs: []kio.Reader{&kio.ByteReader{Reader: strings.NewReader(y)}},
190 Filters: []kio.Filter{FormatFilter{
191 UseSchema: true,
192 Process: func(n *yaml.Node) error {
193 if yaml.IsYaml1_1NonString(n) {
194
195
196 return nil
197 }
198
199 n.Style = 0
200 return nil
201 }}},
202 Outputs: []kio.Writer{kio.ByteWriter{Writer: buff}},
203 }.Execute()
204 require.NoError(t, err)
205 assert.Equal(t, expected, buff.String())
206
207 y = `
208 apiVersion: v1
209 kind: Foo
210 metadata:
211 name: 'foo'
212 spec:
213 notBoolean: "true"
214 notBoolean2: "on"
215 notBoolean3: y is yes
216 isBoolean: on
217 isBoolean2: true
218 isBoolean3: y
219 notInt2: 1234 five
220 notInt3: one 2345
221 notInt: "12345"
222 isInt1: 12345
223 isInt2: -12345
224 isFloat1: 1.1234
225 isFloat2: 1.1234
226 isString1: hello world
227 isString2: "hello world"
228 isString3: 'hello world'
229 `
230
231
232 expected = `apiVersion: 'v1'
233 kind: 'Foo'
234 metadata:
235 name: 'foo'
236 spec:
237 isBoolean: on
238 isBoolean2: true
239 isBoolean3: y
240 isFloat1: 1.1234
241 isFloat2: 1.1234
242 isInt1: 12345
243 isInt2: -12345
244 isString1: 'hello world'
245 isString2: 'hello world'
246 isString3: 'hello world'
247 notBoolean: "true"
248 notBoolean2: "on"
249 notBoolean3: 'y is yes'
250 notInt: "12345"
251 notInt2: '1234 five'
252 notInt3: 'one 2345'
253 `
254
255 buff = &bytes.Buffer{}
256 err = kio.Pipeline{
257 Inputs: []kio.Reader{&kio.ByteReader{Reader: strings.NewReader(y)}},
258 Filters: []kio.Filter{FormatFilter{
259 UseSchema: true,
260 Process: func(n *yaml.Node) error {
261 if yaml.IsYaml1_1NonString(n) {
262
263
264 return nil
265 }
266
267 n.Style = yaml.SingleQuotedStyle
268 return nil
269 }}},
270 Outputs: []kio.Writer{kio.ByteWriter{Writer: buff}},
271 }.Execute()
272 require.NoError(t, err)
273 assert.Equal(t, expected, buff.String())
274 }
275
276 func TestFormatInput_Style(t *testing.T) {
277 y := `
278 apiVersion: v1
279 kind: Foo
280 metadata:
281 name: foo
282 spec:
283 notBoolean: "true"
284 notBoolean2: "on"
285 isBoolean: on
286 isBoolean2: true
287 `
288
289 expected := `apiVersion: v1
290 kind: Foo
291 metadata:
292 name: foo
293 spec:
294 isBoolean: on
295 isBoolean2: true
296 notBoolean: "true"
297 notBoolean2: "on"
298 `
299
300 s, err := FormatInput(strings.NewReader(y))
301 require.NoError(t, err)
302 assert.Equal(t, expected, s.String())
303 }
304
305
306 func TestFormatInput_configMap(t *testing.T) {
307 y := `
308
309
310 # this formatting is intentionally weird
311
312 apiVersion: v1
313 # this is data
314 data:
315 # this is color
316 color: purple
317 # that was color
318
319 # this is textmode
320 textmode: "true"
321 # this is how
322 how: fairlyNice
323
324
325
326 kind: ConfigMap
327
328
329 metadata:
330 selfLink: /api/v1/namespaces/default/configmaps/config-multi-env-files
331 namespace: default
332 creationTimestamp: 2017-12-27T18:38:34Z
333 name: config-multi-env-files
334 resourceVersion: "810136"
335 uid: 252c4572-eb35-11e7-887b-42010a8002b8 # keep no trailing linefeed`
336
337 expected := `# this formatting is intentionally weird
338
339 apiVersion: v1
340 kind: ConfigMap
341 metadata:
342 name: config-multi-env-files
343 namespace: default
344 creationTimestamp: 2017-12-27T18:38:34Z
345 resourceVersion: "810136"
346 selfLink: /api/v1/namespaces/default/configmaps/config-multi-env-files
347 uid: 252c4572-eb35-11e7-887b-42010a8002b8 # keep no trailing linefeed
348 # this is data
349 data:
350 # this is color
351 color: purple
352 # that was color
353
354 # this is how
355 how: fairlyNice
356 # this is textmode
357 textmode: "true"
358 `
359
360 s, err := FormatInput(strings.NewReader(y))
361 require.NoError(t, err)
362 assert.Equal(t, expected, s.String())
363 }
364
365
366 func TestFormatInput_deployment(t *testing.T) {
367 y := `
368 apiVersion: apps/v1
369 kind: Deployment
370 metadata:
371 name: nginx-deployment
372 labels:
373 app: nginx
374 spec:
375 selector:
376 matchLabels:
377 app: nginx
378 replicas: 3
379 template:
380 metadata:
381 labels:
382 app: nginx
383 spec:
384 containers:
385 # this is a container
386 - ports:
387 # this is a port
388 - containerPort: 80
389 name: b-nginx
390 image: nginx:1.7.9
391 # this is another container
392 - name: a-nginx
393 image: nginx:1.7.9
394 ports:
395 - containerPort: 80
396 `
397 expected := `apiVersion: apps/v1
398 kind: Deployment
399 metadata:
400 name: nginx-deployment
401 labels:
402 app: nginx
403 spec:
404 replicas: 3
405 selector:
406 matchLabels:
407 app: nginx
408 template:
409 metadata:
410 labels:
411 app: nginx
412 spec:
413 containers:
414 # this is another container
415 - name: a-nginx
416 image: nginx:1.7.9
417 ports:
418 - containerPort: 80
419 # this is a container
420 - name: b-nginx
421 image: nginx:1.7.9
422 ports:
423 # this is a port
424 - containerPort: 80
425 `
426 s, err := FormatInput(strings.NewReader(y))
427 require.NoError(t, err)
428 assert.Equal(t, expected, s.String())
429 }
430
431
432 func TestFormatInput_service(t *testing.T) {
433 y := `
434 apiVersion: v1
435 kind: Service
436 metadata:
437 name: my-service
438 spec:
439 selector:
440 app: MyApp
441 ports:
442 - protocol: TCP
443 port: 80
444 targetPort: 9376
445 `
446 expected := `apiVersion: v1
447 kind: Service
448 metadata:
449 name: my-service
450 spec:
451 selector:
452 app: MyApp
453 ports:
454 - protocol: TCP
455 port: 80
456 targetPort: 9376
457 `
458 s, err := FormatInput(strings.NewReader(y))
459 require.NoError(t, err)
460 assert.Equal(t, expected, s.String())
461 }
462
463
464 func TestFormatInput_validatingWebhookConfiguration(t *testing.T) {
465 y := `
466 apiVersion: admissionregistration.k8s.io/v1
467 kind: ValidatingWebhookConfiguration
468 metadata:
469 name: <name of this configuration object>
470 webhooks:
471 - name: <webhook name, e.g., pod-policy.example.io>
472 rules:
473 - apiGroups:
474 - ""
475 apiVersions:
476 - v1
477 operations:
478 - UPDATE # this list is indented by 2
479 - CREATE
480 - CONNECT
481 resources:
482 - pods # this list is not indented by 2
483 scope: "Namespaced"
484 clientConfig:
485 service:
486 namespace: <namespace of the front-end service>
487 name: <name of the front-end service>
488 caBundle: <pem encoded ca cert that signs the server cert used by the webhook>
489 admissionReviewVersions:
490 - v1beta1
491 timeoutSeconds: 1
492 `
493 expected := `apiVersion: admissionregistration.k8s.io/v1
494 kind: ValidatingWebhookConfiguration
495 metadata:
496 name: <name of this configuration object>
497 webhooks:
498 - name: <webhook name, e.g., pod-policy.example.io>
499 admissionReviewVersions:
500 - v1beta1
501 clientConfig:
502 service:
503 name: <name of the front-end service>
504 namespace: <namespace of the front-end service>
505 caBundle: <pem encoded ca cert that signs the server cert used by the webhook>
506 rules:
507 - resources:
508 - pods # this list is not indented by 2
509 apiGroups:
510 - ""
511 apiVersions:
512 - v1
513 operations:
514 - CONNECT
515 - CREATE
516 - UPDATE # this list is indented by 2
517 scope: "Namespaced"
518 timeoutSeconds: 1
519 `
520 s, err := FormatInput(strings.NewReader(y))
521 require.NoError(t, err)
522 assert.Equal(t, expected, s.String())
523 }
524
525
526 func TestFormatInput_unKnownType(t *testing.T) {
527 y := `
528 spec:
529 template:
530 spec:
531 # these shouldn't be sorted because the type isn't whitelisted
532 containers:
533 - name: b
534 - name: a
535 replicas: 1
536 status:
537 conditions:
538 - 3
539 - 1
540 - 2
541 other:
542 b: a1
543 a: b1
544 apiVersion: example.com/v1beta1
545 kind: MyType
546 `
547
548 expected := `apiVersion: example.com/v1beta1
549 kind: MyType
550 spec:
551 replicas: 1
552 template:
553 spec:
554 # these shouldn't be sorted because the type isn't whitelisted
555 containers:
556 - name: b
557 - name: a
558 status:
559 conditions:
560 - 3
561 - 1
562 - 2
563 other:
564 a: b1
565 b: a1
566 `
567 s, err := FormatInput(strings.NewReader(y))
568 require.NoError(t, err)
569 assert.Equal(t, expected, s.String())
570 }
571
572
573 func TestFormatInput_resources(t *testing.T) {
574 input := &bytes.Buffer{}
575 _, err := io.Copy(input, bytes.NewReader(testyaml.UnformattedYaml1))
576 require.NoError(t, err)
577 _, err = io.Copy(input, strings.NewReader("---\n"))
578 require.NoError(t, err)
579 _, err = io.Copy(input, bytes.NewReader(testyaml.UnformattedYaml2))
580 require.NoError(t, err)
581 _, err = io.Copy(input, strings.NewReader("---\n"))
582 require.NoError(t, err)
583 _, err = io.Copy(input, bytes.NewReader(testyaml.UnformattedYaml3))
584 require.NoError(t, err)
585
586 expectedOutput := &bytes.Buffer{}
587 _, err = io.Copy(expectedOutput, bytes.NewReader(testyaml.FormattedYaml1))
588 require.NoError(t, err)
589 _, err = io.Copy(expectedOutput, strings.NewReader("---\n"))
590 require.NoError(t, err)
591 _, err = io.Copy(expectedOutput, bytes.NewReader(testyaml.FormattedYaml2))
592 require.NoError(t, err)
593 _, err = io.Copy(expectedOutput, strings.NewReader("---\n"))
594 require.NoError(t, err)
595 _, err = io.Copy(expectedOutput, bytes.NewReader(testyaml.FormattedYaml3))
596 require.NoError(t, err)
597
598 s, err := FormatInput(input)
599 require.NoError(t, err)
600 assert.Equal(t, expectedOutput.String(), s.String())
601 }
602
603 func TestFormatInput_failMissingKind(t *testing.T) {
604 y := `
605 spec:
606 template:
607 spec:
608 containers:
609 - b
610 - a
611 replicas: 1
612 status:
613 conditions:
614 - 3
615 - 1
616 - 2
617 other:
618 b: a1
619 a: b1
620 apiVersion: example.com/v1beta1
621 `
622
623 b, err := FormatInput(strings.NewReader(y))
624 require.NoError(t, err)
625 assert.Equal(t, strings.TrimLeft(y, "\n"), b.String())
626 }
627
628 func TestFormatInput_failMissingApiVersion(t *testing.T) {
629 y := `
630 spec:
631 template:
632 spec:
633 containers:
634 - a
635 - b
636 replicas: 1
637 status:
638 conditions:
639 - 3
640 - 1
641 - 2
642 other:
643 b: a1
644 a: b1
645 kind: MyKind
646 `
647
648 b, err := FormatInput(strings.NewReader(y))
649 require.NoError(t, err)
650 assert.Equal(t, strings.TrimLeft(y, "\n"), b.String())
651 }
652
653 func TestFormatInput_failUnmarshal(t *testing.T) {
654 y := `
655 spec:
656 template:
657 spec:
658 containers:
659 - a
660 - b
661 replicas: 1
662 status:
663 conditions:
664 - 3
665 - 1
666 - 2
667 other:
668 b: a1
669 a: b1
670 kind: MyKind
671 apiVersion: example.com/v1beta1
672 `
673
674 _, err := FormatInput(strings.NewReader(y))
675 assert.EqualError(t, err, "MalformedYAMLError: yaml: line 15: found character that cannot start any token")
676 }
677
678
679
680 func TestFormatFileOrDirectory_yamlExtFile(t *testing.T) {
681
682 f, err := os.CreateTemp("", "yamlfmt*.yaml")
683 if !assert.NoError(t, err) {
684 return
685 }
686 defer os.Remove(f.Name())
687 err = os.WriteFile(f.Name(), testyaml.UnformattedYaml1, 0600)
688 if !assert.NoError(t, err) {
689 return
690 }
691
692
693 err = FormatFileOrDirectory(f.Name())
694 if !assert.NoError(t, err) {
695 return
696 }
697
698
699 b, err := os.ReadFile(f.Name())
700 if !assert.NoError(t, err) {
701 return
702 }
703 assert.Equal(t, string(testyaml.FormattedYaml1), string(b))
704 }
705
706 func TestFormatFileOrDirectory_multipleYamlEntries(t *testing.T) {
707
708 f, err := os.CreateTemp("", "yamlfmt*.yaml")
709 require.NoError(t, err)
710 defer os.Remove(f.Name())
711 err = os.WriteFile(f.Name(),
712 []byte(string(testyaml.UnformattedYaml1)+"---\n"+string(testyaml.UnformattedYaml2)), 0600)
713 require.NoError(t, err)
714
715
716 err = FormatFileOrDirectory(f.Name())
717 require.NoError(t, err)
718
719
720 b, err := os.ReadFile(f.Name())
721 require.NoError(t, err)
722 assert.Equal(t, string(testyaml.FormattedYaml1)+"---\n"+string(testyaml.FormattedYaml2), string(b))
723 }
724
725
726
727 func TestFormatFileOrDirectory_ymlExtFile(t *testing.T) {
728
729 f, err := os.CreateTemp("", "yamlfmt*.yml")
730 require.NoError(t, err)
731 defer os.Remove(f.Name())
732 err = os.WriteFile(f.Name(), testyaml.UnformattedYaml1, 0600)
733 require.NoError(t, err)
734
735
736 err = FormatFileOrDirectory(f.Name())
737 require.NoError(t, err)
738
739
740 b, err := os.ReadFile(f.Name())
741 require.NoError(t, err)
742 assert.Equal(t, string(testyaml.FormattedYaml1), string(b))
743 }
744
745
746
747 func TestFormatFileOrDirectory_YamlExtFileWithJson(t *testing.T) {
748
749 f, err := os.CreateTemp("", "yamlfmt*.yaml")
750 require.NoError(t, err)
751 defer os.Remove(f.Name())
752 err = os.WriteFile(f.Name(), testyaml.UnformattedJSON1, 0600)
753 require.NoError(t, err)
754
755
756 err = FormatFileOrDirectory(f.Name())
757 require.NoError(t, err)
758
759
760 b, err := os.ReadFile(f.Name())
761 require.NoError(t, err)
762 assert.Equal(t, string(testyaml.FormattedFlowYAML1), string(b))
763 }
764
765
766
767 func TestFormatFileOrDirectory_JsonExtFileWithNotModified(t *testing.T) {
768
769 f, err := os.CreateTemp("", "yamlfmt*.json")
770 require.NoError(t, err)
771 defer os.Remove(f.Name())
772 err = os.WriteFile(f.Name(), testyaml.UnformattedJSON1, 0600)
773 require.NoError(t, err)
774
775
776 err = FormatFileOrDirectory(f.Name())
777 require.NoError(t, err)
778
779
780 b, err := os.ReadFile(f.Name())
781 require.NoError(t, err)
782 assert.Equal(t, string(testyaml.UnformattedJSON1), string(b))
783 }
784
785
786
787 func TestFormatFileOrDirectory_partialKubernetesYamlFile(t *testing.T) {
788
789 f, err := os.CreateTemp("", "yamlfmt*.yaml")
790 require.NoError(t, err)
791 defer os.Remove(f.Name())
792 err = os.WriteFile(f.Name(), []byte(string(testyaml.UnformattedYaml1)+`---
793 status:
794 conditions:
795 - 3
796 - 1
797 - 2
798 spec: a
799 ---
800 `+string(testyaml.UnformattedYaml2)), 0600)
801 require.NoError(t, err)
802
803
804 err = FormatFileOrDirectory(f.Name())
805 require.NoError(t, err)
806
807
808 b, err := os.ReadFile(f.Name())
809 require.NoError(t, err)
810 assert.Equal(t, string(testyaml.FormattedYaml1)+`---
811 status:
812 conditions:
813 - 3
814 - 1
815 - 2
816 spec: a
817 ---
818 `+string(testyaml.FormattedYaml2), string(b))
819 }
820
821
822
823 func TestFormatFileOrDirectory_skipNonKubernetesYamlFile(t *testing.T) {
824
825 f, err := os.CreateTemp("", "yamlfmt*.yaml")
826 require.NoError(t, err)
827 defer os.Remove(f.Name())
828 err = os.WriteFile(f.Name(), []byte(`
829 status:
830 conditions:
831 - 3
832 - 1
833 - 2
834 spec: a
835 `), 0600)
836 require.NoError(t, err)
837
838
839 err = FormatFileOrDirectory(f.Name())
840 require.NoError(t, err)
841
842
843 b, err := os.ReadFile(f.Name())
844 require.NoError(t, err)
845 assert.Equal(t, `status:
846 conditions:
847 - 3
848 - 1
849 - 2
850 spec: a
851 `, string(b))
852 }
853
854
855 func TestFormatFileOrDirectory_skipJsonExtFile(t *testing.T) {
856 f, err := os.CreateTemp("", "yamlfmt*.json")
857 require.NoError(t, err)
858 defer os.Remove(f.Name())
859 err = os.WriteFile(f.Name(), testyaml.UnformattedYaml1, 0600)
860 require.NoError(t, err)
861
862 err = FormatFileOrDirectory(f.Name())
863 require.NoError(t, err)
864
865 b, err := os.ReadFile(f.Name())
866 require.NoError(t, err)
867
868 assert.Equal(t, string(testyaml.UnformattedYaml1), string(b))
869 }
870
871
872
873 func TestFormatFileOrDirectory_directory(t *testing.T) {
874 d := t.TempDir()
875
876 err := os.Mkdir(filepath.Join(d, "config"), 0700)
877 require.NoError(t, err)
878
879 err = os.WriteFile(filepath.Join(d, "c1.yaml"), testyaml.UnformattedYaml1, 0600)
880 require.NoError(t, err)
881
882 err = os.WriteFile(filepath.Join(d, "config", "c2.yaml"), testyaml.UnformattedYaml2, 0600)
883 require.NoError(t, err)
884
885 err = os.WriteFile(filepath.Join(d, "README.md"), []byte(`# Markdown`), 0600)
886 require.NoError(t, err)
887
888 err = FormatFileOrDirectory(d)
889 require.NoError(t, err)
890
891 b, err := os.ReadFile(filepath.Join(d, "c1.yaml"))
892 require.NoError(t, err)
893 assert.Equal(t, string(testyaml.FormattedYaml1), string(b))
894
895 b, err = os.ReadFile(filepath.Join(d, "config", "c2.yaml"))
896 require.NoError(t, err)
897 assert.Equal(t, string(testyaml.FormattedYaml2), string(b))
898
899 b, err = os.ReadFile(filepath.Join(d, "README.md"))
900 require.NoError(t, err)
901 assert.Equal(t, `# Markdown`, string(b))
902
903
904 files := []string{
905 ".", "c1.yaml", "README.md", "config", filepath.Join("config", "c2.yaml")}
906 err = filepath.Walk(d, func(path string, info os.FileInfo, err error) error {
907 require.NoError(t, err)
908 path, err = filepath.Rel(d, path)
909 require.NoError(t, err)
910 assert.Contains(t, files, path)
911 return nil
912 })
913 require.NoError(t, err)
914 }
915
916
917
918 func TestFormatFileOrDirectory_trimWhiteSpace(t *testing.T) {
919 f, err := os.CreateTemp("", "yamlfmt*.yaml")
920 require.NoError(t, err)
921 defer os.Remove(f.Name())
922 err = os.WriteFile(f.Name(), []byte("\n\n"+string(testyaml.UnformattedYaml1)+"\n\n"), 0600)
923 require.NoError(t, err)
924
925 err = FormatFileOrDirectory(f.Name())
926 require.NoError(t, err)
927
928 b, err := os.ReadFile(f.Name())
929 require.NoError(t, err)
930
931 assert.Equal(t, string(testyaml.FormattedYaml1), string(b))
932 }
933
934 func TestFormatFileOrDirectory_FmtAnnotation(t *testing.T) {
935 testCases := []struct {
936 name string
937 input []byte
938 expectedOutput []byte
939 expectError bool
940 }{
941 {
942 name: "no formatting annotation",
943 input: testyaml.UnformattedYaml1,
944 expectedOutput: testyaml.FormattedYaml1,
945 },
946 {
947 name: "formatting strategy none",
948 input: []byte(`
949 spec: a
950 status:
951 conditions:
952 - 3
953 - 1
954 - 2
955 apiVersion: example.com/v1beta1
956 kind: MyType
957 metadata:
958 annotations:
959 config.kubernetes.io/formatting: none
960 `),
961 expectedOutput: []byte(`
962 spec: a
963 status:
964 conditions:
965 - 3
966 - 1
967 - 2
968 apiVersion: example.com/v1beta1
969 kind: MyType
970 metadata:
971 annotations:
972 config.kubernetes.io/formatting: none
973 `),
974 },
975 {
976 name: "formatting strategy standard",
977 input: []byte(`
978 spec: a
979 status:
980 conditions:
981 - 3
982 - 1
983 - 2
984 apiVersion: example.com/v1beta1
985 kind: MyType
986 metadata:
987 annotations:
988 config.kubernetes.io/formatting: standard
989 `),
990 expectedOutput: []byte(`
991 apiVersion: example.com/v1beta1
992 kind: MyType
993 metadata:
994 annotations:
995 config.kubernetes.io/formatting: standard
996 spec: a
997 status:
998 conditions:
999 - 3
1000 - 1
1001 - 2
1002 `),
1003 },
1004 {
1005 name: "unknown formatting strategy",
1006 input: []byte(`
1007 spec: a
1008 status:
1009 conditions:
1010 - 3
1011 - 1
1012 - 2
1013 apiVersion: example.com/v1beta1
1014 kind: MyType
1015 metadata:
1016 annotations:
1017 config.kubernetes.io/formatting: unknown
1018 `),
1019 expectError: true,
1020 },
1021 }
1022
1023 for i := range testCases {
1024 test := testCases[i]
1025 t.Run(test.name, func(t *testing.T) {
1026 f, err := os.CreateTemp("", "yamlfmt*.yaml")
1027 require.NoError(t, err)
1028 defer os.Remove(f.Name())
1029
1030 err = os.WriteFile(f.Name(), test.input, 0600)
1031 require.NoError(t, err)
1032
1033 err = FormatFileOrDirectory(f.Name())
1034 if test.expectError {
1035 require.Error(t, err)
1036 return
1037 }
1038 require.NoError(t, err)
1039
1040 b, err := os.ReadFile(f.Name())
1041 require.NoError(t, err)
1042
1043 assert.Equal(t, strings.TrimSpace(string(test.expectedOutput)),
1044 strings.TrimSpace(string(b)))
1045 })
1046 }
1047 }
1048
1049 func TestFormatInput_NullCases(t *testing.T) {
1050 y := `
1051 apiVersion: v1
1052 kind: Service
1053 metadata:
1054 name: nginx
1055 labels:
1056 app: null
1057 spec:
1058 selector:
1059 app: nginx
1060 ports:
1061 - name: http
1062 port: 80
1063 targetPort: ~
1064 nodePort: null
1065 allocateLoadBalancerNodePorts: null
1066 `
1067
1068
1069 expected := `apiVersion: v1
1070 kind: Service
1071 metadata:
1072 name: nginx
1073 labels:
1074 app: null
1075 spec:
1076 selector:
1077 app: nginx
1078 ports:
1079 - name: http
1080 port: 80
1081 targetPort: ~
1082 nodePort: null
1083 allocateLoadBalancerNodePorts: null
1084 `
1085
1086 buff := &bytes.Buffer{}
1087 err := kio.Pipeline{
1088 Inputs: []kio.Reader{&kio.ByteReader{Reader: strings.NewReader(y)}},
1089 Filters: []kio.Filter{FormatFilter{
1090 UseSchema: true,
1091 }},
1092 Outputs: []kio.Writer{kio.ByteWriter{Writer: buff}},
1093 }.Execute()
1094 require.NoError(t, err)
1095 assert.Equal(t, expected, buff.String())
1096 }
1097
View as plain text