get this shit started
commit
10508bceeb
@ -0,0 +1,83 @@
|
|||||||
|
// +build std
|
||||||
|
|
||||||
|
package thing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSet(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
key string
|
||||||
|
value string
|
||||||
|
bad bool
|
||||||
|
}{
|
||||||
|
{"foo", "bar", false},
|
||||||
|
{"foo", "a-value", false},
|
||||||
|
{"foo", "a value", false},
|
||||||
|
{"one-two-three", "whatever", false},
|
||||||
|
{"one-two-three", "what ever", false},
|
||||||
|
{"one two three", "whatever", true},
|
||||||
|
{" one-two-three", "whatever", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
thing := new(Thing)
|
||||||
|
err := thing.Set(test.key, test.value)
|
||||||
|
if !test.bad && err != nil {
|
||||||
|
t.Errorf("should be able to set %q=%q but saw error %v", test.key, test.value, err)
|
||||||
|
}
|
||||||
|
if test.bad && err == nil {
|
||||||
|
t.Errorf("able to set bad values %q=%q", test.key, test.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHas(t *testing.T) {
|
||||||
|
var (
|
||||||
|
key = "foo"
|
||||||
|
value = "bar"
|
||||||
|
thing = &Thing{
|
||||||
|
data: map[string]string{
|
||||||
|
key: value,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if !thing.Has(key) {
|
||||||
|
t.Errorf("missing expected key %q", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGet(t *testing.T) {
|
||||||
|
var (
|
||||||
|
key = "foo"
|
||||||
|
value = "bar"
|
||||||
|
thing = &Thing{
|
||||||
|
data: map[string]string{
|
||||||
|
key: value,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if v := thing.Get(key); v != value {
|
||||||
|
t.Errorf("read value %q, expected %q", v, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKeys(t *testing.T) {
|
||||||
|
goodKeys := []string{"one", "two", "3", "one-two-three", "steve?"}
|
||||||
|
badKeys := []string{"o n e", "one two three", " one", "one "}
|
||||||
|
|
||||||
|
for _, key := range goodKeys {
|
||||||
|
if err := validateKey(key); err != nil {
|
||||||
|
t.Errorf("key %q should be valid but saw validation error %v", key, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, key := range badKeys {
|
||||||
|
if err := validateKey(key); err == nil {
|
||||||
|
t.Errorf("key %q should be invalid but passed validation", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package tea
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
type Fn func(*testing.T)
|
@ -0,0 +1,34 @@
|
|||||||
|
package tea
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
type step struct {
|
||||||
|
Test
|
||||||
|
next *step
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *step) run(t *testing.T) {
|
||||||
|
t.Logf("running step: %v", s.Test)
|
||||||
|
s.Test.Run(t)
|
||||||
|
if s.next != nil {
|
||||||
|
s.next.run(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tree) plan() []step {
|
||||||
|
if len(t.children) == 0 {
|
||||||
|
// this is a leaf node.
|
||||||
|
s := &step{Test: t.Test}
|
||||||
|
for t.parent != nil {
|
||||||
|
t = t.parent
|
||||||
|
s = &step{Test: t.Test, next: s}
|
||||||
|
}
|
||||||
|
return []step{*s}
|
||||||
|
}
|
||||||
|
|
||||||
|
var steps []step
|
||||||
|
for _, child := range t.children {
|
||||||
|
steps = append(steps, child.plan()...)
|
||||||
|
}
|
||||||
|
return steps
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
package tea
|
@ -0,0 +1,7 @@
|
|||||||
|
package tea
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
type Test interface {
|
||||||
|
Run(*testing.T)
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package tea
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
// Run runs a tree of tests, starting from its root.
|
||||||
|
func Run(t *testing.T, tree *Tree) {
|
||||||
|
plan := tree.plan()
|
||||||
|
t.Logf("steps in plan: %d", len(plan))
|
||||||
|
for _, start := range plan {
|
||||||
|
t.Logf("start test %T: %#v", start.Test, start.Test)
|
||||||
|
start.run(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(test Test) *Tree {
|
||||||
|
return &Tree{Test: test}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tree struct {
|
||||||
|
Test
|
||||||
|
parent *Tree
|
||||||
|
children []*Tree
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tree) Child(test Test) *Tree {
|
||||||
|
child := &Tree{
|
||||||
|
Test: test,
|
||||||
|
parent: t,
|
||||||
|
}
|
||||||
|
t.children = append(t.children, child)
|
||||||
|
return child
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
// +build tea
|
||||||
|
|
||||||
|
package thing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"./tea"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testThingSetup struct {
|
||||||
|
thing *Thing
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *testThingSetup) Run(t *testing.T) {
|
||||||
|
t.Log("Running testThingSetup")
|
||||||
|
test.thing = new(Thing)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test testThingSetup) String() string { return "thingSetup" }
|
||||||
|
|
||||||
|
type setKey struct {
|
||||||
|
key string
|
||||||
|
value string
|
||||||
|
bad bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test setKey) String() string {
|
||||||
|
return fmt.Sprintf("setKey(%q=%q)", test.key, test.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (test *setKey) Run(t *testing.T) {
|
||||||
|
t.Logf("Running setKey key: %q value: %q bad?: %t", test.key, test.value, test.bad)
|
||||||
|
thing := new(Thing)
|
||||||
|
|
||||||
|
err := thing.Set(test.key, test.value)
|
||||||
|
if !test.bad && err != nil {
|
||||||
|
t.Errorf("should be able to set %q=%q but saw error %v", test.key, test.value, err)
|
||||||
|
}
|
||||||
|
if test.bad && err == nil {
|
||||||
|
t.Errorf("able to set bad values %q=%q", test.key, test.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestThing(t *testing.T) {
|
||||||
|
root := tea.New(new(testThingSetup))
|
||||||
|
root.Child(&setKey{key: "alice", value: "apple"})
|
||||||
|
bob := root.Child(&setKey{key: "bob", value: "banana"})
|
||||||
|
bob.Child(&setKey{key: "car-el", value: "candy"})
|
||||||
|
root.Child(&setKey{key: "d' oh", bad: true})
|
||||||
|
tea.Run(t, root)
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package thing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalidKey = errors.New("invalid key")
|
||||||
|
ErrNotFound = errors.New("not found")
|
||||||
|
)
|
||||||
|
|
||||||
|
func validateKey(key string) error {
|
||||||
|
if strings.Count(key, " ") > 0 {
|
||||||
|
return fmt.Errorf("%w: key cannot contain spaces", ErrInvalidKey)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Thing struct {
|
||||||
|
data map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Thing) Get(key string) string {
|
||||||
|
return t.data[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Thing) Set(key, value string) error {
|
||||||
|
if err := validateKey(key); err != nil {
|
||||||
|
return fmt.Errorf("unable to set value for key %q: %w", key, err)
|
||||||
|
}
|
||||||
|
t.data = map[string]string{key: value}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Thing) Has(key string) bool {
|
||||||
|
_, ok := t.data[key]
|
||||||
|
return ok
|
||||||
|
}
|
Loading…
Reference in New Issue