1// +build go1.7 2 3package ini 4 5import ( 6 "encoding/json" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "strings" 11 "testing" 12) 13 14func TestValidDataFiles(t *testing.T) { 15 const expectedFileSuffix = "_expected" 16 filepath.Walk("./testdata/valid", func(path string, info os.FileInfo, err error) error { 17 if strings.HasSuffix(path, expectedFileSuffix) { 18 return nil 19 } 20 21 if info.IsDir() { 22 return nil 23 } 24 25 f, err := os.Open(path) 26 if err != nil { 27 t.Errorf("%s: unexpected error, %v", path, err) 28 } 29 defer f.Close() 30 31 tree, err := ParseAST(f) 32 if err != nil { 33 t.Errorf("%s: unexpected parse error, %v", path, err) 34 } 35 36 v := NewDefaultVisitor() 37 err = Walk(tree, v) 38 if err != nil { 39 t.Errorf("%s: unexpected walk error, %v", path, err) 40 } 41 42 expectedPath := path + "_expected" 43 e := map[string]interface{}{} 44 45 b, err := ioutil.ReadFile(expectedPath) 46 if err != nil { 47 // ignore files that do not have an expected file 48 return nil 49 } 50 51 err = json.Unmarshal(b, &e) 52 if err != nil { 53 t.Errorf("unexpected error during deserialization, %v", err) 54 } 55 56 for profile, tableIface := range e { 57 p, ok := v.Sections.GetSection(profile) 58 if !ok { 59 t.Fatal("could not find profile " + profile) 60 } 61 62 table := tableIface.(map[string]interface{}) 63 for k, v := range table { 64 switch e := v.(type) { 65 case string: 66 a := p.String(k) 67 if e != a { 68 t.Errorf("%s: expected %v, but received %v for profile %v", path, e, a, profile) 69 } 70 case int: 71 a := p.Int(k) 72 if int64(e) != a { 73 t.Errorf("%s: expected %v, but received %v", path, e, a) 74 } 75 case float64: 76 v := p.values[k] 77 if v.Type == IntegerType { 78 a := p.Int(k) 79 if int64(e) != a { 80 t.Errorf("%s: expected %v, but received %v", path, e, a) 81 } 82 } else { 83 a := p.Float64(k) 84 if e != a { 85 t.Errorf("%s: expected %v, but received %v", path, e, a) 86 } 87 } 88 default: 89 t.Errorf("unexpected type: %T", e) 90 } 91 } 92 } 93 94 return nil 95 }) 96} 97 98func TestInvalidDataFiles(t *testing.T) { 99 cases := []struct { 100 path string 101 expectedParseError bool 102 expectedWalkError bool 103 }{ 104 { 105 path: "./testdata/invalid/bad_syntax_1", 106 expectedParseError: true, 107 }, 108 { 109 path: "./testdata/invalid/bad_syntax_2", 110 expectedParseError: true, 111 }, 112 { 113 path: "./testdata/invalid/incomplete_section_profile", 114 expectedParseError: true, 115 }, 116 { 117 path: "./testdata/invalid/syntax_error_comment", 118 expectedParseError: true, 119 }, 120 { 121 path: "./testdata/invalid/invalid_keys", 122 expectedParseError: true, 123 }, 124 { 125 path: "./testdata/invalid/bad_section_name", 126 expectedParseError: true, 127 }, 128 } 129 130 for i, c := range cases { 131 t.Run(c.path, func(t *testing.T) { 132 f, err := os.Open(c.path) 133 if err != nil { 134 t.Errorf("unexpected error, %v", err) 135 } 136 defer f.Close() 137 138 tree, err := ParseAST(f) 139 if err != nil && !c.expectedParseError { 140 t.Errorf("%d: unexpected error, %v", i+1, err) 141 } else if err == nil && c.expectedParseError { 142 t.Errorf("%d: expected error, but received none", i+1) 143 } 144 145 if c.expectedParseError { 146 return 147 } 148 149 v := NewDefaultVisitor() 150 err = Walk(tree, v) 151 if err == nil && c.expectedWalkError { 152 t.Errorf("%d: expected error, but received none", i+1) 153 } 154 }) 155 } 156} 157