From 81d96f305f606c323cf7d5cfa30a6d7cab1ee4af Mon Sep 17 00:00:00 2001 From: Matthew Rich Date: Wed, 8 May 2024 13:28:36 -0700 Subject: [PATCH] import testing package --- LICENSE | 21 +++ README.md | 40 ++++- fixture/fixture.go | 139 ++++++++++++++++++ fixture/fixture_test.go | 51 +++++++ fixture/params.go | 32 ++++ fixture/results.go | 30 ++++ fixtures/README.md | 17 +++ fixtures/fixture_test.go | 18 +++ fixtures/fixtures.go | 39 +++++ fixtures/testdata.go | 41 ++++++ fixtures/testdata_test.go | 10 ++ fixtures/tester.go | 24 +++ go.mod | 5 + go.sum | 3 + md/mockdata.go | 25 ++++ md/mockdata_test.go | 33 +++++ md/params.go | 78 ++++++++++ md/results.go | 43 ++++++ md/testdata/mock_MDFixture_simple.yml | 2 + td/params.go | 57 +++++++ td/results.go | 48 ++++++ td/testdata.go | 23 +++ ...ixture_TestTDFixtureTypeConversion_int.txt | 1 + td/testdata/fixture_TestTDFixture_empty.yml | 1 + ...result_TestTDFixtureTypeConversion_int.txt | 1 + td/testdata_test.go | 36 +++++ 26 files changed, 816 insertions(+), 2 deletions(-) create mode 100644 LICENSE create mode 100644 fixture/fixture.go create mode 100644 fixture/fixture_test.go create mode 100644 fixture/params.go create mode 100644 fixture/results.go create mode 100644 fixtures/README.md create mode 100644 fixtures/fixture_test.go create mode 100644 fixtures/fixtures.go create mode 100644 fixtures/testdata.go create mode 100644 fixtures/testdata_test.go create mode 100644 fixtures/tester.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 md/mockdata.go create mode 100644 md/mockdata_test.go create mode 100644 md/params.go create mode 100644 md/results.go create mode 100644 md/testdata/mock_MDFixture_simple.yml create mode 100644 td/params.go create mode 100644 td/results.go create mode 100644 td/testdata.go create mode 100644 td/testdata/fixture_TestTDFixtureTypeConversion_int.txt create mode 100644 td/testdata/fixture_TestTDFixture_empty.yml create mode 100644 td/testdata/result_TestTDFixtureTypeConversion_int.txt create mode 100644 td/testdata_test.go diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..44bcfd1 --- /dev/null +++ b/LICENSE @@ -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. diff --git a/README.md b/README.md index 7b647ab..d55caa0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,39 @@ -# testing +# Test Fixtures in Go -Test Fixtures \ No newline at end of file +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) + }) + +} + +``` diff --git a/fixture/fixture.go b/fixture/fixture.go new file mode 100644 index 0000000..e80a7f7 --- /dev/null +++ b/fixture/fixture.go @@ -0,0 +1,139 @@ +// Copyright 2024 Matthew Rich . 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]) + } +} + diff --git a/fixture/fixture_test.go b/fixture/fixture_test.go new file mode 100644 index 0000000..795bf3c --- /dev/null +++ b/fixture/fixture_test.go @@ -0,0 +1,51 @@ +// Copyright 2024 Matthew Rich . 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)) + }) + +} diff --git a/fixture/params.go b/fixture/params.go new file mode 100644 index 0000000..04dcec4 --- /dev/null +++ b/fixture/params.go @@ -0,0 +1,32 @@ +// Copyright 2024 Matthew Rich . 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 +} diff --git a/fixture/results.go b/fixture/results.go new file mode 100644 index 0000000..1cde32b --- /dev/null +++ b/fixture/results.go @@ -0,0 +1,30 @@ +// Copyright 2024 Matthew Rich . 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 +} diff --git a/fixtures/README.md b/fixtures/README.md new file mode 100644 index 0000000..9a9b025 --- /dev/null +++ b/fixtures/README.md @@ -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) + + +}) +} diff --git a/fixtures/fixture_test.go b/fixtures/fixture_test.go new file mode 100644 index 0000000..3627d52 --- /dev/null +++ b/fixtures/fixture_test.go @@ -0,0 +1,18 @@ +// Copyright 2024 Matthew Rich . 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, +} diff --git a/fixtures/fixtures.go b/fixtures/fixtures.go new file mode 100644 index 0000000..c00cd05 --- /dev/null +++ b/fixtures/fixtures.go @@ -0,0 +1,39 @@ +// Copyright 2024 Matthew Rich . 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{}) { + +} diff --git a/fixtures/testdata.go b/fixtures/testdata.go new file mode 100644 index 0000000..8d49e6e --- /dev/null +++ b/fixtures/testdata.go @@ -0,0 +1,41 @@ +// Copyright 2024 Matthew Rich . 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) }) + } +} diff --git a/fixtures/testdata_test.go b/fixtures/testdata_test.go new file mode 100644 index 0000000..227cee3 --- /dev/null +++ b/fixtures/testdata_test.go @@ -0,0 +1,10 @@ +// Copyright 2024 Matthew Rich . All rights reserved. +package fixtures_test + +import ( + "testing" +) + +func TestFixtureTestData(t *testing.T) { + +} diff --git a/fixtures/tester.go b/fixtures/tester.go new file mode 100644 index 0000000..be74d77 --- /dev/null +++ b/fixtures/tester.go @@ -0,0 +1,24 @@ +// Copyright 2024 Matthew Rich . 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) + } +} + diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..6838aff --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module testing + +go 1.15 + +require gopkg.in/yaml.v2 v2.3.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8fabe8d --- /dev/null +++ b/go.sum @@ -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= diff --git a/md/mockdata.go b/md/mockdata.go new file mode 100644 index 0000000..f126c71 --- /dev/null +++ b/md/mockdata.go @@ -0,0 +1,25 @@ +// Copyright 2024 Matthew Rich . 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()) +} diff --git a/md/mockdata_test.go b/md/mockdata_test.go new file mode 100644 index 0000000..99acc0c --- /dev/null +++ b/md/mockdata_test.go @@ -0,0 +1,33 @@ +// Copyright 2024 Matthew Rich . 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") + } + }) + +} diff --git a/md/params.go b/md/params.go new file mode 100644 index 0000000..09e3e4f --- /dev/null +++ b/md/params.go @@ -0,0 +1,78 @@ +// Copyright 2024 Matthew Rich . 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 +} + + diff --git a/md/results.go b/md/results.go new file mode 100644 index 0000000..dd937f4 --- /dev/null +++ b/md/results.go @@ -0,0 +1,43 @@ +// Copyright 2024 Matthew Rich . 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 +} diff --git a/md/testdata/mock_MDFixture_simple.yml b/md/testdata/mock_MDFixture_simple.yml new file mode 100644 index 0000000..1c36601 --- /dev/null +++ b/md/testdata/mock_MDFixture_simple.yml @@ -0,0 +1,2 @@ +foo: 3 +bar: 5 diff --git a/td/params.go b/td/params.go new file mode 100644 index 0000000..0ebe474 --- /dev/null +++ b/td/params.go @@ -0,0 +1,57 @@ +// Copyright 2024 Matthew Rich . 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 +} + + diff --git a/td/results.go b/td/results.go new file mode 100644 index 0000000..7611854 --- /dev/null +++ b/td/results.go @@ -0,0 +1,48 @@ +// Copyright 2024 Matthew Rich . 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 +} diff --git a/td/testdata.go b/td/testdata.go new file mode 100644 index 0000000..8af93c2 --- /dev/null +++ b/td/testdata.go @@ -0,0 +1,23 @@ +// Copyright 2024 Matthew Rich . 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)) +} diff --git a/td/testdata/fixture_TestTDFixtureTypeConversion_int.txt b/td/testdata/fixture_TestTDFixtureTypeConversion_int.txt new file mode 100644 index 0000000..aa34eab --- /dev/null +++ b/td/testdata/fixture_TestTDFixtureTypeConversion_int.txt @@ -0,0 +1 @@ +199 diff --git a/td/testdata/fixture_TestTDFixture_empty.yml b/td/testdata/fixture_TestTDFixture_empty.yml new file mode 100644 index 0000000..7b4d68d --- /dev/null +++ b/td/testdata/fixture_TestTDFixture_empty.yml @@ -0,0 +1 @@ +empty \ No newline at end of file diff --git a/td/testdata/result_TestTDFixtureTypeConversion_int.txt b/td/testdata/result_TestTDFixtureTypeConversion_int.txt new file mode 100644 index 0000000..aa34eab --- /dev/null +++ b/td/testdata/result_TestTDFixtureTypeConversion_int.txt @@ -0,0 +1 @@ +199 diff --git a/td/testdata_test.go b/td/testdata_test.go new file mode 100644 index 0000000..5b20c80 --- /dev/null +++ b/td/testdata_test.go @@ -0,0 +1,36 @@ +// Copyright 2024 Matthew Rich . 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) + }) + +}