From 06bc725f4b34ba0f36bb32aa72cba8b7ed674734 Mon Sep 17 00:00:00 2001 From: Alexander Willing Date: Fri, 10 Mar 2017 14:08:23 +0100 Subject: [PATCH 1/2] use new globbing when pushing locale files --- internal/paths/glob.go | 29 ++ internal/paths/glob_test.go | 50 +++ internal/paths/paths.go | 4 + internal/placeholders/placeholders.go | 3 + internal/placeholders/placeholders_test.go | 41 +++ push.go | 84 ++--- push_pattern_test.go | 361 --------------------- 7 files changed, 153 insertions(+), 419 deletions(-) delete mode 100644 push_pattern_test.go diff --git a/internal/paths/glob.go b/internal/paths/glob.go index 1de1b94..457abe4 100644 --- a/internal/paths/glob.go +++ b/internal/paths/glob.go @@ -19,6 +19,35 @@ func dirGlobOperatorUseValid(pattern string) bool { return !containsOperator || (operatorIsOwnPathSegment || startsWithOperator) } +// SplitAtDirGlobOperator splits pattern at the '**' operator, if it's contained, then splits path accordingly, +// dropping the segments that the '**' operator would have matched against. The returned paths will match the returned patterns. +// An error is returned if the '**' operator is incorrectly used in pattern. +func SplitAtDirGlobOperator(path, pattern string) (pathStart, patternStart, pathEnd, patternEnd string, err error) { + if !dirGlobOperatorUseValid(pattern) { + return "", "", "", "", fmt.Errorf("invalid pattern '%s': the ** globbing operator may only be used as path segment on its own, i.e. …/**/… or **/…", pattern) + } + + parts := strings.Split(pattern, string(filepath.Separator)+dirGlobOperator+string(filepath.Separator)) + patternStart = parts[0] + if len(parts) == 2 { + patternEnd = parts[1] + } + + numSegmentsStart := len(Segments(patternStart)) + numSegmentsEnd := len(Segments(patternEnd)) + + segments := Segments(path) + + pathStart = filepath.Join(segments[:numSegmentsStart]...) + pathEnd = filepath.Join(segments[len(segments)-numSegmentsEnd:]...) + + if strings.HasPrefix(path, "/") && pathStart != "" { + pathStart = "/" + pathStart + } + + return +} + // Glob supports * and ** globbing according to https://phraseapp.com/docs/developers/cli/configuration/#globbing func Glob(pattern string) (matches []string, err error) { pattern = filepath.Clean(pattern) diff --git a/internal/paths/glob_test.go b/internal/paths/glob_test.go index 9ef62bb..01c4032 100644 --- a/internal/paths/glob_test.go +++ b/internal/paths/glob_test.go @@ -147,3 +147,53 @@ func areEqual(s, t []string) bool { return true } + +func TestSplitAtDirGlobOperator(t *testing.T) { + path := "/foo/bla/bar/baz/asd/a/b/c" + + tests := map[string]struct { + pathStart, patternStart, pathEnd, patternEnd string + }{ + "/foo/**/asd/a/b/c": { + "/foo", + "/foo", + "asd/a/b/c", + "asd/a/b/c", + }, + "/foo/*/bar/**/a/*/c": { + "/foo/bla/bar", + "/foo/*/bar", + "a/b/c", + "a/*/c", + }, + "/**/bar/baz/*/a/*/c": { + "", + "", + "bar/baz/asd/a/b/c", + "bar/baz/*/a/*/c", + }, + } + + for pattern, expected := range tests { + pathStart, patternStart, pathEnd, patternEnd, err := SplitAtDirGlobOperator(path, pattern) + if err != nil { + t.Error(err) + } + + if pathStart != expected.pathStart { + t.Errorf("expected path start to be %v, got %v", expected.pathStart, pathStart) + } + + if patternStart != expected.patternStart { + t.Errorf("expected pattern start to be %v, got %v", expected.patternStart, patternStart) + } + + if pathEnd != expected.pathEnd { + t.Errorf("expected path end to be %v, got %v", expected.pathEnd, pathEnd) + } + + if patternEnd != expected.patternEnd { + t.Errorf("expected pattern end to be %v, got %v", expected.patternEnd, patternEnd) + } + } +} diff --git a/internal/paths/paths.go b/internal/paths/paths.go index 1c4b23c..9348f5d 100644 --- a/internal/paths/paths.go +++ b/internal/paths/paths.go @@ -50,5 +50,9 @@ func IsDir(path string) bool { } func Segments(s string) []string { + if s == "" { + return []string{} + } + return strings.FieldsFunc(filepath.Clean(s), func(c rune) bool { return c == filepath.Separator }) } diff --git a/internal/placeholders/placeholders.go b/internal/placeholders/placeholders.go index 17cf2c9..0b717cc 100644 --- a/internal/placeholders/placeholders.go +++ b/internal/placeholders/placeholders.go @@ -36,6 +36,9 @@ func ToGlobbingPattern(s string) string { // Resolve handles '*' wildcards in the pattern, but will return an error // if the pattern contains '**'. func Resolve(s, pattern string) (map[string]string, error) { + s = filepath.Clean(s) + pattern = filepath.Clean(pattern) + if strings.Contains(pattern, "**") { return map[string]string{}, fmt.Errorf("'**' wildcard not allowed in pattern") } diff --git a/internal/placeholders/placeholders_test.go b/internal/placeholders/placeholders_test.go index 63965ba..ca476da 100644 --- a/internal/placeholders/placeholders_test.go +++ b/internal/placeholders/placeholders_test.go @@ -21,6 +21,47 @@ func TestResolve(t *testing.T) { }: { "tag": "bla", }, + { + "config/locales/en.yml", + "config/locales/.yml", + }: { + "locale_code": "en", + }, + { + "abc/defg/en.lproj/Localizable.strings", + "./abc/defg/.lproj/Localizable.strings", + }: { + "locale_code": "en", + }, + { + "config/german/de.yml", + "config//.yml", + }: { + "locale_name": "german", + "locale_code": "de", + }, + { + "config/german/de/de.yml", + "config///*.yml", + }: { + "locale_name": "german", + "locale_code": "de", + }, + { + "abc/en.lproj/MyStoryboard.strings", + "./abc/.lproj/.strings", + }: { + "locale_code": "en", + "tag": "MyStoryboard", + }, + { + "no_tag/abc/play.en", + "*//.", + }: { + "locale_name": "play", + "locale_code": "en", + "tag": "abc", + }, } for input, expected := range tests { diff --git a/push.go b/push.go index 178c224..866a4e0 100644 --- a/push.go +++ b/push.go @@ -12,7 +12,6 @@ import ( "github.com/phrase/phraseapp-client/internal/placeholders" "github.com/phrase/phraseapp-client/internal/print" "github.com/phrase/phraseapp-client/internal/spinner" - "github.com/phrase/phraseapp-client/internal/stringz" "github.com/phrase/phraseapp-go/phraseapp" ) @@ -160,21 +159,18 @@ func (source *Source) LocaleFiles() (LocaleFiles, error) { return nil, err } - patternTokens := paths.Segments(source.File) - var localeFiles LocaleFiles for _, path := range filePaths { - pathTokens := paths.Segments(path) - localeFile := extractParamsFromPathTokens(patternTokens, pathTokens) + localeFile := new(LocaleFile) + localeFile.fillFromPath(path, source.File) - absolutePath, err := filepath.Abs(path) + localeFile.Path, err = filepath.Abs(path) if err != nil { return nil, err } - localeFile.Path = absolutePath - locale := source.getRemoteLocaleForLocaleFile(localeFile) + // TODO: sinnvoll? if locale != nil { localeFile.ExistsRemote = true localeFile.Code = locale.Code @@ -192,13 +188,14 @@ func (source *Source) LocaleFiles() (LocaleFiles, error) { localeFiles = append(localeFiles, localeFile) } - if len(localeFiles) <= 0 { + if len(localeFiles) == 0 { abs, err := filepath.Abs(source.File) if err != nil { abs = source.File } return nil, fmt.Errorf("Could not find any files on your system that matches: '%s'", abs) } + return localeFiles, nil } @@ -261,63 +258,34 @@ func (source *Source) getRemoteLocaleForLocaleFile(localeFile *LocaleFile) *phra } } -func extractParamsFromPathTokens(patternTokens, pathTokens []string) *LocaleFile { - localeFile := new(LocaleFile) - - if Debug { - fmt.Println("pattern:", patternTokens) - fmt.Println("path:", pathTokens) +func (localeFile *LocaleFile) fillFromPath(path, pattern string) { + pathStart, patternStart, pathEnd, patternEnd, err := paths.SplitAtDirGlobOperator(path, pattern) + if err != nil { + print.Error(err) + return } - for idx, patternToken := range patternTokens { - pathToken := pathTokens[idx] - - if patternToken == "*" { - continue - } - if patternToken == "**" { - break + fillFrom := func(path, pattern string) { + params, err := placeholders.Resolve(path, pattern) + if err != nil { + print.Error(err) + return } - localeFile.extractParamFromPathToken(patternToken, pathToken) - } - if stringz.Contains(patternTokens, "**") { - offset := 1 - for idx := len(patternTokens) - 1; idx >= 0; idx-- { - patternToken := patternTokens[idx] - pathToken := pathTokens[len(pathTokens)-offset] - offset += 1 - - if patternToken == "*" { - continue - } else if patternToken == "**" { - break + for placeholder, value := range params { + switch placeholder { + case "locale_code": + localeFile.Code = value + case "locale_name": + localeFile.Name = value + case "tag": + localeFile.Tag = value } - - localeFile.extractParamFromPathToken(patternToken, pathToken) } } - return localeFile -} - -func (localeFile *LocaleFile) extractParamFromPathToken(patternToken, pathToken string) { - params, err := placeholders.Resolve(pathToken, patternToken) - if err != nil { - print.Error(err) - return - } - - for placeholder, value := range params { - switch placeholder { - case "locale_code": - localeFile.Code = value - case "locale_name": - localeFile.Name = value - case "tag": - localeFile.Tag = value - } - } + fillFrom(pathStart, patternStart) + fillFrom(pathEnd, patternEnd) } func (localeFile *LocaleFile) shouldCreateLocale(source *Source) bool { diff --git a/push_pattern_test.go b/push_pattern_test.go deleted file mode 100644 index 0b2e1c0..0000000 --- a/push_pattern_test.go +++ /dev/null @@ -1,361 +0,0 @@ -package main - -import ( - "testing" - - "github.com/phrase/phraseapp-client/internal/paths" -) - -type Patterns []*Pattern - -type Pattern struct { - File string - Ext string - TestPath string - ExpectedCode string - ExpectedName string - ExpectedTag string -} - -func TestSpecialCharacters(t *testing.T) { - patterns := Patterns{ - { - File: "./locales/?*.yml", - Ext: "yml", - TestPath: "locales/?en.yml", - }, - { - File: "./abc+/defg./}{x/][etc??/.yml", - Ext: "yml", - TestPath: "abc+/defg./}{x/][etc??/en.yml", - ExpectedCode: "en", - }, - } - patterns.TestPatterns(t) -} - -func TestSinglePlaceholders(t *testing.T) { - patterns := Patterns{ - { - File: "./.abc/.yml", - Ext: "yml", - TestPath: ".abc/en.yml", - ExpectedCode: "en", - }, - { - File: "./*.yml", - Ext: "yml", - TestPath: "en.yml", - }, - { - File: "./locales/en.yml", - Ext: "yml", - TestPath: "locales/en.yml", - }, - { - File: "./locales/.yml", - Ext: "yml", - TestPath: "locales/en.yml", - }, - { - File: "./abc/defg/.lproj/.strings", - Ext: "strings", - TestPath: "abc/defg/en.lproj/Localizable.strings", - ExpectedCode: "en", - }, - { - File: "./locales/.yml", - Ext: "yml", - TestPath: "locales/en.yml", - ExpectedCode: "en", - }, - { - File: "./abc/.lproj/.strings", - Ext: "strings", - TestPath: "abc/en.lproj/Localizable.strings", - ExpectedCode: "en", - }, - } - patterns.TestPatterns(t) -} - -func TestMultiplePlaceholders(t *testing.T) { - patterns := Patterns{ - { - File: "./config//.yml", - Ext: "yml", - TestPath: "config/abc/en.yml", - ExpectedCode: "en", - ExpectedTag: "abc", - }, - { - File: "./config//.yml", - Ext: "yml", - TestPath: "config/german/de.yml", - ExpectedCode: "de", - ExpectedTag: "", - ExpectedName: "german", - }, - { - File: "./config//*.yml", - Ext: "yml", - TestPath: "config/en/english.yml", - ExpectedCode: "en", - }, - { - File: "./no_tag//.lproj/Localizable.strings", - Ext: "strings", - TestPath: "no_tag/abc/en.lproj/Localizable.strings", - ExpectedCode: "en", - ExpectedTag: "abc", - }, - { - File: "./abc/.lproj/.strings", - Ext: "strings", - TestPath: "abc/en.lproj/MyStoryboard.strings", - ExpectedCode: "en", - ExpectedTag: "MyStoryboard", - }, - { - File: "./*//-values/Strings.xml", - Ext: "xml", - TestPath: "no_tag/abc/en-values/Strings.xml", - ExpectedCode: "en", - ExpectedTag: "abc", - }, - { - File: "./lang//**/*.php", - Ext: "php", - TestPath: "lang/en/hijk/bla/bla/someName.php", - ExpectedCode: "en", - }, - { - File: "./**///.yml", - Ext: "yml", - TestPath: "abc/defg/someTag/english/en.yml", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: "./**///*.yml", - Ext: "yml", - TestPath: "haha/haha/haha/haha/english/someTag/filename.yml", - ExpectedCode: "", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: ".//**/*//*.yml", - Ext: "yml", - TestPath: "english/abc/defg/haha/hahah/hahah/someTag/main.yml", - ExpectedCode: "", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: "./locales/**/.*.yml", - Ext: "yml", - TestPath: "./locales/a/b/my-tag.anything.yml", - ExpectedCode: "", - ExpectedTag: "my-tag", - ExpectedName: "", - }, - { - File: "./locales/**/.*.yml", - Ext: "yml", - TestPath: "./locales/a/b/my-tag.anything.yml", - ExpectedCode: "", - ExpectedTag: "my-tag", - ExpectedName: "", - }, - { - File: "./**/.*/.yml", - Ext: "yml", - TestPath: "./locales/a/my-tag.anything/en.yml", - ExpectedCode: "en", - ExpectedTag: "my-tag", - ExpectedName: "", - }, - } - patterns.TestPatterns(t) -} - -func TestMultipleWithPlaceholderExtension(t *testing.T) { - patterns := Patterns{ - { - File: "./abc//.", - Ext: "", - TestPath: "abc/en/MyStoryboard.english", - ExpectedCode: "en", - ExpectedTag: "MyStoryboard", - ExpectedName: "english", - }, - { - File: "./*//play.", - Ext: "", - TestPath: "no_tag/abc/play.en", - ExpectedCode: "en", - ExpectedTag: "abc", - }, - { - File: "./*//.", - Ext: "", - TestPath: "no_tag/abc/play.en", - ExpectedCode: "en", - ExpectedTag: "abc", - ExpectedName: "play", - }, - { - File: "./**/*.", - Ext: "", - TestPath: "abc/defg/hijk/some_name.english", - ExpectedName: "english", - }, - { - File: "./**/.", - Ext: "", - TestPath: "abc/defg/hijk/someTag.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - }, - { - File: "./**/xyz//.", - Ext: "", - TestPath: "abc/xyz/english/someTag.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: ".///**/*.", - Ext: "", - TestPath: "english/someTag/abc/defg/filename.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: ".///**/*.", - Ext: "", - TestPath: "english/someTag/abc/defg/filename.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: ".//**//*.", - Ext: "", - TestPath: "english/abc/defg/someTag/filename.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: "./_more/**/no_tag/*.", - Ext: "", - TestPath: "english_more/abc/defg/someTagno_tag/filename.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: ".//**//*.", - Ext: "", - TestPath: "english/abc/defg/haha/hahah/hahah/someTag/filename.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: ".///**/*.", - Ext: "", - TestPath: "english/someTag/haha/hahah/hahah/filename.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: "./**///*.", - Ext: "", - TestPath: "haha/haha/haha/haha/english/someTag/filename.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: ".//**/*//main.", - Ext: "", - TestPath: "english/abc/defg/haha/hahah/hahah/someTag/main.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: "./**///*//main.yml", - Ext: "", - TestPath: "haha/haha/haha/en/english/hahah/someTag/main.yml", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: ".//*//**/main.", - Ext: "", - TestPath: "english/xyz/someTag/haha/hahah/hahah/main.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: "./**//*/.", - Ext: "", - TestPath: "haha/haha/haha/hahah/english/hahah/someTag.en", - ExpectedCode: "en", - ExpectedTag: "someTag", - ExpectedName: "english", - }, - { - File: "./**//abc.*/.yml", - Ext: "yml", - TestPath: "./locales/a/english/abc.lol/en.yml", - ExpectedCode: "en", - ExpectedTag: "", - ExpectedName: "english", - }, - { - File: "./a/b//abc.*/**/.yml", - Ext: "yml", - TestPath: "./a/b/english/abc.lol/a/b/c/en.yml", - ExpectedCode: "en", - ExpectedTag: "", - ExpectedName: "english", - }, - } - patterns.TestPatterns(t) -} - -func (patterns Patterns) TestPatterns(t *testing.T) { - for idx, pattern := range patterns { - pattern.TestPattern(t, idx) - } -} - -func (pattern *Pattern) TestPattern(t *testing.T, idx int) { - tokens := paths.Segments(pattern.File) - pathTokens := paths.Segments(pattern.TestPath) - - localeFile := extractParamsFromPathTokens(tokens, pathTokens) - - if localeFile.Code != pattern.ExpectedCode { - t.Errorf("Expected Code to equal '%s' but was '%s' Pattern: %d", pattern.ExpectedCode, localeFile.Code, idx+1) - } - - if localeFile.Tag != pattern.ExpectedTag { - t.Errorf("Expected Tag to equal '%s' but was '%s' Pattern: %d", pattern.ExpectedTag, localeFile.Tag, idx+1) - } - - if localeFile.Name != pattern.ExpectedName { - t.Errorf("Expected LocaleName to equal '%s' but was '%s' Pattern: %d", pattern.ExpectedName, localeFile.Name, idx+1) - } -} From 6829ea123c9755b862cca16dae0b21dc54dc283e Mon Sep 17 00:00:00 2001 From: Matthias Nitsche Date: Thu, 23 Mar 2017 17:40:33 +0100 Subject: [PATCH 2/2] globbing: add old push_tests, test globbing for special file case as well --- internal/placeholders/placeholders.go | 8 +- internal/placeholders/placeholders_test.go | 25 ++ push_test.go | 341 +++++++++++++++++++++ 3 files changed, 373 insertions(+), 1 deletion(-) diff --git a/internal/placeholders/placeholders.go b/internal/placeholders/placeholders.go index 0b717cc..20c2151 100644 --- a/internal/placeholders/placeholders.go +++ b/internal/placeholders/placeholders.go @@ -28,7 +28,13 @@ func ContainsTagPlaceholder(s string) bool { } func ToGlobbingPattern(s string) string { - return anyPlaceholderRegexp.ReplaceAllString(s, "*") + path := anyPlaceholderRegexp.ReplaceAllString(s, "*") + baseName := filepath.Base(s) + extension := filepath.Ext(s) + if baseName == extension { + return strings.Replace(path, baseName, "*"+baseName, 1) + } + return path } // Resolve matches s against pattern and maps placeholders in pattern to diff --git a/internal/placeholders/placeholders_test.go b/internal/placeholders/placeholders_test.go index ca476da..0aae0bd 100644 --- a/internal/placeholders/placeholders_test.go +++ b/internal/placeholders/placeholders_test.go @@ -76,6 +76,31 @@ func TestResolve(t *testing.T) { } } +func TestToGlobbing(t *testing.T) { + tests := []struct { + path string + pattern string + }{ + { + path: "abc/*.lproj/*.strings", + pattern: "abc/.lproj/.strings", + }, { + path: "abc/defg/*.lproj/*.strings", + pattern: "abc/defg/.lproj/.strings", + }, { + path: "abc/defg/*.lproj/Localizable.strings", + pattern: "abc/defg/.lproj/Localizable.strings", + }, + } + for _, test := range tests { + result := ToGlobbingPattern(test.pattern) + + if result != test.path { + t.Errorf("expected result to be %q, but got %q", test.path, result) + } + } +} + func TestResolve_errorPlaceholderReuse(t *testing.T) { tests := []struct { path string diff --git a/push_test.go b/push_test.go index 5f17273..2df1482 100644 --- a/push_test.go +++ b/push_test.go @@ -607,3 +607,344 @@ func TestShouldCreateLocale(t *testing.T) { } } } + +// Push pattern tests +type Patterns []*Pattern + +type Pattern struct { + File string + Ext string + TestPath string + ExpectedCode string + ExpectedName string + ExpectedTag string +} + +func TestSpecialCharacters(t *testing.T) { + patterns := Patterns{ + { + File: "./locales/?*.yml", + Ext: "yml", + TestPath: "locales/?en.yml", + }, + { + File: "./abc+/defg./}{x/][etc??/.yml", + Ext: "yml", + TestPath: "abc+/defg./}{x/][etc??/en.yml", + ExpectedCode: "en", + }, + } + patterns.TestPatterns(t) +} + +func TestSinglePlaceholders(t *testing.T) { + patterns := Patterns{ + { + File: "./.abc/.yml", + Ext: "yml", + TestPath: ".abc/en.yml", + ExpectedCode: "en", + }, + { + File: "./*.yml", + Ext: "yml", + TestPath: "en.yml", + }, + { + File: "./locales/en.yml", + Ext: "yml", + TestPath: "locales/en.yml", + }, + { + File: "./locales/.yml", + Ext: "yml", + TestPath: "locales/en.yml", + }, + { + File: "./locales/.yml", + Ext: "yml", + TestPath: "locales/en.yml", + ExpectedCode: "en", + }, + } + patterns.TestPatterns(t) +} + +func TestMultiplePlaceholders(t *testing.T) { + patterns := Patterns{ + { + File: "./config//.yml", + Ext: "yml", + TestPath: "config/abc/en.yml", + ExpectedCode: "en", + ExpectedTag: "abc", + }, + { + File: "./config//.yml", + Ext: "yml", + TestPath: "config/german/de.yml", + ExpectedCode: "de", + ExpectedTag: "", + ExpectedName: "german", + }, + { + File: "./config//*.yml", + Ext: "yml", + TestPath: "config/en/english.yml", + ExpectedCode: "en", + }, + { + File: "./no_tag//.lproj/Localizable.strings", + Ext: "strings", + TestPath: "no_tag/abc/en.lproj/Localizable.strings", + ExpectedCode: "en", + ExpectedTag: "abc", + }, + { + File: "./abc/.lproj/.strings", + Ext: "strings", + TestPath: "abc/en.lproj/MyStoryboard.strings", + ExpectedCode: "en", + ExpectedTag: "MyStoryboard", + }, + { + File: "./*//-values/Strings.xml", + Ext: "xml", + TestPath: "no_tag/abc/en-values/Strings.xml", + ExpectedCode: "en", + ExpectedTag: "abc", + }, + { + File: "./lang//**/*.php", + Ext: "php", + TestPath: "lang/en/hijk/bla/bla/someName.php", + ExpectedCode: "en", + }, + { + File: "./**///.yml", + Ext: "yml", + TestPath: "abc/defg/someTag/english/en.yml", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: "./**///*.yml", + Ext: "yml", + TestPath: "haha/haha/haha/haha/english/someTag/filename.yml", + ExpectedCode: "", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: ".//**/*//*.yml", + Ext: "yml", + TestPath: "english/abc/defg/haha/hahah/hahah/someTag/main.yml", + ExpectedCode: "", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: "./locales/**/.*.yml", + Ext: "yml", + TestPath: "./locales/a/b/my-tag.anything.yml", + ExpectedCode: "", + ExpectedTag: "my-tag", + ExpectedName: "", + }, + { + File: "./locales/**/.*.yml", + Ext: "yml", + TestPath: "./locales/a/b/my-tag.anything.yml", + ExpectedCode: "", + ExpectedTag: "my-tag", + ExpectedName: "", + }, + { + File: "./**/.*/.yml", + Ext: "yml", + TestPath: "./locales/a/my-tag.anything/en.yml", + ExpectedCode: "en", + ExpectedTag: "my-tag", + ExpectedName: "", + }, + } + patterns.TestPatterns(t) +} + +func TestMultipleWithPlaceholderExtension(t *testing.T) { + patterns := Patterns{ + { + File: "./abc//.", + Ext: "", + TestPath: "abc/en/MyStoryboard.english", + ExpectedCode: "en", + ExpectedTag: "MyStoryboard", + ExpectedName: "english", + }, + { + File: "./*//play.", + Ext: "", + TestPath: "no_tag/abc/play.en", + ExpectedCode: "en", + ExpectedTag: "abc", + }, + { + File: "./*//.", + Ext: "", + TestPath: "no_tag/abc/play.en", + ExpectedCode: "en", + ExpectedTag: "abc", + ExpectedName: "play", + }, + { + File: "./**/*.", + Ext: "", + TestPath: "abc/defg/hijk/some_name.english", + ExpectedName: "english", + }, + { + File: "./**/.", + Ext: "", + TestPath: "abc/defg/hijk/someTag.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + }, + { + File: "./**/xyz//.", + Ext: "", + TestPath: "abc/xyz/english/someTag.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: ".///**/*.", + Ext: "", + TestPath: "english/someTag/abc/defg/filename.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: ".///**/*.", + Ext: "", + TestPath: "english/someTag/abc/defg/filename.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: ".//**//*.", + Ext: "", + TestPath: "english/abc/defg/someTag/filename.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: "./_more/**/no_tag/*.", + Ext: "", + TestPath: "english_more/abc/defg/someTagno_tag/filename.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: ".//**//*.", + Ext: "", + TestPath: "english/abc/defg/haha/hahah/hahah/someTag/filename.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: ".///**/*.", + Ext: "", + TestPath: "english/someTag/haha/hahah/hahah/filename.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: "./**///*.", + Ext: "", + TestPath: "haha/haha/haha/haha/english/someTag/filename.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: ".//**/*//main.", + Ext: "", + TestPath: "english/abc/defg/haha/hahah/hahah/someTag/main.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: "./**///*//main.yml", + Ext: "", + TestPath: "haha/haha/haha/en/english/hahah/someTag/main.yml", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: ".//*//**/main.", + Ext: "", + TestPath: "english/xyz/someTag/haha/hahah/hahah/main.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: "./**//*/.", + Ext: "", + TestPath: "haha/haha/haha/hahah/english/hahah/someTag.en", + ExpectedCode: "en", + ExpectedTag: "someTag", + ExpectedName: "english", + }, + { + File: "./**//abc.*/.yml", + Ext: "yml", + TestPath: "./locales/a/english/abc.lol/en.yml", + ExpectedCode: "en", + ExpectedTag: "", + ExpectedName: "english", + }, + { + File: "./a/b//abc.*/**/.yml", + Ext: "yml", + TestPath: "./a/b/english/abc.lol/a/b/c/en.yml", + ExpectedCode: "en", + ExpectedTag: "", + ExpectedName: "english", + }, + } + patterns.TestPatterns(t) +} + +func (patterns Patterns) TestPatterns(t *testing.T) { + for idx, pattern := range patterns { + pattern.TestPattern(t, idx) + } +} + +func (pattern *Pattern) TestPattern(t *testing.T, idx int) { + localeFile := new(LocaleFile) + localeFile.fillFromPath(pattern.TestPath, pattern.File) + + if localeFile.Code != pattern.ExpectedCode { + t.Errorf("Expected Code to equal '%s' but was '%s' Pattern: %d", pattern.ExpectedCode, localeFile.Code, idx+1) + } + + if localeFile.Tag != pattern.ExpectedTag { + t.Errorf("Expected Tag to equal '%s' but was '%s' Pattern: %d", pattern.ExpectedTag, localeFile.Tag, idx+1) + } + + if localeFile.Name != pattern.ExpectedName { + t.Errorf("Expected LocaleName to equal '%s' but was '%s' Pattern: %d", pattern.ExpectedName, localeFile.Name, idx+1) + } +}