Skip to content

Commit

Permalink
Merge branch 'dev' into 'master'
Browse files Browse the repository at this point in the history
v1.1.1

See merge request objectbox/objectbox-go!83
  • Loading branch information
vaind committed Feb 14, 2020
2 parents a5d4a17 + 56039c7 commit de02d9a
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 85 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ id, err := box.Put(&Person{ FirstName: "Joe", LastName: "Green" })
Want details? **[Read the docs](https://golang.objectbox.io/)** or
**[check out the API reference](https://godoc.org/github.com/objectbox/objectbox-go/objectbox)**.

Latest release: [v1.1.0 (2019-12-16)](https://golang.objectbox.io/)
Latest release: [v1.1.1 (2020-02-14)](https://golang.objectbox.io/)

Some features
-------------
Expand Down
2 changes: 1 addition & 1 deletion objectbox/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (v Version) String() string {
// VersionGo returns the Version of the ObjectBox-Go binding
func VersionGo() Version {
// for label, use `beta.0` format, increasing the counter for each subsequent release
return Version{1, 1, 0, ""}
return Version{1, 1, 1, ""}
}

// VersionLib returns the Version of the dynamic linked ObjectBox library
Expand Down
34 changes: 17 additions & 17 deletions test/box_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ import (
)

func TestBox(t *testing.T) {
objectBox := iot.LoadEmptyTestObjectBox()
defer objectBox.Close()
box1 := iot.BoxForEvent(objectBox)
box2 := iot.BoxForEvent(objectBox)
env := iot.NewTestEnv()
defer env.Close()
box1 := iot.BoxForEvent(env.ObjectBox)
box2 := iot.BoxForEvent(env.ObjectBox)

assert.Eq(t, box1.Box, box2.Box)
}

func TestPutAsync(t *testing.T) {
objectBox := iot.LoadEmptyTestObjectBox()
defer objectBox.Close()
box := iot.BoxForEvent(objectBox)
env := iot.NewTestEnv()
defer env.Close()
box := iot.BoxForEvent(env.ObjectBox)
err := box.RemoveAll()
assert.NoErr(t, err)

Expand All @@ -47,7 +47,7 @@ func TestPutAsync(t *testing.T) {
assert.NoErr(t, err)
assert.Eq(t, objectId, event.Id)

assert.NoErr(t, objectBox.AwaitAsyncCompletion())
assert.NoErr(t, env.AwaitAsyncCompletion())

count, err := box.Count()
assert.NoErr(t, err)
Expand All @@ -74,9 +74,9 @@ func TestPutAsync(t *testing.T) {
}

func TestUnique(t *testing.T) {
objectBox := iot.LoadEmptyTestObjectBox()
defer objectBox.Close()
box := iot.BoxForEvent(objectBox)
env := iot.NewTestEnv()
defer env.Close()
box := iot.BoxForEvent(env.ObjectBox)

err := box.RemoveAll()
assert.NoErr(t, err)
Expand All @@ -101,9 +101,9 @@ func TestUnique(t *testing.T) {
}

func TestBoxBulk(t *testing.T) {
objectBox := iot.LoadEmptyTestObjectBox()
defer objectBox.Close()
box := iot.BoxForEvent(objectBox)
env := iot.NewTestEnv()
defer env.Close()
box := iot.BoxForEvent(env.ObjectBox)

err := box.RemoveAll()
assert.NoErr(t, err)
Expand Down Expand Up @@ -167,9 +167,9 @@ func TestBoxBulk(t *testing.T) {
}

func TestPut(t *testing.T) {
objectBox := iot.LoadEmptyTestObjectBox()
defer objectBox.Close()
box := iot.BoxForEvent(objectBox)
env := iot.NewTestEnv()
defer env.Close()
box := iot.BoxForEvent(env.ObjectBox)

assert.NoErr(t, box.RemoveAll())

Expand Down
3 changes: 2 additions & 1 deletion test/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import (

// Package builds a single Go package/directory, running `go build path`
func Package(path string) (stdOut []byte, stdErr []byte, err error) {
var cmd = exec.Command("go", "build", path)
var cmd = exec.Command("go", "build")
cmd.Dir = path
stdOut, err = cmd.Output()
if ee, ok := err.(*exec.ExitError); ok {
stdErr = ee.Stderr
Expand Down
8 changes: 4 additions & 4 deletions test/concurrency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ func TestConcurrentPutAsync(t *testing.T) {
}

func concurrentInsert(t *testing.T, count, concurrency int, putAsync bool) {
objectBox := iot.LoadEmptyTestObjectBox()
defer objectBox.Close()
box := iot.BoxForEvent(objectBox)
env := iot.NewTestEnv()
defer env.Close()
box := iot.BoxForEvent(env.ObjectBox)

err := box.RemoveAll()
assert.NoErr(t, err)
Expand Down Expand Up @@ -93,7 +93,7 @@ func concurrentInsert(t *testing.T, count, concurrency int, putAsync bool) {
t.Log("waiting for all goroutines to finish")
wg.Wait()

assert.NoErr(t, objectBox.AwaitAsyncCompletion())
assert.NoErr(t, env.ObjectBox.AwaitAsyncCompletion())

t.Log("validating counts")
if len(errors) != 0 {
Expand Down
54 changes: 46 additions & 8 deletions test/generator/file-io.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,28 @@
package generator

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)

func copyFile(sourceFile, targetFile string) error {
func copyFile(sourceFile, targetFile string, permsOverride os.FileMode) error {
data, err := ioutil.ReadFile(sourceFile)
if err != nil {
return err
}

// copy permissions either from the existing target file or from the source file
var perm os.FileMode
if info, _ := os.Stat(targetFile); info != nil {
perm = info.Mode()
} else if info, err := os.Stat(sourceFile); info != nil {
perm = info.Mode()
} else {
return err
var perm os.FileMode = permsOverride
if perm == 0 {
if info, _ := os.Stat(targetFile); info != nil {
perm = info.Mode()
} else if info, err := os.Stat(sourceFile); info != nil {
perm = info.Mode()
} else {
return err
}
}

err = ioutil.WriteFile(targetFile, data, perm)
Expand All @@ -49,3 +53,37 @@ func fileExists(path string) bool {
_, err := os.Stat(path)
return !os.IsNotExist(err)
}

func copyDirectory(sourceDir, targetDir string, dirPerms, filePerms os.FileMode) error {
if err := os.MkdirAll(targetDir, dirPerms); err != nil {
return err
}

entries, err := ioutil.ReadDir(sourceDir)
if err != nil {
return err
}

for _, entry := range entries {
sourcePath := filepath.Join(sourceDir, entry.Name())
targetPath := filepath.Join(targetDir, entry.Name())

info, err := os.Stat(sourcePath)
if err != nil {
return err
}

if info.IsDir() {
if err := copyDirectory(sourcePath, targetPath, dirPerms, filePerms); err != nil {
return err
}
} else if info.Mode().IsRegular() {
if err := copyFile(sourcePath, targetPath, filePerms); err != nil {
return err
}
} else {
return fmt.Errorf("not a regular file or directory: %s", sourcePath)
}
}
return nil
}
78 changes: 70 additions & 8 deletions test/generator/test-all.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ import (
"github.com/objectbox/objectbox-go/test/build"
)

// this containing module name - used for test case modules
const moduleName = "github.com/objectbox/objectbox-go"

// generateAllDirs walks through the "data" and generates bindings for each subdirectory
// set overwriteExpected to TRUE to update all ".expected" files with the generated content
func generateAllDirs(t *testing.T, overwriteExpected bool) {
Expand All @@ -54,7 +57,57 @@ func generateAllDirs(t *testing.T, overwriteExpected bool) {
}
}

func generateOneDir(t *testing.T, overwriteExpected bool, dir string) {
func generateOneDir(t *testing.T, overwriteExpected bool, srcDir string) {
var dir = srcDir

var errorTransformer = func(err error) error {
return err
}

var cleanup = func() {}
defer func() {
cleanup()
}()

// Test in a temporary directory - if tested by an end user, the repo is read-only.
// This doesn't apply if overwriteExpected is set, as that's only supposed to be run during this lib's development.
if !overwriteExpected {
tempRoot, err := ioutil.TempDir("", "objectbox-generator-test")
assert.NoErr(t, err)

// we can't defer directly because compilation step is run in a separate goroutine after this function exits
cleanup = func() {
assert.NoErr(t, os.RemoveAll(tempRoot))
}

// copy the source dir, including the relative paths (to make sure expected errors contain same paths)
var tempDir = filepath.Join(tempRoot, srcDir)
assert.NoErr(t, copyDirectory(srcDir, tempDir, 0700, 0600))
t.Logf("Testing in a temporary directory %s", tempDir)

// When outside of the project's directory, we need to set up the whole temp dir as its own module, otherwise
// it won't find this `objectbox-go`. Therefore, we create a go.mod file pointing it to the right path.
cwd, err := os.Getwd()
assert.NoErr(t, err)
var modulePath = "example.com/virtual/objectbox-go/test/generator/" + srcDir
var goMod = "module " + modulePath + "\n" +
"replace " + moduleName + " => " + filepath.Join(cwd, "/../../") + "\n" +
"require " + moduleName + " v0.0.0"
assert.NoErr(t, ioutil.WriteFile(path.Join(tempDir, "go.mod"), []byte(goMod), 0600))

// NOTE: we can't change directory using os.Chdir() because it applies to a process/thread, not a goroutine.
// Therefore, we just map paths in received errors, so they match the expected ones.
dir = tempDir
errorTransformer = func(err error) error {
if err == nil {
return nil
}
var str = strings.Replace(err.Error(), tempRoot+string(os.PathSeparator), "", -1)
str = strings.Replace(str, modulePath, moduleName+"/test/generator/"+srcDir, -1)
return errors.New(str)
}
}

modelInfoFile := generator.ModelInfoFile(dir)
modelInfoExpectedFile := modelInfoFile + ".expected"

Expand All @@ -76,18 +129,23 @@ func generateOneDir(t *testing.T, overwriteExpected bool, dir string) {
initialFiles, err := filepath.Glob(filepath.Join(dir, "*.initial"))
assert.NoErr(t, err)
for _, initialFile := range initialFiles {
assert.NoErr(t, copyFile(initialFile, initialFile[0:len(initialFile)-len(".initial")]))
assert.NoErr(t, copyFile(initialFile, initialFile[0:len(initialFile)-len(".initial")], 0))
}

generateAllFiles(t, overwriteExpected, dir, modelInfoFile)
generateAllFiles(t, overwriteExpected, dir, modelInfoFile, errorTransformer)

assertSameFile(t, modelInfoFile, modelInfoExpectedFile, overwriteExpected)
assertSameFile(t, modelFile, modelExpectedFile, overwriteExpected)
}

// verify the result can be built
if !testing.Short() {
// override the defer to prevent cleanup before compilation is actually run
var cleanupAfterCompile = cleanup
cleanup = func() {}

t.Run("compile", func(t *testing.T) {
defer cleanupAfterCompile()
t.Parallel()

var expectedError error
Expand All @@ -97,7 +155,7 @@ func generateOneDir(t *testing.T, overwriteExpected bool, dir string) {
expectedError = errors.New(string(content))
}

stdOut, stdErr, err := build.Package("./" + dir)
stdOut, stdErr, err := build.Package(dir)
if err == nil && expectedError == nil {
// successful
return
Expand All @@ -107,7 +165,11 @@ func generateOneDir(t *testing.T, overwriteExpected bool, dir string) {
assert.Failf(t, "Unexpected PASS during compilation")
}

var receivedError = fmt.Errorf("%s\n%s\n%s", stdOut, stdErr, err)
// On Windows, we're getting a `go finding` message during the build - remove it to be consistent.
var reg = regexp.MustCompile("go: finding " + moduleName + " v0.0.0[ \r\n]+")
stdErr = reg.ReplaceAll(stdErr, nil)

var receivedError = errorTransformer(fmt.Errorf("%s\n%s\n%s", stdOut, stdErr, err))

// Fix paths in the error output on Windows so that it matches the expected error (which always uses '/').
if os.PathSeparator != '/' {
Expand Down Expand Up @@ -137,7 +199,7 @@ func assertSameFile(t *testing.T, file string, expectedFile string, overwriteExp
assert.NoErr(t, err)

if overwriteExpected {
assert.NoErr(t, copyFile(file, expectedFile))
assert.NoErr(t, copyFile(file, expectedFile, 0))
}

contentExpected, err := ioutil.ReadFile(expectedFile)
Expand All @@ -148,7 +210,7 @@ func assertSameFile(t *testing.T, file string, expectedFile string, overwriteExp
}
}

func generateAllFiles(t *testing.T, overwriteExpected bool, dir string, modelInfoFile string) {
func generateAllFiles(t *testing.T, overwriteExpected bool, dir string, modelInfoFile string, errorTransformer func(error) error) {
var modelFile = generator.ModelFile(modelInfoFile)

// remove generated files during development (they might be syntactically wrong)
Expand Down Expand Up @@ -176,7 +238,7 @@ func generateAllFiles(t *testing.T, overwriteExpected bool, dir string, modelInf

t.Logf(" %s", filepath.Base(sourceFile))

err = generator.Process(sourceFile, getOptions(t, sourceFile, modelInfoFile))
err = errorTransformer(generator.Process(sourceFile, getOptions(t, sourceFile, modelInfoFile)))

// handle negative test
var shouldFail = strings.HasSuffix(filepath.Base(sourceFile), ".fail.go")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# github.com/objectbox/objectbox-go/test/generator/testdata/property-update
testdata/property-update/objectbox-model.go:16:24: undefined: ABinding
./objectbox-model.go:16:24: undefined: ABinding

exit status 2
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# github.com/objectbox/objectbox-go/test/generator/testdata/rename-property
testdata/rename-property/objectbox-model.go:16:24: undefined: CBinding
./objectbox-model.go:16:24: undefined: CBinding

exit status 2
12 changes: 6 additions & 6 deletions test/generator/testdata/rename-relation/compile-error.expected
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

# github.com/objectbox/objectbox-go/test/generator/testdata/rename-relation
testdata/rename-relation/objectbox-model.go:22:24: undefined: NegTaskRelIdBinding
testdata/rename-relation/objectbox-model.go:23:24: undefined: NegTaskRelPtrBinding
testdata/rename-relation/objectbox-model.go:24:24: undefined: NegTaskRelValueBinding
testdata/rename-relation/objectbox-model.go:25:24: undefined: NegTaskRelEmbeddedBinding
testdata/rename-relation/objectbox-model.go:26:24: undefined: NegTaskRelManyPtrBinding
testdata/rename-relation/objectbox-model.go:27:24: undefined: NegTaskRelManyValueBinding
./objectbox-model.go:22:24: undefined: NegTaskRelIdBinding
./objectbox-model.go:23:24: undefined: NegTaskRelPtrBinding
./objectbox-model.go:24:24: undefined: NegTaskRelValueBinding
./objectbox-model.go:25:24: undefined: NegTaskRelEmbeddedBinding
./objectbox-model.go:26:24: undefined: NegTaskRelManyPtrBinding
./objectbox-model.go:27:24: undefined: NegTaskRelManyValueBinding

exit status 2
Loading

0 comments on commit de02d9a

Please sign in to comment.