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

add natural language datetime assertion #711

Merged
merged 3 commits into from
Sep 20, 2023
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
57 changes: 50 additions & 7 deletions assertions/assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/pkg/errors"
"github.com/spf13/cast"
"github.com/tj/go-naturaldate"
)

type AssertFunc func(actual interface{}, expected ...interface{}) error
Expand Down Expand Up @@ -954,7 +955,7 @@ func ShouldEqualTrimSpace(actual interface{}, expected ...interface{}) error {
}

// ShouldHappenBefore receives exactly 2 time.Time arguments and asserts that the first happens before the second.
// The arguments have to respect the date format RFC3339, as 2006-01-02T15:04:00+07:00
// The arguments have to respect the date format RFC3339 (ie. 2006-01-02T15:04:00+07:00) or humanize format (ie. now, tomorrow, yesterday, 5 minutes ago)
//
// Example of testsuite file:
//
Expand All @@ -969,6 +970,13 @@ func ShouldEqualTrimSpace(actual interface{}, expected ...interface{}) error {
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenBefore "{{.time_with_5s_after}}"
// - name: test assertion with humanize format
// steps:
// - type: exec
// script: "echo {{.venom.datetime}}"
// assertions:
// - "result.systemout ShouldHappenBefore tomorrow"
// - "result.systemout ShouldHappenBefore '5 minutes from now'"
func ShouldHappenBefore(actual interface{}, expected ...interface{}) error {
if err := need(1, expected); err != nil {
return err
Expand All @@ -991,7 +999,7 @@ func ShouldHappenBefore(actual interface{}, expected ...interface{}) error {
}

// ShouldHappenOnOrBefore receives exactly 2 time.Time arguments and asserts that the first happens on or before the second.
// The arguments have to respect the date format RFC3339, as 2006-01-02T15:04:00+07:00
// The arguments have to respect the date format RFC3339 (ie. 2006-01-02T15:04:00+07:00) or humanize format (ie. now, tomorrow, yesterday, 5 minutes ago)
//
// Example of testsuite file:
//
Expand All @@ -1006,6 +1014,13 @@ func ShouldHappenBefore(actual interface{}, expected ...interface{}) error {
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenOnOrBefore "{{.time_with_5s_after}}"
// - name: test assertion with humanize format
// steps:
// - type: exec
// script: "echo {{.venom.datetime}}"
// assertions:
// - "result.systemout ShouldHappenOnOrBefore tomorrow"
// - "result.systemout ShouldHappenOnOrBefore '5 minutes from now'"
func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) error {
if err := need(1, expected); err != nil {
return err
Expand All @@ -1027,7 +1042,7 @@ func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) error {
}

// ShouldHappenAfter receives exactly 2 time.Time arguments and asserts that the first happens after the second.
// The arguments have to respect the date format RFC3339, as 2006-01-02T15:04:00+07:00
// The arguments have to respect the date format RFC3339 (ie. 2006-01-02T15:04:00+07:00) or humanize format (ie. now, tomorrow, yesterday, 5 minutes ago)
//
// Example of testsuite file:
//
Expand All @@ -1042,6 +1057,13 @@ func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) error {
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenAfter "{{.time_with_5s_before}}"
// - name: test assertion with humanize format
// steps:
// - type: exec
// script: "echo {{.venom.datetime}}"
// assertions:
// - "result.systemout ShouldHappenAfter yesterday"
// - "result.systemout ShouldHappenAfter '5 minutes ago'"
func ShouldHappenAfter(actual interface{}, expected ...interface{}) error {
if err := need(1, expected); err != nil {
return err
Expand All @@ -1063,7 +1085,7 @@ func ShouldHappenAfter(actual interface{}, expected ...interface{}) error {
}

// ShouldHappenOnOrAfter receives exactly 2 time.Time arguments and asserts that the first happens on or after the second.
// The arguments have to respect the date format RFC3339, as 2006-01-02T15:04:00+07:00
// The arguments have to respect the date format RFC3339 (ie. 2006-01-02T15:04:00+07:00) or humanize format (ie. now, tomorrow, yesterday, 5 minutes ago)
//
// Example of testsuite file:
//
Expand All @@ -1078,6 +1100,13 @@ func ShouldHappenAfter(actual interface{}, expected ...interface{}) error {
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenOnOrAfter "{{.time_with_5s_before}}"
// - name: test assertion with humanize format
// steps:
// - type: exec
// script: "echo {{.venom.datetime}}"
// assertions:
// - "result.systemout ShouldHappenOnOrAfter yesterday"
// - "result.systemout ShouldHappenOnOrAfter '5 minutes ago'"
func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) error {
if err := need(1, expected); err != nil {
return err
Expand All @@ -1099,7 +1128,7 @@ func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) error {
}

// ShouldHappenBetween receives exactly 3 time.Time arguments and asserts that the first happens between (not on) the second and third.
// The arguments have to respect the date format RFC3339, as 2006-01-02T15:04:00+07:00
// The arguments have to respect the date format RFC3339 (ie. 2006-01-02T15:04:00+07:00) or humanize format (ie. yesterday, 5 minutes ago)
//
// Example of testsuite file:
//
Expand All @@ -1115,6 +1144,13 @@ func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) error {
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenBetween "{{.time_with_5s_before}}" "{{.time_with_5s_after}}"
// - name: test assertion with humanize format
// steps:
// - type: exec
// script: "echo {{.venom.datetime}}"
// assertions:
// - "result.systemout ShouldHappenBetween yesterday tomorrow"
// - "result.systemout ShouldHappenBetween '5 minutes ago' '5 minutes from now'"
func ShouldHappenBetween(actual interface{}, expected ...interface{}) error {
if err := need(2, expected); err != nil {
return err
Expand Down Expand Up @@ -1304,14 +1340,21 @@ func getTimeFromString(in interface{}) (time.Time, error) {
if t, isTime := in.(time.Time); isTime {
return t, nil
}

s, err := cast.ToStringE(in)
if err != nil {
return time.Time{}, errors.Errorf("invalid date provided: %q", in)
}

t, err := time.Parse(time.RFC3339, s)
if err != nil {
return time.Time{}, errors.Errorf("invalid date RFC3339 provided with %q", in)
if err == nil {
return t, nil
}

t, innerErr := naturaldate.Parse(s, time.Now())
if innerErr != nil {
return time.Time{}, errors.Errorf("invalid date provided with %q not in RFC3339 format or humanize format", in)
}

return t, nil
}
35 changes: 35 additions & 0 deletions assertions/assertions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,13 @@ func TestShouldHappenBefore(t *testing.T) {
expected: []interface{}{time.Now().Add(1 * time.Second)},
},
},
{
name: "ok",
args: args{
actual: time.Now(),
expected: []interface{}{"1 minute from now"},
},
},
{
name: "ko",
args: args{
Expand Down Expand Up @@ -1218,6 +1225,13 @@ func TestShouldHappenOnOrBefore(t *testing.T) {
expected: []interface{}{time.Now().Add(1 * time.Second)},
},
},
{
name: "ok",
args: args{
actual: time.Now(),
expected: []interface{}{"1 minute from now"},
},
},
{
name: "ko",
args: args{
Expand Down Expand Up @@ -1253,6 +1267,13 @@ func TestShouldHappenAfter(t *testing.T) {
expected: []interface{}{time.Now().Add(-1 * time.Second)},
},
},
{
name: "ok",
args: args{
actual: time.Now(),
expected: []interface{}{"1 second ago"},
},
},
{
name: "ko",
args: args{
Expand Down Expand Up @@ -1288,6 +1309,13 @@ func TestShouldHappenOnOrAfter(t *testing.T) {
expected: []interface{}{time.Now().Add(-1 * time.Second)},
},
},
{
name: "ok",
args: args{
actual: time.Now(),
expected: []interface{}{"1 second ago"},
},
},
{
name: "ko",
args: args{
Expand Down Expand Up @@ -1346,6 +1374,13 @@ func TestShouldHappenBetween(t *testing.T) {
},
wantErr: true,
},
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is failing:

assertions_test.go:1388: ShouldHappenBetween() error = expected '2023-09-07 09:06:34.28230254 +0000 UTC m=+0.000668682' to be between '2023-09-07 01:00:00 +0000 UTC' and '2023-09-07 01:00:00 +0000 UTC' , wantErr false

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you check again?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rhzs it's ok, thank you. LGTM

name: "ok",
args: args{
actual: time.Now(),
expected: []interface{}{"1 minute ago", "1 minute from now"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/tj/go-naturaldate v1.3.0
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,10 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160 h1:NSWpaDaurcAJY7PkL8Xt0PhZE7qpvbZl5ljd8r6U0bI=
github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
github.com/tj/go-naturaldate v1.3.0 h1:OgJIPkR/Jk4bFMBLbxZ8w+QUxwjqSvzd9x+yXocY4RI=
github.com/tj/go-naturaldate v1.3.0/go.mod h1:rpUbjivDKiS1BlfMGc2qUKNZ/yxgthOfmytQs8d8hKk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
Expand Down
13 changes: 10 additions & 3 deletions tests/assertions/ShouldHappenAfter.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
name: test ShouldHappenAfter - use RFC3339 format
name: test ShouldHappenAfter
vars:
time_with_5s_before: 2006-01-02T15:04:00+07:00
time: 2006-01-02T15:04:05+07:00
testcases:
- name: test assertion
- name: test assertion with RFC3339 date format
steps:
- type: exec
script: "echo {{.time}}"
assertions:
- result.systemout ShouldHappenAfter "{{.time_with_5s_before}}"
- result.systemout ShouldHappenAfter "{{.time_with_5s_before}}"
- name: test assertion with humanize format
steps:
- type: exec
script: "echo {{.venom.datetime}}"
assertions:
- "result.systemout ShouldHappenAfter yesterday"
- "result.systemout ShouldHappenAfter '5 minutes ago'"
13 changes: 10 additions & 3 deletions tests/assertions/ShouldHappenBefore.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
name: test ShouldHappenBefore - use RFC3339 format
name: test ShouldHappenBefore
vars:
time: 2006-01-02T15:04:05+07:00
time_with_5s_after: 2006-01-02T15:04:10+07:00
testcases:
- name: test assertion
- name: test assertion with RFC3339 date format
steps:
- type: exec
script: "echo {{.time}}"
assertions:
- result.systemout ShouldHappenBefore "{{.time_with_5s_after}}"
- result.systemout ShouldHappenBefore "{{.time_with_5s_after}}"
- name: test assertion with humanize format
steps:
- type: exec
script: "echo {{.venom.datetime}}"
assertions:
- "result.systemout ShouldHappenBefore tomorrow"
- "result.systemout ShouldHappenBefore '5 minutes from now'"
13 changes: 10 additions & 3 deletions tests/assertions/ShouldHappenBetween.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
name: test ShouldHappenBetween - use RFC3339 format
name: test ShouldHappenBetween
vars:
time_with_5s_before: 2006-01-02T15:04:00+07:00
time: 2006-01-02T15:04:05+07:00
time_with_5s_after: 2006-01-02T15:04:10+07:00
testcases:
- name: test assertion
- name: test assertion with RFC3339 date format
steps:
- type: exec
script: "echo {{.time}}"
assertions:
- result.systemout ShouldHappenBetween "{{.time_with_5s_before}}" "{{.time_with_5s_after}}"
- result.systemout ShouldHappenBetween "{{.time_with_5s_before}}" "{{.time_with_5s_after}}"
- name: test assertion with humanize format
steps:
- type: exec
script: "echo {{.venom.datetime}}"
assertions:
- "result.systemout ShouldHappenBetween yesterday tomorrow"
- "result.systemout ShouldHappenBetween '5 minutes ago' '5 minutes from now'"
13 changes: 10 additions & 3 deletions tests/assertions/ShouldHappenOnOrAfter.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
name: test ShouldHappenOnOrAfter - use RFC3339 format
name: test ShouldHappenOnOrAfter
vars:
time_with_5s_before: 2006-01-02T15:04:00+07:00
time: 2006-01-02T15:04:05+07:00
testcases:
- name: test assertion
- name: test assertion with RFC3339 date format
steps:
- type: exec
script: "echo {{.time}}"
assertions:
- result.systemout ShouldHappenOnOrAfter "{{.time_with_5s_before}}"
- result.systemout ShouldHappenOnOrAfter "{{.time_with_5s_before}}"
- name: test assertion with humanize format
steps:
- type: exec
script: "echo {{.venom.datetime}}"
assertions:
- "result.systemout ShouldHappenOnOrAfter yesterday"
- "result.systemout ShouldHappenOnOrAfter '5 minutes ago'"
13 changes: 10 additions & 3 deletions tests/assertions/ShouldHappenOnOrBefore.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
name: test ShouldHappenOnOrBefore - use RFC3339 format
name: test ShouldHappenOnOrBefore
vars:
time: 2006-01-02T15:04:05+07:00
time_with_5s_after: 2006-01-02T15:04:10+07:00
testcases:
- name: test assertion
- name: test assertion with RFC3339 date format
steps:
- type: exec
script: "echo {{.time}}"
assertions:
- result.systemout ShouldHappenOnOrBefore "{{.time_with_5s_after}}"
- result.systemout ShouldHappenOnOrBefore "{{.time_with_5s_after}}"
- name: test assertion with humanize format
steps:
- type: exec
script: "echo {{.venom.datetime}}"
assertions:
- "result.systemout ShouldHappenOnOrBefore tomorrow"
- "result.systemout ShouldHappenOnOrBefore '5 minutes from now'"