testtime

package module
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2021 License: MIT Imports: 5 Imported by: 3

README

testtime

pkg.go.dev

How to use

testtime package provides testtime.Now() and testtime.SetTime(). testtime.SetTime() stores a fixed time to a map with a caller of testtime.SetTime() as a key. When a caller or its ancestor caller of testtime.Now() is related to a fixed time by testtime.SetTime(), it returns the fixed time otherwise it returns current time which is returned by time.Now().

package main

import (
	"fmt"
	"time"
	"testing"

	"github.com/tenntenn/testtime"
)

func Test(t *testing.T) {
	func() {
		// set zero value
		testtime.SetTime(t, time.Time{})
		// true
		if time.Now().IsZero {
			t.Error("error")
		}
	}()

	func() {
		// set func which return zero value
		f := func() time.Time {
			return time.Time{}
		}
		testtime.SetFunc(t, f)
		// true
		if time.Now().IsZero {
			t.Error("error")
		}
	}()

	// false
	if !time.Now().IsZero {
		t.Error("error")
	}
}

The testtime command replace time.Now to testtime.Now. It prints a file path of overlay JSON which can be given to -overlay flag of go test command.

$ go install github.com/tenntenn/testtime/cmd/testtime@latest
$ go test -overlay=`testtime`
PASS
ok  	main	0.156s

The testtime command creates an overlay JSON file and time.go which is replaced time.Now in $GOPATH/pkg/testtime directory. The testtime command does not update these files without -u flag.

$ cat `testtime` | jq
{
  "Replace": {
    "/usr/local/go/src/time/time.go": "/Users/tenntenn/go/pkg/testtime/time_go1.16.go"
  }
}
$ diff /usr/local/go/src/time/time.go /Users/tenntenn/go/pkg/testtime/time_go1.16.go
79a80,81
> 	"runtime"
> 	"sync"
1066c1068
< func Now() Time {
---
> func _Now() Time {
1521a1524,1568
>
> // It will be added to GOROOT/src/time/time.go.
>
> var timeMap sync.Map
>
> func Now() Time {
> 	pcs := make([]uintptr, 10)
> 	n := runtime.Callers(1, pcs)
> 	frames := runtime.CallersFrames(pcs[:n])
> 	for {
> 		frame, hasNext := frames.Next()
> 		v, ok := timeMap.Load(goroutineID() + ":" + frame.Function)
> 		if ok {
> 			return v.(func() Time)()
> 		}
>
> 		if !hasNext {
> 			break
> 		}
> 	}
> 	return _Now()
> }
>
> func funcName(skip int) (string, bool) {
> 	pc, _, _, ok := runtime.Caller(skip + 1)
> 	if !ok {
> 		return "", false
> 	}
> 	fnc := runtime.FuncForPC(pc)
>
> 	return goroutineID() + ":" + fnc.Name(), true
> }
>
> func goroutineID() string {
> 	var buf [64]byte
> 	n := runtime.Stack(buf[:], false)
> 	for i := 10; i < n; i++ {
> 		if buf[i] == ' ' {
> 			return string(buf[10:i])
> 		}
> 	}
> 	return ""
> }
>
> // End of testtime's code

Examples

See _examples directory.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Now

func Now() time.Time

Now returns a fixed time which is related with the caller function by Set. If the caller is not related with any fixed time, Now calls time.Now and returns its returned value.

func SetFunc added in v0.2.0

func SetFunc(t *testing.T, f func() time.Time) bool

SetFunc sets a function which returns time.Time.

func SetTime added in v0.2.0

func SetTime(t *testing.T, tm time.Time) bool

SetTime sets a fixed time with its caller.

Types

This section is empty.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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