seq

package module
v0.0.0-...-d5467c1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2016 License: BSD-2-Clause Imports: 4 Imported by: 4

README

Structural equality library for Golang.

Story

While we were working on HappyPancake project, Pieter always wanted to have a better assertion library for our event-driven specifications.

Months later, awesome folks from @DDDBE community presented me with some Trappist Beer. Thanks to it (and some spare time on the weekend), this assertion library was finally written.

How it works

You can define expectations on objects (e.g. API responses or expected events) by creating an instance of seq.Map, which is provided by the package github.com/abdullin/seq.

Maps can be nested or they could have flat paths. Values could be represented with strings, primitive types, instances of seq.Map or JSON-serializable objects.

Consider following types:

type Robot struct {
    Legs int    `json:"legs"`
    Arms int    `json:"arms"`
    Name string `json:"name"`
}

type Party struct {
    Rating  []int             `json:"rating"`
    Seating map[string]*Robot `json:"seating"`
}

Let's imagine that our JSON API returns Party object, which we want to verify. We could define our expectation like this:

  expect := seq.Map{
    // array
    "rating.len": 3,
    "rating[1]":  5,
    // flat path with value terminator
    "seating.front.name": "R2D2",
    "seating.front.arms": "1",
    "seating.front.legs": 3,
    // flat path with map terminator
    "seating.right": seq.Map{
      "name": "C3PO",
    },
    // flat path with object terminator
    "seating.back": &Robot{
      Name: "Marvin",
      Legs: 2,
      Arms: 2,
    },
  }

Once you have the expectation, you could compare it with an actual object. Here is an example of a valid object:

  actual := &Party{
    Rating: []int{4, 5, 4},
    Seating: map[string]*Robot{
      "front": &Robot{
        Name: "R2D2",
        Arms: 1,
        Legs: 3,
      },
      "back": &Robot{
        Name: "Marvin",
        Legs: 2,
        Arms: 2,
      },
      "right": &Robot{
        Name: "C3PO",
        Legs: 2,
        Arms: 2,
      },
    },
  }
  result := expect.Test(actual)

Result value would contain Issues []seq.Issue with any differences and could be checked like this:

if !result.Ok() {
  fmt.Println("Differences")
  for _, v := range result.Issues {
    fmt.Println(v.String())
  }
}

If actual object has some invalid or missing properties, then result will have nice error messages. Consider this object:

  actual := &Party{
    Seating: map[string]*Robot{
      "front": &Robot{
        Name: "R2D2",
        Arms: 1,
      },
      "back": &Robot{
        Name: "Marvin",
        Arms: 3,
      },
      "right": &Robot{
        Name: "C4PO",
        Legs: 2,
        Arms: 3,
      },
    },
  }

If verified against the original expectation, result.Issues would contain these error messages:

Expected rating.len to be '3' but got nothing
Expected seating.back.legs to be '2' but got '0'
Expected seating.front.legs to be '3' but got '0'
Expected rating[1] to be '5' but got nothing
Expected seating.back.arms to be '2' but got '3'
Expected seating.right.name to be 'C3PO' but got 'C4PO'

Check out the unit tests for more examples.

Feedback

Feedback is welcome and appreciated!

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Issue

type Issue struct {
	Path          string
	ExpectedValue string
	ActualValue   string
}

func (*Issue) String

func (d *Issue) String() string

type Map

type Map map[string]interface{}

func (Map) Test

func (m Map) Test(actual interface{}) *Result

type Result

type Result struct {
	Issues []Issue
}

func NewResult

func NewResult() *Result

func Test

func Test(expected, actual interface{}) *Result

func (*Result) AddIssue

func (r *Result) AddIssue(key, expected, actual string)

func (*Result) Ok

func (r *Result) Ok() bool

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL