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  }