Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce api.Runnable back into the mix #43

Merged
merged 3 commits into from
Jun 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions api/runnable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Use and distribution licensed under the Apache license version 2.
//
// See the COPYING file in the root project directory for full text.

package api

import (
"context"
"testing"
)

// Runnable are things that Run a `*testing.T`
type Runnable interface {
// Run accepts a context and a `*testing.T` and runs some tests within that
// context
//
// Errors returned by Run() are **RuntimeErrors**, not failures in
// assertions.
Run(context.Context, *testing.T) error
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// See the COPYING file in the root project directory for full text.

package scenario_test
package errstarter

import (
"context"
Expand All @@ -16,7 +16,7 @@ var (
return fmt.Errorf("error starting fixture!")
}

errStarterFixture = fixture.New(
Fixture = fixture.New(
fixture.WithStarter(errStarter),
)
)
101 changes: 101 additions & 0 deletions internal/testutil/plugin/bar/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Use and distribution licensed under the Apache license version 2.
//
// See the COPYING file in the root project directory for full text.

package bar

import (
"context"
"strconv"

"github.com/gdt-dev/gdt/api"
"github.com/gdt-dev/gdt/plugin"
"github.com/samber/lo"
"gopkg.in/yaml.v3"
)

func init() {
plugin.Register(&Plugin{})
}

type Defaults struct {
Foo string `yaml:"bar"`
}

func (d *Defaults) UnmarshalYAML(node *yaml.Node) error {
return nil
}

type Spec struct {
api.Spec
Bar int `yaml:"bar"`
}

func (s *Spec) SetBase(b api.Spec) {
s.Spec = b
}

func (s *Spec) Base() *api.Spec {
return &s.Spec
}

func (s *Spec) Retry() *api.Retry {
return api.NoRetry
}

func (s *Spec) Timeout() *api.Timeout {
return nil
}

func (s *Spec) Eval(context.Context) (*api.Result, error) {
return api.NewResult(), nil
}

func (s *Spec) UnmarshalYAML(node *yaml.Node) error {
if node.Kind != yaml.MappingNode {
return api.ExpectedMapAt(node)
}
// maps/structs are stored in a top-level Node.Content field which is a
// concatenated slice of Node pointers in pairs of key/values.
for i := 0; i < len(node.Content); i += 2 {
keyNode := node.Content[i]
if keyNode.Kind != yaml.ScalarNode {
return api.ExpectedScalarAt(keyNode)
}
key := keyNode.Value
valNode := node.Content[i+1]
switch key {
case "bar":
if valNode.Kind != yaml.ScalarNode {
return api.ExpectedScalarAt(valNode)
}
if v, err := strconv.Atoi(valNode.Value); err != nil {
return api.ExpectedIntAt(valNode)
} else {
s.Bar = v
}
default:
if lo.Contains(api.BaseSpecFields, key) {
continue
}
return api.UnknownFieldAt(key, keyNode)
}
}
return nil
}

type Plugin struct{}

func (p *Plugin) Info() api.PluginInfo {
return api.PluginInfo{
Name: "bar",
}
}

func (p *Plugin) Defaults() yaml.Unmarshaler {
return &Defaults{}
}

func (p *Plugin) Specs() []api.Evaluable {
return []api.Evaluable{&Spec{}}
}
136 changes: 136 additions & 0 deletions internal/testutil/plugin/failer/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Use and distribution licensed under the Apache license version 2.
//
// See the COPYING file in the root project directory for full text.

package failer

import (
"context"
"fmt"
"strconv"

"github.com/gdt-dev/gdt/api"
gdtapi "github.com/gdt-dev/gdt/api"
"github.com/gdt-dev/gdt/plugin"
"github.com/samber/lo"
"gopkg.in/yaml.v3"
)

func init() {
plugin.Register(&Plugin{})
}

type InnerDefaults struct {
Fail bool `yaml:"fail,omitempty"`
}

type Defaults struct {
InnerDefaults
}

func (d *Defaults) UnmarshalYAML(node *yaml.Node) error {
if node.Kind != yaml.MappingNode {
return api.ExpectedMapAt(node)
}
// maps/structs are stored in a top-level Node.Content field which is a
// concatenated slice of Node pointers in pairs of key/values.
for i := 0; i < len(node.Content); i += 2 {
keyNode := node.Content[i]
if keyNode.Kind != yaml.ScalarNode {
return api.ExpectedScalarAt(keyNode)
}
key := keyNode.Value
valNode := node.Content[i+1]
switch key {
case "fail":
if valNode.Kind != yaml.MappingNode {
return api.ExpectedMapAt(valNode)
}
inner := InnerDefaults{}
if err := valNode.Decode(&inner); err != nil {
return err
}
d.InnerDefaults = inner
// This is just for testing api when parsing defaults...
if d.Fail {
return fmt.Errorf("defaults parsing failed")
}
default:
continue
}
}
return nil
}

type Spec struct {
api.Spec
Fail bool `yaml:"fail"`
}

func (s *Spec) SetBase(b api.Spec) {
s.Spec = b
}

func (s *Spec) Base() *api.Spec {
return &s.Spec
}

func (s *Spec) Retry() *api.Retry {
return nil
}

func (s *Spec) Timeout() *api.Timeout {
return nil
}

func (s *Spec) Eval(context.Context) (*api.Result, error) {
return nil, fmt.Errorf("%w: Indy, bad dates!", gdtapi.RuntimeError)
}

func (s *Spec) UnmarshalYAML(node *yaml.Node) error {
if node.Kind != yaml.MappingNode {
return api.ExpectedMapAt(node)
}
// maps/structs are stored in a top-level Node.Content field which is a
// concatenated slice of Node pointers in pairs of key/values.
for i := 0; i < len(node.Content); i += 2 {
keyNode := node.Content[i]
if keyNode.Kind != yaml.ScalarNode {
return api.ExpectedScalarAt(keyNode)
}
key := keyNode.Value
valNode := node.Content[i+1]
switch key {
case "fail":
if valNode.Kind != yaml.ScalarNode {
return api.ExpectedScalarAt(valNode)
}
s.Fail, _ = strconv.ParseBool(valNode.Value)
if s.Fail {
return fmt.Errorf("Indy, bad parse!")
}
default:
if lo.Contains(api.BaseSpecFields, key) {
continue
}
return api.UnknownFieldAt(key, keyNode)
}
}
return nil
}

type Plugin struct{}

func (p *Plugin) Info() api.PluginInfo {
return api.PluginInfo{
Name: "fail",
}
}

func (p *Plugin) Defaults() yaml.Unmarshaler {
return &Defaults{}
}

func (p *Plugin) Specs() []api.Evaluable {
return []api.Evaluable{&Spec{}}
}
Loading
Loading