goyave.dev/goyave/v5@v5.0.0-rc9.0.20240517145003-d3f977d0b9f3/lang/lang_test.go (about) 1 package lang 2 3 import ( 4 "os" 5 "path" 6 "runtime" 7 "testing" 8 9 "github.com/stretchr/testify/suite" 10 "goyave.dev/goyave/v5/util/fsutil" 11 "goyave.dev/goyave/v5/util/fsutil/osfs" 12 ) 13 14 type LangTestSuite struct { 15 suite.Suite 16 } 17 18 func setRootWorkingDirectory() { 19 _, filename, _, _ := runtime.Caller(1) 20 directory := path.Dir(filename) 21 for !fsutil.FileExists(&osfs.FS{}, path.Join(directory, "go.mod")) { 22 directory = path.Join(directory, "..") 23 if !fsutil.IsDirectory(&osfs.FS{}, directory) { 24 panic("Couldn't find project's root directory.") 25 } 26 } 27 if err := os.Chdir(directory); err != nil { 28 panic(err) 29 } 30 } 31 32 func (suite *LangTestSuite) SetupSuite() { 33 setRootWorkingDirectory() 34 } 35 36 func (suite *LangTestSuite) TestNew() { 37 l := New() 38 expected := &Languages{ 39 languages: map[string]*Language{enUS.name: enUS}, 40 Default: enUS.name, 41 } 42 suite.Equal(expected, l) 43 } 44 45 func (suite *LangTestSuite) TestLoadError() { 46 l := New() 47 err := l.Load(&osfs.FS{}, "notalanguagedir", "notalanguagepath") 48 suite.Error(err) 49 suite.Len(l.languages, 1) 50 } 51 52 func (suite *LangTestSuite) TestLoadInvalid() { 53 dst := map[string]string{} 54 suite.Error(readLangFile(&osfs.FS{}, "resources/lang/invalid.json", &dst)) 55 } 56 57 func (suite *LangTestSuite) TestLoadOverride() { 58 l := New() 59 err := l.Load(&osfs.FS{}, "en-US", "resources/lang/en-US") 60 suite.NoError(err) 61 suite.Len(l.languages, 1) 62 suite.Equal("rule override", l.languages["en-US"].validation.rules["override"]) 63 suite.Equal("Custom line", l.languages["en-US"].lines["custom-line"]) 64 } 65 66 func (suite *LangTestSuite) TestLoad() { 67 l := New() 68 err := l.Load(&osfs.FS{}, "en-UK", "resources/lang/en-UK") 69 suite.NoError(err) 70 suite.Len(l.languages, 2) 71 expected := &Language{ 72 name: "en-UK", 73 lines: map[string]string{ 74 "malformed-request": "Malformed request", 75 "malformed-json": "Malformed JSON", 76 "test-load": "load UK", 77 }, 78 validation: validationLines{ 79 rules: map[string]string{}, 80 fields: map[string]string{}, 81 }, 82 } 83 suite.Equal(expected, l.languages["en-UK"]) 84 85 err = l.Load(&osfs.FS{}, "en-UK", "resources/lang/en-US") // Overriding en-UK with the lines in en-US 86 suite.NoError(err) 87 suite.Len(l.languages, 2) 88 expected = &Language{ 89 name: "en-UK", 90 lines: map[string]string{ 91 "malformed-request": "Malformed request", 92 "malformed-json": "Malformed JSON", 93 "custom-line": "Custom line", 94 "placeholder": "Line with :placeholders", 95 "many-placeholders": "Line with :count :placeholders", 96 "test-load": "load US", 97 }, 98 validation: validationLines{ 99 rules: map[string]string{ 100 "override": "rule override", 101 "required.array": "The :field values are required.", 102 }, 103 fields: map[string]string{ 104 "email": "email address", 105 }, 106 }, 107 } 108 suite.Equal(expected, l.languages["en-UK"]) 109 } 110 111 func (suite *LangTestSuite) TestLoadAllAvailableLanguages() { 112 l := New() 113 suite.NoError(l.LoadAllAvailableLanguages(&osfs.FS{})) 114 suite.Len(l.languages, 2) 115 suite.Contains(l.languages, "en-US") 116 suite.Contains(l.languages, "en-UK") 117 } 118 119 func (suite *LangTestSuite) TestGetLanguage() { 120 l := New() 121 if err := l.LoadAllAvailableLanguages(&osfs.FS{}); err != nil { 122 suite.Error(err) 123 return 124 } 125 suite.Equal(l.languages["en-UK"], l.GetLanguage("en-UK")) 126 suite.Equal("dummy", l.GetLanguage("fr-FR").Name()) 127 } 128 129 func (suite *LangTestSuite) TestDummyLanguage() { 130 l := New() 131 lang := l.GetLanguage("dummy") 132 suite.Equal("malformed-request", lang.Get("malformed-request")) 133 suite.Equal("validation.rules.required", lang.Get("validation.rules.required")) 134 suite.Equal("validation.fields.email", lang.Get("validation.fields.email")) 135 } 136 137 func (suite *LangTestSuite) TestGetDefault() { 138 l := New() 139 suite.Equal(l.languages["en-US"], l.GetDefault()) 140 } 141 142 func (suite *LangTestSuite) TestIsAvailable() { 143 l := New() 144 suite.True(l.IsAvailable("en-US")) 145 suite.False(l.IsAvailable("fr-FR")) 146 } 147 148 func (suite *LangTestSuite) TestGetAvailableLanguages() { 149 l := New() 150 if err := l.LoadAllAvailableLanguages(&osfs.FS{}); err != nil { 151 suite.Error(err) 152 return 153 } 154 155 suite.ElementsMatch([]string{"en-US", "en-UK"}, l.GetAvailableLanguages()) 156 } 157 158 func (suite *LangTestSuite) TestDetectLanguage() { 159 l := New() 160 if err := l.Load(&osfs.FS{}, "fr-FR", "resources/lang/en-US"); err != nil { 161 panic(err) 162 } 163 164 suite.Equal(l.languages["en-US"], l.DetectLanguage("en")) 165 suite.Equal(l.languages["en-US"], l.DetectLanguage("en-US, fr")) 166 suite.Equal(l.languages["fr-FR"], l.DetectLanguage("fr-FR")) 167 suite.Equal(l.languages["fr-FR"], l.DetectLanguage("fr")) 168 suite.Equal(l.languages["en-US"], l.DetectLanguage("fr, en-US")) 169 suite.Equal(l.languages["fr-FR"], l.DetectLanguage("fr-FR, en-US")) 170 suite.Equal(l.languages["fr-FR"], l.DetectLanguage("fr, en-US;q=0.9")) 171 suite.Equal(l.languages["en-US"], l.DetectLanguage("en, fr-FR;q=0.9")) 172 suite.Equal(l.languages["en-US"], l.DetectLanguage("*")) 173 suite.Equal(l.languages["en-US"], l.DetectLanguage("notalang")) 174 } 175 176 func (suite *LangTestSuite) TestLanguagesGet() { 177 l := New() 178 if err := l.LoadAllAvailableLanguages(&osfs.FS{}); err != nil { 179 suite.Error(err) 180 return 181 } 182 183 suite.Equal("malformed-request", l.Get("fr-FR", "malformed-request")) 184 suite.Equal("Malformed request", l.Get("en-US", "malformed-request")) 185 suite.Equal("Line with awesomeness", l.Get("en-US", "placeholder", ":placeholders", "awesomeness")) 186 } 187 188 func (suite *LangTestSuite) TestGet() { 189 l := New() 190 if err := l.LoadAllAvailableLanguages(&osfs.FS{}); err != nil { 191 suite.Error(err) 192 return 193 } 194 195 lang := l.GetLanguage("en-US") 196 suite.Equal("Malformed request", lang.Get("malformed-request")) 197 suite.Equal("notaline", lang.Get("notaline")) 198 suite.Equal("validation.rules.notarule", lang.Get("validation.rules.notarule")) 199 suite.Equal("validation.rules.notafield", lang.Get("validation.rules.notafield")) 200 suite.Equal("Line with an infinite amount of awesomeness", lang.Get("many-placeholders", ":placeholders", "awesomeness", ":count", "an infinite amount of")) 201 } 202 203 func (suite *LangTestSuite) TestMerge() { 204 dst := &Language{ 205 lines: map[string]string{"line": "line 1"}, 206 validation: validationLines{ 207 rules: map[string]string{}, 208 fields: map[string]string{ 209 "test": "test field", 210 }, 211 }, 212 } 213 src := &Language{ 214 lines: map[string]string{"other": "line 2"}, 215 validation: validationLines{ 216 rules: map[string]string{}, 217 fields: map[string]string{ 218 "email": "email address", 219 "test": "test field override", 220 }, 221 }, 222 } 223 224 mergeLang(dst, src) 225 suite.Equal("line 1", dst.lines["line"]) 226 suite.Equal("line 2", dst.lines["other"]) 227 228 suite.Equal("email address", dst.validation.fields["email"]) 229 230 suite.Equal("test field override", dst.validation.fields["test"]) 231 } 232 233 func (suite *LangTestSuite) TestPlaceholders() { 234 suite.Equal("notaline", convertEmptyLine("notaline", "", []string{":username", "Kevin"})) 235 suite.Equal("Greetings, Kevin", convertEmptyLine("greetings", "Greetings, :username", []string{":username", "Kevin"})) 236 suite.Equal("Greetings, Kevin, today is Monday", convertEmptyLine("greetings", "Greetings, :username, today is :today", []string{":username", "Kevin", ":today", "Monday"})) 237 suite.Equal("Greetings, Kevin, today is :today", convertEmptyLine("greetings", "Greetings, :username, today is :today", []string{":username", "Kevin", ":today"})) 238 } 239 240 func (suite *LangTestSuite) TestSetDefault() { 241 SetDefaultLine("test-line", "It's sunny today") 242 suite.Equal("It's sunny today", enUS.lines["test-line"]) 243 delete(enUS.lines, "test-line") 244 245 SetDefaultValidationRule("test-validation-rules", "It's sunny today") 246 suite.Equal("It's sunny today", enUS.validation.rules["test-validation-rules"]) 247 delete(enUS.validation.rules, "test-validation-rules") 248 249 SetDefaultFieldName("test-field-name", "Sun") 250 suite.Equal("Sun", enUS.validation.fields["test-field-name"]) 251 delete(enUS.validation.fields, "test-field-name") 252 253 // Test no override 254 enUS.validation.fields["test-field"] = "test" 255 SetDefaultFieldName("test-field", "Sun") 256 suite.Equal("Sun", enUS.validation.fields["test-field"]) 257 delete(enUS.validation.fields, "test-field") 258 } 259 260 func TestLangTestSuite(t *testing.T) { 261 suite.Run(t, new(LangTestSuite)) 262 }