import testing package
This commit is contained in:
parent
e5e216708a
commit
81d96f305f
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 rosskeenhouse
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
40
README.md
40
README.md
@ -1,3 +1,39 @@
|
|||||||
# testing
|
# Test Fixtures in Go
|
||||||
|
|
||||||
Test Fixtures
|
The purpose of this package is to provide a simple tool for creating test fixtures for go tests.
|
||||||
|
|
||||||
|
## What is a fixture?
|
||||||
|
|
||||||
|
A test fixture is generally used as a mechanism to provide consistent, repeatable state when testing software.
|
||||||
|
|
||||||
|
## Adding Fixtures
|
||||||
|
|
||||||
|
A fixture can be as simple as a function that returns a static value or it can leverage parameters to run the same test with different values. You can also provide a matching result set to make it easier to verify the expected results.
|
||||||
|
|
||||||
|
```
|
||||||
|
// A fixture returns some data, often based on some input parameter
|
||||||
|
func FixtureExample(p fixture.Param) interface{} {
|
||||||
|
return fmt.Sprintf("data %s", p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExample(t *testing.T) {
|
||||||
|
// you may define a result set for verification
|
||||||
|
r := fixture.R([]fixture.Result{"I do not like your data here","I do not like your data there","I do not like your data anywhere"})
|
||||||
|
|
||||||
|
// creating a parameterized fixture will cause the test to be executed for parameter
|
||||||
|
p := fixture.P([]fixture.Param{"here","there","anywhere"})
|
||||||
|
|
||||||
|
f := fixture.New(t, FixtureExample, p, r)
|
||||||
|
|
||||||
|
// The test body will be run 3 times (once for each parameter)
|
||||||
|
f.RunWith(
|
||||||
|
func (t *testing.T) {
|
||||||
|
fv := f.Fixture()
|
||||||
|
test_result := fmt.Sprintf("I do not like your %s", fv)
|
||||||
|
// Verify the test a result that matches the result set
|
||||||
|
f.AssertStrEq(test_result)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
139
fixture/fixture.go
Normal file
139
fixture/fixture.go
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
package fixture
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"strconv"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Test func(t *testing.T)
|
||||||
|
|
||||||
|
type F func(p Param) interface{}
|
||||||
|
|
||||||
|
type Ft struct {
|
||||||
|
*testing.T
|
||||||
|
params ParamReader
|
||||||
|
fixture F
|
||||||
|
data []interface{}
|
||||||
|
results ResultReader
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(t *testing.T, f F, p ParamReader, r ResultReader) *Ft {
|
||||||
|
return &Ft{ T: t, params: p, fixture: f, results: r }
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) Fixture() []interface{} {
|
||||||
|
return f.data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) Value() interface{} {
|
||||||
|
return f.data[len(f.data) - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) Result() interface{} {
|
||||||
|
return f.results.Values()[len(f.data) - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) RunWith(t Test) {
|
||||||
|
f.data = nil
|
||||||
|
for i, r := range(f.params.Values()) {
|
||||||
|
f.data = append(f.data, f.fixture(r))
|
||||||
|
f.Run(strconv.Itoa(i), t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) assertOp(value interface{}, o func (a interface{}, b interface{}) bool) {
|
||||||
|
r := f.Result()
|
||||||
|
if ! o(r, value) {
|
||||||
|
f.Errorf("Failure: value does not match expected result: [%s] != [%s]", r, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) AssertStrEq(value string) {
|
||||||
|
f.assertOp(value, func (a interface{}, b interface{}) bool { return a.(string) == b.(string) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) AssertEq(value interface{}) {
|
||||||
|
cmpOp := func (a, b interface{}) bool {
|
||||||
|
rType := reflect.TypeOf(a)
|
||||||
|
switch rType.Name() {
|
||||||
|
case "float64", "float32":
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Float() == reflect.ValueOf(b).Convert(rType).Float()
|
||||||
|
default:
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Int() == reflect.ValueOf(b).Convert(rType).Int()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.assertOp(value, cmpOp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) AssertGt(value interface{}) {
|
||||||
|
cmpOp := func (a, b interface{}) bool {
|
||||||
|
rType := reflect.TypeOf(a)
|
||||||
|
switch rType.Name() {
|
||||||
|
case "float64", "float32":
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Float() > reflect.ValueOf(b).Convert(rType).Float()
|
||||||
|
default:
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Int() > reflect.ValueOf(b).Convert(rType).Int()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.assertOp(value, cmpOp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) AssertGe(value interface{}) {
|
||||||
|
cmpOp := func (a, b interface{}) bool {
|
||||||
|
rType := reflect.TypeOf(a)
|
||||||
|
switch rType.Name() {
|
||||||
|
case "float64", "float32":
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Float() >= reflect.ValueOf(b).Convert(rType).Float()
|
||||||
|
default:
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Int() >= reflect.ValueOf(b).Convert(rType).Int()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.assertOp(value, cmpOp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) AssertLt(value interface{}) {
|
||||||
|
cmpOp := func (a, b interface{}) bool {
|
||||||
|
rType := reflect.TypeOf(a)
|
||||||
|
switch rType.Name() {
|
||||||
|
case "float64", "float32":
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Float() < reflect.ValueOf(b).Convert(rType).Float()
|
||||||
|
default:
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Int() < reflect.ValueOf(b).Convert(rType).Int()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.assertOp(value, cmpOp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) AssertLe(value interface{}) {
|
||||||
|
cmpOp := func (a, b interface{}) bool {
|
||||||
|
rType := reflect.TypeOf(a)
|
||||||
|
switch rType.Name() {
|
||||||
|
case "float64", "float32":
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Float() <= reflect.ValueOf(b).Convert(rType).Float()
|
||||||
|
default:
|
||||||
|
return reflect.ValueOf(a).Convert(rType).Int() <= reflect.ValueOf(b).Convert(rType).Int()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.assertOp(value, cmpOp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ft) Assert() {
|
||||||
|
r := f.results.Values()
|
||||||
|
i := len(f.data) - 1
|
||||||
|
data := f.data[i]
|
||||||
|
res := r[i]
|
||||||
|
switch r[i].(type) {
|
||||||
|
case string:
|
||||||
|
data = string(f.data[i].([]byte))
|
||||||
|
res = string(r[i].(string))
|
||||||
|
}
|
||||||
|
if data != res {
|
||||||
|
f.Errorf("Failed value does not match expected result: [%s] != [%s]", f.data[i], r[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
51
fixture/fixture_test.go
Normal file
51
fixture/fixture_test.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package fixture_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"math"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/fixture"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Fixture2Pow(p fixture.Param) interface{} {
|
||||||
|
return math.Exp2(p.(float64))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewFixture(t *testing.T) {
|
||||||
|
f := fixture.New(t, Fixture2Pow, fixture.P([]fixture.Param{1.0,2.0,3.0}), fixture.R([]fixture.Result{2.0,4.0,8.0}))
|
||||||
|
|
||||||
|
f.RunWith(
|
||||||
|
func (t *testing.T) {
|
||||||
|
f.Fixture()
|
||||||
|
f.Assert()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TargetMul2(input float64) float64 {
|
||||||
|
return input * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAssertGe(t *testing.T) {
|
||||||
|
f := fixture.New(t, Fixture2Pow, fixture.P([]fixture.Param{1.0,2.0,3.0}), fixture.R([]fixture.Result{4.0,8.0,16.0}))
|
||||||
|
|
||||||
|
f.RunWith(
|
||||||
|
func (t *testing.T) {
|
||||||
|
pow := f.Value()
|
||||||
|
result := TargetMul2(pow.(float64))
|
||||||
|
f.AssertGe(float32(result))
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAssertEq(t *testing.T) {
|
||||||
|
f := fixture.New(t, Fixture2Pow, fixture.P([]fixture.Param{1.0,2.0,3.0}), fixture.R([]fixture.Result{4.0,8.0,16.0}))
|
||||||
|
|
||||||
|
f.RunWith(
|
||||||
|
func (t *testing.T) {
|
||||||
|
pow := f.Value()
|
||||||
|
result := TargetMul2(pow.(float64))
|
||||||
|
f.AssertEq(float32(result))
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
32
fixture/params.go
Normal file
32
fixture/params.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package fixture
|
||||||
|
|
||||||
|
import (
|
||||||
|
)
|
||||||
|
|
||||||
|
// Fixture params are a list of values used to initialize a fixture
|
||||||
|
type Param interface{}
|
||||||
|
|
||||||
|
type ParamReader interface {
|
||||||
|
Values() []Param
|
||||||
|
Read() <-chan Param
|
||||||
|
}
|
||||||
|
|
||||||
|
type Parameters struct {
|
||||||
|
values []Param
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize parameters from a slice
|
||||||
|
func P(v []Param) *Parameters { return &Parameters{ values: v } }
|
||||||
|
|
||||||
|
func (p *Parameters) Values() []Param {
|
||||||
|
return p.values
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parameters) Read() <-chan Param {
|
||||||
|
rc := make(chan Param, len(p.values))
|
||||||
|
for i := range(p.Values()) {
|
||||||
|
rc <- i
|
||||||
|
}
|
||||||
|
return rc
|
||||||
|
}
|
30
fixture/results.go
Normal file
30
fixture/results.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package fixture
|
||||||
|
|
||||||
|
import (
|
||||||
|
)
|
||||||
|
|
||||||
|
type Result interface{}
|
||||||
|
|
||||||
|
type ResultReader interface {
|
||||||
|
Values() []Result
|
||||||
|
Read() <-chan Result
|
||||||
|
}
|
||||||
|
|
||||||
|
type Results struct {
|
||||||
|
values []Result
|
||||||
|
}
|
||||||
|
|
||||||
|
func R(v []Result) *Results { return &Results{ values: v } }
|
||||||
|
|
||||||
|
func (r *Results) Values() []Result {
|
||||||
|
return r.values
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Results) Read() <-chan Result {
|
||||||
|
rc := make(chan Result, len(r.values))
|
||||||
|
for i := range(r.Values()) {
|
||||||
|
rc <- i
|
||||||
|
}
|
||||||
|
return rc
|
||||||
|
}
|
17
fixtures/README.md
Normal file
17
fixtures/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Ex.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func TestSample(t *testing.T) {
|
||||||
|
f := fixtures.New(t, fixtures.TestDataInit{})
|
||||||
|
f.RunWith(Test(func (t *testing.T) {
|
||||||
|
d := f.GetData('')
|
||||||
|
f.Successful
|
||||||
|
|
||||||
|
r,e := MySample(d)
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
18
fixtures/fixture_test.go
Normal file
18
fixtures/fixture_test.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package fixtures_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Fixture16bit(t *testing.T) interface{} {
|
||||||
|
return 65536
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFixture(t *testing.T) {
|
||||||
|
var f Ft = Fixture16bit
|
||||||
|
var t Test {
|
||||||
|
|
||||||
|
}
|
||||||
|
t.RunWith(f,
|
||||||
|
}
|
39
fixtures/fixtures.go
Normal file
39
fixtures/fixtures.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package fixtures
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fixture set type
|
||||||
|
type Ft func(t *testing.T, input interface{}) []interface{}
|
||||||
|
|
||||||
|
// Defines a fixture which can return a slice of values
|
||||||
|
type F struct {
|
||||||
|
name string
|
||||||
|
func []Getter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *F) AddGetter(ft Getter) {
|
||||||
|
append(f.func, ft)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Ft func(t *testing.T) interface{}
|
||||||
|
|
||||||
|
func (f *Ft) Get(t *testing.T) {
|
||||||
|
return f(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getter interface
|
||||||
|
type Getter interface {
|
||||||
|
Get() interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type F struct {
|
||||||
|
*testing.T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *F) RunWith(t *testing.T, data interface{}) {
|
||||||
|
|
||||||
|
}
|
41
fixtures/testdata.go
Normal file
41
fixtures/testdata.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package fixtures
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"log"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *F) FixtureTestDataBasePath() string {
|
||||||
|
g := fmt.Sprintf("fixture_%s_", f.Name())
|
||||||
|
p := filepath.Join("./testdata", g)
|
||||||
|
d := filepath.Join(g,p)
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *F) FixtureTestDataPaths() []string {
|
||||||
|
p := f.FixtureTestDataBasePath()
|
||||||
|
df, e := filepath.Glob(p + "*")
|
||||||
|
if e != nil {
|
||||||
|
log.Fatal(e)
|
||||||
|
}
|
||||||
|
return df
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *F) FixtureTestData() {
|
||||||
|
bp := f.FixtureTestDataBasePath()
|
||||||
|
df := f.FixtureTestDataPaths()
|
||||||
|
for i, d := range(df) {
|
||||||
|
subtestname := strings.TrimPrefix(d, bp)
|
||||||
|
if subtestname == d {
|
||||||
|
subtestname = strconv.Itoa(i)
|
||||||
|
}
|
||||||
|
data,_ := ioutil.ReadFile(d)
|
||||||
|
f.Run(f.Name() + "." + subtestname, func (t *testing.T) { f.RunWith(f.T, data) })
|
||||||
|
}
|
||||||
|
}
|
10
fixtures/testdata_test.go
Normal file
10
fixtures/testdata_test.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package fixtures_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFixtureTestData(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
24
fixtures/tester.go
Normal file
24
fixtures/tester.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package fixtures
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Test func(t *testing.T)
|
||||||
|
|
||||||
|
type Tester interface {
|
||||||
|
Test(t *testing.T)
|
||||||
|
RunWith(t *testing.T, f []Ft)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tf Test) Test(t *testing.T) {
|
||||||
|
tf(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tf Test) RunWith(t *testing.T, f []Ft) {
|
||||||
|
for i, fixture := range(f) {
|
||||||
|
t.Run(t.Name() + strconv.Itoa(i), tf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module testing
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
|
require gopkg.in/yaml.v2 v2.3.0
|
3
go.sum
Normal file
3
go.sum
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
25
md/mockdata.go
Normal file
25
md/mockdata.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package mockdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "testing"
|
||||||
|
// "io/ioutil"
|
||||||
|
// "path/filepath"
|
||||||
|
// "log"
|
||||||
|
// "fmt"
|
||||||
|
// "strings"
|
||||||
|
// "strconv"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/fixture"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Raw file fixture data
|
||||||
|
|
||||||
|
func FixtureMockFile(p fixture.Param) interface{} {
|
||||||
|
mp := p.(MockParam)
|
||||||
|
return Read(mp.param.(string), mp.mock())
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResultMockFile(p fixture.Result) interface{} {
|
||||||
|
mp := p.(MockParam)
|
||||||
|
return Read(mp.param.(string), mp.mock())
|
||||||
|
}
|
33
md/mockdata_test.go
Normal file
33
md/mockdata_test.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package mockdata_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/fixture"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/md"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MockDataTest struct {
|
||||||
|
foo int
|
||||||
|
bar int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMock() interface{} {
|
||||||
|
return &MockDataTest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMDFixture(t *testing.T) {
|
||||||
|
//r := fixture.R([]fixture.Result{"empty"})
|
||||||
|
//"./testdat/fixture_TestTDFixture_empty.yml"})
|
||||||
|
f := fixture.New(t, mockdata.FixtureMockFile, mockdata.P(t.Name(), NewMock), nil)
|
||||||
|
|
||||||
|
f.RunWith(
|
||||||
|
func (t *testing.T) {
|
||||||
|
o := f.Value()
|
||||||
|
var d *MockDataTest = o.(*MockDataTest)
|
||||||
|
if d.foo != 3 {
|
||||||
|
t.Errorf("Failed to load mock object")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
78
md/params.go
Normal file
78
md/params.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package mockdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
"log"
|
||||||
|
"fmt"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/fixture"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Return a structure to load the mock data into
|
||||||
|
type MockObjectFn func() interface{}
|
||||||
|
|
||||||
|
type MockParam struct {
|
||||||
|
param fixture.Param
|
||||||
|
mock MockObjectFn
|
||||||
|
}
|
||||||
|
|
||||||
|
type Parameters struct {
|
||||||
|
*fixture.Parameters
|
||||||
|
name string
|
||||||
|
basepath string
|
||||||
|
mockdata MockObjectFn
|
||||||
|
}
|
||||||
|
|
||||||
|
func P(name string, mockdata MockObjectFn) *Parameters { return &Parameters{ name: name, mockdata: mockdata } }
|
||||||
|
|
||||||
|
// mockdata.BasePath('./testdata/mock_{testname}_')
|
||||||
|
func (p *Parameters) BasePath() string {
|
||||||
|
if p.basepath == "" {
|
||||||
|
g := fmt.Sprintf("mock_%s_", p.name)
|
||||||
|
p.basepath = filepath.Join("./testdata", g)
|
||||||
|
}
|
||||||
|
return p.basepath
|
||||||
|
}
|
||||||
|
|
||||||
|
// mockdata.Paths(base string)
|
||||||
|
func (p *Parameters) Paths() []string {
|
||||||
|
df, e := filepath.Glob(p.BasePath() + "*")
|
||||||
|
if e != nil {
|
||||||
|
log.Fatal(e)
|
||||||
|
}
|
||||||
|
return df
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parameters) Values() []fixture.Param {
|
||||||
|
// return TestData files
|
||||||
|
paths := p.Paths()
|
||||||
|
r := make([]fixture.Param, len(paths))
|
||||||
|
for i := range(paths) {
|
||||||
|
r[i] = MockParam { param: paths[i], mock: p.mockdata }
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func Read(path string, mockdata interface{}) interface{} {
|
||||||
|
d,e := ioutil.ReadFile(path)
|
||||||
|
if e != nil {
|
||||||
|
log.Fatalf("Error reading fixture data from %s: %s", path, e)
|
||||||
|
}
|
||||||
|
err := yaml.Unmarshal([]byte(d), mockdata)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
}
|
||||||
|
return mockdata
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadRaw(path string) interface{} {
|
||||||
|
d,e := ioutil.ReadFile(path)
|
||||||
|
if e != nil {
|
||||||
|
log.Fatalf("Error reading fixture data from %s: %s", path, e)
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
|
43
md/results.go
Normal file
43
md/results.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package mockdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"log"
|
||||||
|
"fmt"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/fixture"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Results struct {
|
||||||
|
*fixture.Results
|
||||||
|
name string
|
||||||
|
basepath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func R(name string) *Results { return &Results{ name: name } }
|
||||||
|
|
||||||
|
func (r *Results) BasePath() string {
|
||||||
|
if r.basepath == "" {
|
||||||
|
g := fmt.Sprintf("result_%s_", r.name)
|
||||||
|
r.basepath = filepath.Join("./testdata", g)
|
||||||
|
}
|
||||||
|
return r.basepath
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Results) Paths() []string {
|
||||||
|
df, e := filepath.Glob(r.BasePath() + "*")
|
||||||
|
if e != nil {
|
||||||
|
log.Fatal(e)
|
||||||
|
}
|
||||||
|
return df
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Results) Values() []fixture.Result {
|
||||||
|
// return MockData files
|
||||||
|
paths := r.Paths()
|
||||||
|
res := make([]fixture.Result, len(paths))
|
||||||
|
for i := range(paths) {
|
||||||
|
res[i] = ReadRaw(paths[i])
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
2
md/testdata/mock_MDFixture_simple.yml
vendored
Normal file
2
md/testdata/mock_MDFixture_simple.yml
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
foo: 3
|
||||||
|
bar: 5
|
57
td/params.go
Normal file
57
td/params.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"log"
|
||||||
|
"fmt"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/fixture"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type Parameters struct {
|
||||||
|
*fixture.Parameters
|
||||||
|
name string
|
||||||
|
basepath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func P(name string) *Parameters { return &Parameters{ name: name } }
|
||||||
|
|
||||||
|
// testdata.BasePath('./testdata/fixture_{testname}_')
|
||||||
|
func (p *Parameters) BasePath() string {
|
||||||
|
if p.basepath == "" {
|
||||||
|
g := fmt.Sprintf("fixture_%s_", p.name)
|
||||||
|
p.basepath = filepath.Join("./testdata", g)
|
||||||
|
}
|
||||||
|
return p.basepath
|
||||||
|
}
|
||||||
|
|
||||||
|
// testdata.Paths(base string)
|
||||||
|
func (p *Parameters) Paths() []string {
|
||||||
|
df, e := filepath.Glob(p.BasePath() + "*")
|
||||||
|
if e != nil {
|
||||||
|
log.Fatal(e)
|
||||||
|
}
|
||||||
|
return df
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parameters) Values() []fixture.Param {
|
||||||
|
// return TestData files
|
||||||
|
paths := p.Paths()
|
||||||
|
r := make([]fixture.Param, len(paths))
|
||||||
|
for i := range(paths) {
|
||||||
|
r[i] = paths[i]
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func Read(path string) []byte {
|
||||||
|
d,e := ioutil.ReadFile(path)
|
||||||
|
if e != nil {
|
||||||
|
log.Fatalf("Error reading fixture data from %s: %s", path, e)
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
|
48
td/results.go
Normal file
48
td/results.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"log"
|
||||||
|
"fmt"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/fixture"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TypeConversion func(value interface{}) interface{}
|
||||||
|
|
||||||
|
type Results struct {
|
||||||
|
*fixture.Results
|
||||||
|
name string
|
||||||
|
basepath string
|
||||||
|
convert TypeConversion
|
||||||
|
}
|
||||||
|
|
||||||
|
func NoConversion(value interface{}) interface{} { return value }
|
||||||
|
func R(name string) *Results { return &Results{ name: name, convert: NoConversion } }
|
||||||
|
func Rt(name string, convert TypeConversion) *Results { return &Results{ name: name, convert: convert } }
|
||||||
|
|
||||||
|
func (r *Results) BasePath() string {
|
||||||
|
if r.basepath == "" {
|
||||||
|
g := fmt.Sprintf("result_%s_", r.name)
|
||||||
|
r.basepath = filepath.Join("./testdata", g)
|
||||||
|
}
|
||||||
|
return r.basepath
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Results) Paths() []string {
|
||||||
|
df, e := filepath.Glob(r.BasePath() + "*")
|
||||||
|
if e != nil {
|
||||||
|
log.Fatal(e)
|
||||||
|
}
|
||||||
|
return df
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Results) Values() []fixture.Result {
|
||||||
|
// return TestData files
|
||||||
|
paths := r.Paths()
|
||||||
|
res := make([]fixture.Result, len(paths))
|
||||||
|
for i := range(paths) {
|
||||||
|
res[i] = r.convert(string(Read(paths[i])))
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
23
td/testdata.go
Normal file
23
td/testdata.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "testing"
|
||||||
|
// "io/ioutil"
|
||||||
|
// "path/filepath"
|
||||||
|
// "log"
|
||||||
|
// "fmt"
|
||||||
|
// "strings"
|
||||||
|
// "strconv"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/fixture"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Raw file fixture data
|
||||||
|
|
||||||
|
func FixtureRawFile(p fixture.Param) interface{} {
|
||||||
|
return Read(p.(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResultRawFile(p fixture.Result) interface{} {
|
||||||
|
return Read(p.(string))
|
||||||
|
}
|
1
td/testdata/fixture_TestTDFixtureTypeConversion_int.txt
vendored
Normal file
1
td/testdata/fixture_TestTDFixtureTypeConversion_int.txt
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
199
|
1
td/testdata/fixture_TestTDFixture_empty.yml
vendored
Normal file
1
td/testdata/fixture_TestTDFixture_empty.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
empty
|
1
td/testdata/result_TestTDFixtureTypeConversion_int.txt
vendored
Normal file
1
td/testdata/result_TestTDFixtureTypeConversion_int.txt
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
199
|
36
td/testdata_test.go
Normal file
36
td/testdata_test.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
package testdata_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/fixture"
|
||||||
|
"gitea.cv.mazarbul.net/rosskeen.house/testing/td"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTDFixture(t *testing.T) {
|
||||||
|
r := fixture.R([]fixture.Result{"empty"})
|
||||||
|
//"./testdat/fixture_TestTDFixture_empty.yml"})
|
||||||
|
f := fixture.New(t, testdata.FixtureRawFile, testdata.P(t.Name()), r)
|
||||||
|
|
||||||
|
f.RunWith(
|
||||||
|
func (t *testing.T) {
|
||||||
|
f.Fixture()
|
||||||
|
f.Assert()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTDFixtureTypeConversion(t *testing.T) {
|
||||||
|
c := func(v interface{}) interface{} { i,_ := strconv.Atoi(strings.TrimSuffix(v.(string), "\n")); return i }
|
||||||
|
r := testdata.Rt(t.Name(), c)
|
||||||
|
f := fixture.New(t, testdata.FixtureRawFile, testdata.P(t.Name()), r)
|
||||||
|
|
||||||
|
f.RunWith(
|
||||||
|
func (t *testing.T) {
|
||||||
|
f.Fixture()
|
||||||
|
f.AssertEq(199)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user