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