Skip to content

Commit

Permalink
feat: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Osterbind committed Jan 16, 2018
1 parent a631d09 commit 329a79f
Show file tree
Hide file tree
Showing 12 changed files with 215 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: '2'
jobs:
build:
working_directory: /go/src/github.com/qri-io/datasetDiffer
docker:
- image: circleci/golang:1.9
environment:
GOLANG_ENV: test
PORT: 3000
environment:
TEST_RESULTS: /tmp/test-results
steps:
- checkout
- run: mkdir -p $TEST_RESULTS
- run: go get github.com/jstemmer/go-junit-report github.com/golang/lint/golint
- run:
name: Install deps
command: >
go get -v -d -u
github.com/jstemmer/go-junit-report
- run:
name: Run Lint Tests
command: golint ./...
- run:
name: Run Tests
command: |
trap "go-junit-report <${TEST_RESULTS}/go-test.out > ${TEST_RESULTS}/go-test-report.xml" EXIT
./.circleci/cover.test.sh | tee ${TEST_RESULTS}/go-test.out
- run:
name: Publish coverage info to codecov.io
command: bash <(curl -s https://codecov.io/bash)
9 changes: 9 additions & 0 deletions .circleci/cover.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -e
echo "" > coverage.txt
go test -v -race -coverprofile=profile.out -covermode=atomic github.com/qri-io/datasetDiffer
if [ -f profile.out ]; then
cat profile.out >> coverage.txt
rm profile.out
fi
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
[![Qri](https://img.shields.io/badge/made%20by-qri-magenta.svg?style=flat-square)](https://qri.io)
[![GoDoc](https://godoc.org/github.com/qri-io/datasetDiffer?status.svg)](http://godoc.org/github.com/qri-io/datasetDiffer)
[![License](https://img.shields.io/github/license/qri-io/datasetDiffer.svg?style=flat-square)](./LICENSE)
[![Codecov](https://img.shields.io/codecov/c/github/qri-io/datasetDiffer.svg?style=flat-square)](https://codecov.io/gh/qri-io/datasetDiffer)
[![CI](https://img.shields.io/circleci/project/github/qri-io/datasetDiffer.svg?style=flat-square)](https://circleci.com/gh/qri-io/datasetDiffer)
[![Go Report Card](https://goreportcard.com/badge/github.com/qri-io/datasetDiffer)](https://goreportcard.com/report/github.com/qri-io/datasetDiffer)

# datasetDiffer

Utility for Diffing Datasets, currently a very basic placeholder
9 changes: 9 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
codecov:
ci:
- "ci/circle-ci"
notify:
require_ci_to_pass: no
after_n_builds: 2
coverage:
range: "80...100"
comment: off
49 changes: 49 additions & 0 deletions datasetDiffer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package datasetDiffer

import (
"fmt"

"github.com/qri-io/dataset"
)

// Diff contains a string description of a diff
type Diff string

// DiffList contains a slice of diffs in order of descending scope
type DiffList struct {
diffs []Diff
}

// String returns the first (largest scope) change as a string
func (diffList DiffList) String() string {
if len(diffList.diffs) > 0 {
return string(diffList.diffs[0])
}
return ""
}

// DiffDatasets calculates diffs between two datasets and returns a
// dataset. Differences are checked in order of descending scope
// - dataset.Dataset.path
// - dataset.Dataset.Structure.path
// - dataset.Dataset.Data.path
// TODO: make diffs non-trivial
func DiffDatasets(a, b *dataset.Dataset) (*DiffList, error) {
diffList := &DiffList{}
diffDescription := Diff("")
if len(a.Structure.Path().String()) <= 1 || len(b.Structure.Path().String()) <= 1 {
return nil, fmt.Errorf("error: structure path cannot be empty string")
}
if len(a.DataPath) <= 1 || len(b.DataPath) <= 1 {
return nil, fmt.Errorf("error: data path cannot be empty string")
}
if a.Structure.Path() != b.Structure.Path() {
diffDescription = Diff("Structure Changed.")
diffList.diffs = append(diffList.diffs, diffDescription)
}
if a.DataPath != b.DataPath {
diffDescription = Diff("Data Changed.")
diffList.diffs = append(diffList.diffs, diffDescription)
}
return diffList, nil
}
73 changes: 73 additions & 0 deletions datasetDiffer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package datasetDiffer

import (
"fmt"
"io/ioutil"
// "path/filepath"
"testing"
// "github.com/qri-io/qri"
// testrepo "github.com/qri-io/qri/repo/test"
"github.com/qri-io/dataset"
)

func loadTestData(path string) (*dataset.Dataset, error) {
dataBytes, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
d := &dataset.Dataset{}
err = d.UnmarshalJSON(dataBytes)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal dataset: %s", err.Error())
}
return d, nil
}

func TestDiffDataset(t *testing.T) {
//setup

//test cases
cases := []struct {
dsPathA string
dsPathB string
expected string
err string
}{
{"testdata/exampleData_orig.json", "testdata/exampleData_orig.json", "", ""},
{"testdata/exampleData_orig.json", "testdata/exampleData_newData.json", "Data Changed.", ""},
{"testdata/exampleData_orig.json", "testdata/exampleData_newStructure.json", "Structure Changed.", ""},
{"testdata/exampleData_orig.json", "testdata/exampleData_newDataAndStructure.json", "Structure Changed.", ""},
{"testdata/exampleData_orig.json", "testdata/exampleData_blankStructure.json", "", "error: structure path cannot be empty string"},
{"testdata/exampleData_orig.json", "testdata/exampleData_blankData.json", "", "error: data path cannot be empty string"},
}
// load files and execute tests
for i, c := range cases {
pathA := c.dsPathA
pathB := c.dsPathB
//load data
dsA, err := loadTestData(pathA)
if err != nil {
t.Errorf("case %d error: error loading file '%s'", i, pathA)
return
}
dsB, err := loadTestData(pathB)
if err != nil {
t.Errorf("case %d error: error loading file '%s'", i, pathB)
return
}
got, err := DiffDatasets(dsA, dsB)
if err != nil {
if err.Error() == c.err {
continue
} else {
t.Errorf("case %d error mismatch: expected '%s', got '%s'", i, c.err, err.Error())
return
}

}
if got.String() != c.expected {
t.Errorf("case %d response mismatch. expected '%s', got '%s'", i, c.expected, got.String())
continue
}
}
}
6 changes: 6 additions & 0 deletions testdata/exampleData_blankData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"kind": "qri:ds:0",
"DataPath": "",
"path": "123",
"structure": "abc"
}
6 changes: 6 additions & 0 deletions testdata/exampleData_blankStructure.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"kind": "qri:ds:0",
"DataPath": "def",
"path": "123",
"structure": ""
}
6 changes: 6 additions & 0 deletions testdata/exampleData_newData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"kind": "qri:ds:0",
"DataPath": "def",
"path": "123",
"structure": "abc"
}
6 changes: 6 additions & 0 deletions testdata/exampleData_newDataAndStructure.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"kind": "qri:ds:0",
"DataPath": "abc......",
"path": "123",
"structure": "abc......"
}
6 changes: 6 additions & 0 deletions testdata/exampleData_newStructure.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"kind": "qri:ds:0",
"DataPath": "abc",
"path": "123",
"structure": "def"
}
6 changes: 6 additions & 0 deletions testdata/exampleData_orig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"kind": "qri:ds:0",
"DataPath": "abc",
"path": "123",
"structure": "abc"
}

0 comments on commit 329a79f

Please sign in to comment.