blob: c1c14f371e688a230dcd341a336f885c24b2a5f9 [file] [log] [blame]
// 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)
}
}
})
}
}