| // Copyright 2021 The Fuchsia 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 codifier |
| |
| import ( |
| "errors" |
| "fmt" |
| "log" |
| "testing" |
| ) |
| |
| func TestScope(t *testing.T) { |
| var p *Proc |
| if p.Scope("foo", "bar") != nil { |
| t.Error("expected nil Proc") |
| } |
| |
| tests := []struct { |
| in, kind, name, outExp string |
| }{ |
| {"", "", "", ""}, |
| {`g("a"){h("b"){c}}`, "g", "a", `g("a"){h("b"){c}}`}, |
| {`g("a"){h("b"){c}}`, "g", "b", ""}, |
| {`g("a"){h("b"){c}}`, "h", "a", ""}, |
| {`h("a"){g("b"){c}}`, "g", "b", `g("b"){c}`}, |
| {`h("a"){g("b"){c}}`, "g", "a", ""}, |
| {`h("a"){i("b"){j}}`, "h", "b", ""}, |
| } |
| |
| for i, tt := range tests { |
| testname := fmt.Sprintf("(%q)[%d]", tt.in, i) |
| t.Run(testname, func(t *testing.T) { |
| p := NewProcFromString(tt.in).Scope(tt.kind, tt.name) |
| if p == nil { |
| if tt.outExp != "" { |
| t.Errorf("want %s, got nil", tt.outExp) |
| } |
| } else { |
| out := p.replacement |
| if out != tt.outExp { |
| t.Errorf("want %s, got %s", tt.outExp, out) |
| } |
| } |
| }) |
| } |
| } |
| |
| func TestScopeNamed(t *testing.T) { |
| var p *Proc |
| if p.ScopeNamed("foo") != nil { |
| t.Error("expected nil Proc") |
| } |
| |
| tests := []struct { |
| in, name, outExp string |
| }{ |
| {"", "", ""}, |
| {`g("a"){g("b"){c}}`, "a", `g("a"){g("b"){c}}`}, |
| {`g("a"){g("b"){c}}`, "b", `g("b"){c}`}, |
| {`g("a"){g("b"){c}}`, "c", ""}, |
| } |
| |
| for i, tt := range tests { |
| testname := fmt.Sprintf("(%q)[%d]", tt.in, i) |
| t.Run(testname, func(t *testing.T) { |
| p := NewProcFromString(tt.in).ScopeNamed(tt.name) |
| if p == nil { |
| if tt.outExp != "" { |
| t.Errorf("want %s, got nil", tt.outExp) |
| } |
| } else { |
| out := p.replacement |
| if out != tt.outExp { |
| t.Errorf("want %s, got %s", tt.outExp, out) |
| } |
| } |
| }) |
| } |
| } |
| |
| func TestScopeOfType(t *testing.T) { |
| var p *Proc |
| if p.scopeOfType("foo") != nil { |
| t.Error("expected nil Proc") |
| } |
| |
| tests := []struct { |
| in, kind, outExp string |
| }{ |
| {"", "", ""}, |
| {`g("a"){h("b"){c}}`, "g", `g("a"){h("b"){c}}`}, |
| {`h("a"){g("b"){c}}`, "g", `g("b"){c}`}, |
| {`h("a"){i("b"){j}}`, "j", ""}, |
| } |
| |
| for i, tt := range tests { |
| testname := fmt.Sprintf("(%q)[%d]", tt.in, i) |
| t.Run(testname, func(t *testing.T) { |
| p := NewProcFromString(tt.in).scopeOfType(tt.kind) |
| if p == nil { |
| if tt.outExp != "" { |
| t.Errorf("want %s, got nil", tt.outExp) |
| } |
| } else { |
| out := p.replacement |
| if out != tt.outExp { |
| t.Errorf("want %s, got %s", tt.outExp, out) |
| } |
| } |
| }) |
| } |
| } |
| |
| func TestAddaddChildScope(t *testing.T) { |
| var p *Proc |
| if p.addChildScope([]SectionType{{Name: "foo"}}, errors.New("foo"), "foo()", "foo", "bar") != nil { |
| t.Error("expected nil Proc") |
| } |
| |
| tests := []struct { |
| scopes []SectionType |
| err error |
| fn, expKind, expName, expCont string |
| expNil bool |
| }{ |
| {nil, nil, "", "", "", "", true}, |
| {nil, nil, "test()", "fki", "fna", "test()", true}, |
| {nil, errors.New("bar"), "test()", "baz", "bim", "test()", true}, |
| {[]SectionType{{Name: "foo"}}, errors.New("bar"), "test()", "baz", "bim", "test()", true}, |
| {[]SectionType{{"fna", "fki", "text"}, {"fna2", "fki2", "text2"}}, nil, "", "", "", "", true}, |
| {[]SectionType{{Kind: "fki", Contents: "text"}}, nil, "test()", "fki", "", "test()", false}, |
| {[]SectionType{{Name: "fna", Contents: "text"}}, nil, "test()", "", "fna", "test()", false}, |
| {[]SectionType{{Name: "fna", Kind: "fki", Contents: "text"}}, nil, "test()", "fki", "fna", "test()", false}, |
| } |
| |
| for i, tt := range tests { |
| testname := fmt.Sprintf("(%v, %v, %q, %q, %q)[%d]", tt.scopes, tt.err, tt.fn, tt.expKind, tt.expName, i) |
| t.Run(testname, func(t *testing.T) { |
| p = newProc() |
| q := p.addChildScope(tt.scopes, tt.err, tt.fn, tt.expKind, tt.expName) |
| if q == nil { |
| if !tt.expNil { |
| t.Error("expected nil Proc") |
| } |
| } else { |
| if tt.expNil { |
| t.Error("expected non-nil Proc") |
| } |
| if q.parent == nil { |
| t.Error("expected non-nil parent") |
| } |
| if q.OriginalContents() != tt.scopes[0].Contents { |
| t.Errorf("want contents: %q, got %q", tt.scopes[0].Contents, q.OriginalContents()) |
| } |
| if q.parent != p { |
| t.Error("q not parented with p") |
| } |
| kind, ok := q.Store[tt.expName].(string) |
| if !ok { |
| t.Errorf("no value for Store[%q]", tt.expName) |
| } |
| if kind != tt.expKind { |
| t.Errorf("want %s, got %s", tt.expKind, kind) |
| } |
| name, ok := q.Store[tt.expKind].(string) |
| if !ok { |
| t.Errorf("no value for Store[%q]", tt.expKind) |
| } |
| if name != tt.expName { |
| t.Errorf("want %s, got %s", tt.expName, name) |
| } |
| } |
| }) |
| } |
| } |
| |
| func TestForEachScopeOfType(t *testing.T) { |
| var p *Proc |
| if p.ForEachScopeOfType(`g{"a"}`, func(i int, r *Proc) *Proc { |
| return r |
| }) != nil { |
| t.Error("expected nil Proc") |
| } |
| |
| if NewProcFromString("foo").ForEachScopeOfType(`g{"a"}`, func(i int, r *Proc) *Proc { |
| return r |
| }) != nil { |
| t.Error("expected nil Proc") |
| } |
| |
| tests := []struct { |
| in, scope, old, new, outExp string |
| }{ |
| {``, ``, ``, ``, ``}, |
| // Two scope types, one of interest 'g'. In that scope, replace bb with a string defined |
| // in the passed in function below: tt.new followed by a dash, followed by the scope index. |
| // So abbc -> a22-0c when tt.new is 22 and the index is 0. |
| {`z("bb")g("b"){abbc}`, "g", "bb", "22", `z("bb")g("b"){a22-0c}`}, |
| // Multiple scopes 'g'. In each scope, replace bb with a string defined in |
| // the passed-in function below: tt.new followed by a dash, followed by the |
| // scope index. |
| {`x("bb")z("bb")g("b"){abbc}g("c"){abbc}g("d"){abbc}`, "g", "bb", "22", |
| `x("bb")z("bb")g("b"){a22-0c}g("c"){a22-1c}g("d"){a22-2c}`}, |
| } |
| |
| for i, tt := range tests { |
| testname := fmt.Sprintf("(%q) with (%s, %s)[%d]", tt.in, tt.scope, tt.old, i) |
| t.Run(testname, func(t *testing.T) { |
| p := NewProcFromString(tt.in).ForEachScopeOfType(tt.scope, func(i int, r *Proc) *Proc { |
| return r.Change(tt.old, fmt.Sprintf("%s-%d", tt.new, i)) |
| }) |
| if p == nil { |
| if tt.outExp != "" { |
| t.Errorf("want %s, got nil", tt.outExp) |
| } |
| } else { |
| out := p.replacement |
| if out != tt.outExp { |
| t.Errorf("want %s, got %s", tt.outExp, out) |
| } |
| } |
| }) |
| } |
| } |
| |
| // Use for Testing only. |
| func newProcFromStrings(o, r string) *Proc { |
| p := NewProcFromString(o) |
| p.replacement = r |
| return p |
| } |
| |
| // Use for Testing only. |
| func (p *Proc) addChildWithStrings(o, r string) *Proc { |
| if p == nil { |
| log.Println(" addChildWithString() error: nil receiver") |
| return nil |
| } |
| q := newProcFromStrings(o, r) |
| q.parent = p |
| return q |
| } |
| |
| func TestApplyChange(t *testing.T) { |
| var p *Proc |
| if p.applyChange() != nil { |
| t.Error("expected nil Proc") |
| } |
| p = NewProcFromString("foo") // Parent is nil. |
| p.replacement = "bar" |
| // So p returned without change. |
| if p.applyChange() == nil || p.original == "bar" { |
| t.Error("expected no change") |
| } |
| } |
| |
| func TestApplyChanges(t *testing.T) { |
| var p *Proc |
| if p.ApplyChanges() != nil { |
| t.Error("expected nil Proc") |
| } |
| |
| tests := []struct { |
| i int |
| p *Proc |
| oExp, rExp string |
| }{ |
| {0, NewProcFromString("a"), "a", "a"}, |
| {1, newProcFromStrings("a", "aa"), "a", "aa"}, |
| {2, newProcFromStrings("ppp", "abba").addChildWithStrings("bb", "s"), "ppp", "asa"}, |
| {3, newProcFromStrings("ppp", "abbba").addChildWithStrings("bbb", "foo").addChildWithStrings("ss", "s1"), "ppp", "afooa"}, |
| {4, newProcFromStrings("ppp", "abbba").addChildWithStrings("bbb", `g("adfd"){ss}`). |
| addChildWithStrings("ss", "sdf").addChildWithStrings("ss", "s1"), "ppp", `ag("adfd"){sdf}a`}, |
| } |
| |
| for i, tt := range tests { |
| testname := fmt.Sprintf("[%d]", i) |
| t.Run(testname, func(t *testing.T) { |
| p := tt.p.ApplyChanges() |
| if p == nil { |
| t.Errorf("want (%s, %s), got p == nil", tt.oExp, tt.rExp) |
| } else { |
| oOut := p.original |
| rOut := p.replacement |
| if oOut != tt.oExp || rOut != tt.rExp { |
| t.Errorf("want (%s, %s), got (%s, %s)", tt.oExp, tt.rExp, oOut, rOut) |
| } |
| } |
| }) |
| } |
| } |