• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..13-Mar-2018-

.gitignoreH A D13-Mar-2018266 2519

LICENSEH A D13-Mar-20181.3 KiB2519

MakefileH A D13-Mar-201880 96

Readme.mdH A D13-Mar-20183.3 KiB127106

diff.goH A D13-Mar-2018544 3426

flatten.goH A D13-Mar-2018988 5447

marshal.goH A D13-Mar-2018815 4741

result.goH A D13-Mar-2018529 3426

seq.goH A D13-Mar-2018405 2417

seq_test.goH A D13-Mar-20183.2 KiB209175

Readme.md

1Structural equality library for Golang.
2
3## Story
4
5While we were working on [HappyPancake](http://abdullin.com/happypancake/) project, [Pieter](https://twitter.com/pjvds) always wanted to have a better assertion library for our event-driven specifications.
6
7Months later, awesome folks from [@DDDBE](https://twitter.com/dddbe) community presented me with some Trappist Beer. Thanks to it (and some spare time on the weekend), this assertion library was finally written.
8
9## How it works
10
11You 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`.
12
13Maps 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.
14
15Consider following types:
16
17```go
18type Robot struct {
19    Legs int    `json:"legs"`
20    Arms int    `json:"arms"`
21    Name string `json:"name"`
22}
23
24type Party struct {
25    Rating  []int             `json:"rating"`
26    Seating map[string]*Robot `json:"seating"`
27}
28```
29Let's imagine that our JSON API returns `Party` object, which we want to verify. We could define our expectation like this:
30
31```go
32  expect := seq.Map{
33    // array
34    "rating.len": 3,
35    "rating[1]":  5,
36    // flat path with value terminator
37    "seating.front.name": "R2D2",
38    "seating.front.arms": "1",
39    "seating.front.legs": 3,
40    // flat path with map terminator
41    "seating.right": seq.Map{
42      "name": "C3PO",
43    },
44    // flat path with object terminator
45    "seating.back": &Robot{
46      Name: "Marvin",
47      Legs: 2,
48      Arms: 2,
49    },
50  }
51
52```
53Once you have the expectation, you could compare it with an actual object. Here is an example of a valid object:
54```go
55  actual := &Party{
56    Rating: []int{4, 5, 4},
57    Seating: map[string]*Robot{
58      "front": &Robot{
59        Name: "R2D2",
60        Arms: 1,
61        Legs: 3,
62      },
63      "back": &Robot{
64        Name: "Marvin",
65        Legs: 2,
66        Arms: 2,
67      },
68      "right": &Robot{
69        Name: "C3PO",
70        Legs: 2,
71        Arms: 2,
72      },
73    },
74  }
75  result := expect.Test(actual)
76
77```
78Result value would contain `Issues []seq.Issue` with any differences and could be checked like this:
79
80```go
81if !result.Ok() {
82  fmt.Println("Differences")
83  for _, v := range result.Issues {
84    fmt.Println(v.String())
85  }
86}
87```
88
89If actual object has some invalid or missing properties, then result will have nice error messages. Consider this object:
90
91```go
92  actual := &Party{
93    Seating: map[string]*Robot{
94      "front": &Robot{
95        Name: "R2D2",
96        Arms: 1,
97      },
98      "back": &Robot{
99        Name: "Marvin",
100        Arms: 3,
101      },
102      "right": &Robot{
103        Name: "C4PO",
104        Legs: 2,
105        Arms: 3,
106      },
107    },
108  }
109
110```
111
112If verified against the original expectation, `result.Issues` would contain these error messages:
113
114```
115Expected rating.len to be '3' but got nothing
116Expected seating.back.legs to be '2' but got '0'
117Expected seating.front.legs to be '3' but got '0'
118Expected rating[1] to be '5' but got nothing
119Expected seating.back.arms to be '2' but got '3'
120Expected seating.right.name to be 'C3PO' but got 'C4PO'
121```
122Check out the [unit tests](https://github.com/abdullin/seq/blob/master/seq_test.go) for more examples.
123
124## Feedback
125
126Feedback is welcome and appreciated!
127