// Copyright 2014 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package cldr import ( "fmt" "strings" "testing" ) // A recorder implements the RuleProcessor interface, whereby its methods // simply record the invocations. type recorder struct { calls []string } func (r *recorder) Reset(anchor string, before int) error { if before > 5 { return fmt.Errorf("before %d > 5", before) } r.calls = append(r.calls, fmt.Sprintf("R:%s-%d", anchor, before)) return nil } func (r *recorder) Insert(level int, str, context, extend string) error { s := fmt.Sprintf("O:%d:%s", level, str) if context != "" { s += "|" + context } if extend != "" { s += "/" + extend } r.calls = append(r.calls, s) return nil } func (r *recorder) Index(id string) { r.calls = append(r.calls, fmt.Sprintf("I:%s", id)) } func (r *recorder) Error(err error) { r.calls = append(r.calls, fmt.Sprintf("E:%v", err)) } func TestRuleProcessor(t *testing.T) { for _, tt := range []struct { desc string in string out string }{ {desc: "empty"}, {desc: "whitespace and comments only", in: ` # adsfads # adfadf `, }, { desc: "reset anchor", in: ` & a &b # & [ before 3 ] c & [before 4] d & ee & [first tertiary ignorable] &'g' & 'h''h'h'h' &'\u0069' # LATIN SMALL LETTER I `, out: ` R:a-0 R:b-0 R:c-3 R:d-4 R:ee-0 R:-0 R:g-0 R:hhhh-0 R:i-0 `, }, { desc: "ordering", in: ` & 0 < 1 <<''2# <<< 3'3''33'3# <<<<4 = 5 << 6 | s <<<< 7 / z << 8'' | s / ch `, out: ` R:0-0 O:1:1 O:2:'2 O:3:33333 O:4:4 O:5:5 O:2:6|s O:4:7/z O:2:8'|s/ch `, }, { desc: "index", in: "< '\ufdd0'A", out: "I:A", }, { desc: "sequence", in: ` & 0 <<* 1234 <* a-cde-f =* q-q `, out: ` R:0-0 O:2:1 O:2:2 O:2:3 O:2:4 O:1:a O:1:b O:1:c O:1:d O:1:e O:1:f O:5:q `, }, { desc: "compact", in: "&B 5", }, { desc: "err empty order", in: " < ", out: "E:1: missing string", }, { desc: "err empty identity", in: " = ", out: "E:1: missing string", }, { desc: "err empty context", in: " < a | ", out: "E:1: missing string after context", }, { desc: "err empty extend", in: " < a / ", out: "E:1: missing string after extension", }, { desc: "err empty sequence", in: " <* ", out: "E:1: empty sequence", }, { desc: "err sequence 1", in: " <* -a", out: "E:1: range without starter value", }, { desc: "err sequence 3", in: " <* a-a-b", out: `O:1:a E:1: range without starter value `, }, { desc: "err sequence 3", in: " <* b-a", out: `O:1:b E:1: invalid range 'b'-'a' `, }, { desc: "err unmatched quote", in: " < 'b", out: ` E:1: unmatched single quote `, }, } { rec := &recorder{} err := Collation{ Cr: []*Common{ {hidden: hidden{CharData: tt.in}}, }, }.Process(rec) if err != nil { rec.Error(err) } got := rec.calls want := strings.Split(strings.TrimSpace(tt.out), "\n") if tt.out == "" { want = nil } if len(got) != len(want) { t.Errorf("%s: nResults: got %d; want %d", tt.desc, len(got), len(want)) continue } for i, g := range got { if want := strings.TrimSpace(want[i]); g != want { t.Errorf("%s:%d: got %q; want %q", tt.desc, i, g, want) } } } }