Skip to content
This repository has been archived by the owner on Sep 8, 2021. It is now read-only.

Commit

Permalink
Groundbreaking commit
Browse files Browse the repository at this point in the history
  • Loading branch information
nhatthm committed Apr 15, 2021
1 parent c0baf10 commit 9590bbc
Show file tree
Hide file tree
Showing 16 changed files with 1,013 additions and 30 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,16 @@ jobs:
run: |
make test
- name: Upload code coverage
- name: Upload code coverage (unit)
if: matrix.go-version == env.GO_LATEST_VERSION
uses: codecov/codecov-action@v1
with:
file: ./unit.coverprofile
flags: unittests-${{ runner.os }}

- name: Upload code coverage (features)
if: matrix.go-version == env.GO_LATEST_VERSION
uses: codecov/codecov-action@v1
with:
file: ./features.coverprofile
flags: featuretests-${{ runner.os }}
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ $(VENDOR_DIR):
lint:
@$(GOLANGCI_LINT) run

test: test-unit
test: test-unit test-integration

## Run unit tests
test-unit:
@echo ">> unit test"
@$(GO) test -gcflags=-l -coverprofile=unit.coverprofile -covermode=atomic -race ./...

#test-integration:
# @echo ">> integration test"
# @$(GO) test ./features/... -gcflags=-l -coverprofile=features.coverprofile -coverpkg ./... -godog -race
test-integration:
@echo ">> integration test"
@$(GO) test ./features/... -gcflags=-l -coverprofile=features.coverprofile -coverpkg ./... -godog -race
61 changes: 39 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,49 @@
# @nhatthm/{name}
# Cucumber Clock steps for Golang

<!--
[![Build Status](https://github.com/nhatthm/{name}/actions/workflows/test.yaml/badge.svg)](https://github.com/nhatthm/{}name/actions/workflows/test.yaml)
[![codecov](https://codecov.io/gh/nhatthm/{name}/branch/master/graph/badge.svg?token=eTdAgDE2vR)](https://codecov.io/gh/nhatthm/{name})
[![Go Report Card](https://goreportcard.com/badge/github.com/nhatthm/{name})](https://goreportcard.com/report/github.com/nhatthm/{name})
[![GoDevDoc](https://img.shields.io/badge/dev-doc-00ADD8?logo=go)](https://pkg.go.dev/github.com/nhatthm/{name})
[![Build Status](https://github.com/nhatthm/clockdog/actions/workflows/test.yaml/badge.svg)](https://github.com/nhatthm/clockdog/actions/workflows/test.yaml)
[![codecov](https://codecov.io/gh/nhatthm/clockdog/branch/master/graph/badge.svg?token=eTdAgDE2vR)](https://codecov.io/gh/nhatthm/clockdog)
[![Go Report Card](https://goreportcard.com/badge/github.com/nhatthm/httpmock)](https://goreportcard.com/report/github.com/nhatthm/httpmock)
[![GoDevDoc](https://img.shields.io/badge/dev-doc-00ADD8?logo=go)](https://pkg.go.dev/github.com/nhatthm/clockdog)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?hosted_button_id=PJZSGJN57TDJY)
-->

TBD

## Prerequisites

- `Go >= 1.14`

## Install

```bash
go get github.com/nhatthm/{name}
```
`clockdog` uses [`nhatthm/go-clock`](https://github.com/nhatthm/go-clock) to provide steps for `cucumber/godog` and
makes it easy to run tests with `time`.

## Usage

TBD

## Examples
Initiate the clock and register it to the scenario.

```go
package mypackage

import (
"testing"

"github.com/cucumber/godog"
"github.com/nhatthm/clockdog"
)

func TestIntegration(t *testing.T) {
clock := clockdog.New()
suite := godog.TestSuite{
Name: "Integration",
TestSuiteInitializer: nil,
ScenarioInitializer: func(ctx *godog.ScenarioContext) {
clock.RegisterContext(ctx)
},
Options: &godog.Options{
Strict: true,
Output: out,
Randomize: rand.Int63(),
},
}

// Inject the clock to your application then run the suite.
status := suite.Run()
}
```

TBA
Read more about [`nhatthm/go-clock`](https://github.com/nhatthm/go-clock)

## Donation

Expand Down
99 changes: 99 additions & 0 deletions clock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package clockdog

import (
"errors"
"sync"
"time"

clock "github.com/nhatthm/go-clock"
)

// ErrClockIsNotSet indicates that the clock must be set by either Clock.Set() or Clock.Freeze() before adding some
// time.Duration into it.
var ErrClockIsNotSet = errors.New("clock is not set")

var _ clock.Clock = (*Clock)(nil)

// Clock is a clock.Clock.
type Clock struct {
timestamp *time.Time
mu sync.Mutex
}

// Now returns a fixed timestamp or time.Now().
func (c *Clock) Now() time.Time {
c.mu.Lock()
defer c.mu.Unlock()

if c.timestamp == nil {
return time.Now()
}

return *c.timestamp
}

// Set fixes the clock at a time.
func (c *Clock) Set(t time.Time) {
c.mu.Lock()
defer c.mu.Unlock()

c.timestamp = timestamp(t)
}

// Add adds time to the clock.
func (c *Clock) Add(d time.Duration) error {
c.mu.Lock()
defer c.mu.Unlock()

if c.timestamp == nil {
return ErrClockIsNotSet
}

c.timestamp = timestamp(c.timestamp.Add(d))

return nil
}

// AddDate adds date to the clock.
func (c *Clock) AddDate(years, months, days int) error {
c.mu.Lock()
defer c.mu.Unlock()

if c.timestamp == nil {
return ErrClockIsNotSet
}

c.timestamp = timestamp(c.timestamp.AddDate(years, months, days))

return nil
}

// Freeze freezes the clock.
func (c *Clock) Freeze() {
c.mu.Lock()
defer c.mu.Unlock()

c.timestamp = timestamp(time.Now())
}

// Unfreeze unfreezes the clock.
func (c *Clock) Unfreeze() {
c.mu.Lock()
defer c.mu.Unlock()

c.timestamp = nil
}

// Clock provides clock.Clock.
func (c *Clock) Clock() clock.Clock {
return c
}

// New initiates a new Clock.
func New() *Clock {
return &Clock{}
}

func timestamp(t time.Time) *time.Time {
return &t
}
74 changes: 74 additions & 0 deletions clock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package clockdog_test

import (
"testing"
"time"

"github.com/nhatthm/clockdog"
"github.com/stretchr/testify/assert"
)

func TestClock(t *testing.T) {
t.Parallel()

c := clockdog.New()

now := time.Now()

assert.True(t, now.Before(c.Now()))

// Errors while adding time to a live clock.
assert.Equal(t, clockdog.ErrClockIsNotSet, c.Add(time.Hour))
assert.Equal(t, clockdog.ErrClockIsNotSet, c.AddDate(0, 0, 1))

// Freeze the clock.
c.Freeze()

ts := c.Now()

<-time.After(50 * time.Millisecond)

assert.Equal(t, ts, c.Now())

// Set to another time.
ts = time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC)

c.Set(ts)

<-time.After(50 * time.Millisecond)

assert.Equal(t, ts, c.Now())

// Change the time.
ts = ts.Add(2 * time.Hour)
err := c.Add(2 * time.Hour)
assert.NoError(t, err)

<-time.After(50 * time.Millisecond)

assert.Equal(t, ts, c.Now())

// Change the date.
ts = ts.AddDate(2, 1, 3)
err = c.AddDate(2, 1, 3)
assert.NoError(t, err)

<-time.After(50 * time.Millisecond)

assert.Equal(t, ts, c.Now())

// Unfreeze the clock.
c.Unfreeze()

now = time.Now()

assert.True(t, now.Before(c.Now()))
}

func TestClock_Clock(t *testing.T) {
t.Parallel()

c := clockdog.New()

assert.Equal(t, c, c.Clock())
}
4 changes: 2 additions & 2 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Package main
package main
// Package clockdog provides a clock for tests with cucumber/godog.
package clockdog
14 changes: 14 additions & 0 deletions features/background.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Feature: Test with background

Background:
Given now is "2020-04-05T06:07:08Z"

Scenario: Add days
Given someone adds 2 days to the clock

Then the time is "2020-04-07T06:07:08Z"

Scenario: Add months
Given someone adds 1 month to the clock

Then the time is "2020-05-05T06:07:08Z"
2 changes: 2 additions & 0 deletions features/bootstrap/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package bootstrap provides integration tests.
package bootstrap
Loading

0 comments on commit 9590bbc

Please sign in to comment.