Repository: SimonBaeumer/commander
Pull request #8 (2019-03-06 14:11:16)

Use contains as default, add coverage report


Patch:
diff --git a/.gitignore b/.gitignore
index e9a3516..29d0919 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
 .idea
-commander
\ No newline at end of file
+commander
+
+coverage.out
+coverage
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 99c9d30..5131d74 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,11 +1,12 @@
 language: go
 
 env:
-  - GO111MODULE=on
+  global:
+    - GO111MODULE=on
+    - CC_TEST_REPORTER_ID=4015795135868ee4781bd8cad1d345c20e7d0c2ef6ad5b0f08ccb13da24e66a1
 
 stages:
   - test
-  #- deploy
 
 go:
   - 1.11.x
@@ -21,27 +22,19 @@ before_install:
 
 jobs:
   include:
-    - name: "Go lint"
-      stage: test
-      script: make lint
-
-    - name: "Unit tests"
-      script: make test
-
-    - name: "Integration test"
-      script: make test-integration
-
-   # - stage: deploy
-   #   name: "Deployment"
-   #   if: tag IS present
-   #   deploy:
-   #     script: skip
-   #     provider: releases
-   #     api_key:
-   #       secure: #TODO
-   #     file: #TODO
-   #       - commander
-   #     skip_cleanup: true
-   #     on:
-   #       repo: SimonBaeumer/commander
-   #       tags: true
+  - name: Go lint
+    stage: test
+    script: make lint
+
+  - name: Unit tests
+    before_script:
+      - curl https://s3.amazonaws.com/codeclimate/test-reporter/test-reporter-0.6.3-linux-amd64 --output test-reporter
+      - chmod +x test-reporter
+      - ./test-reporter before-build
+    script:
+      - make test-coverage
+    after_script:
+      - ./test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
+
+  - name: Integration test
+    script: make test-integration
diff --git a/Makefile b/Makefile
index 102b6cb..cd3e1b4 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,10 @@ test:
 	$(info INFO: Starting build $@)
 	go test ./...
 
+test-coverage:
+	$(info INFO: Starting build $@)
+	go test -coverprofile coverage.out ./...
+
 test-integration: build
 	$(info INFO: Starting build $@)
 	./commander test
diff --git a/README.md b/README.md
index cffbf6e..488a9a0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
 [![Build Status](https://travis-ci.org/SimonBaeumer/commander.svg?branch=master)](https://travis-ci.org/SimonBaeumer/commander)
 [![Go Report Card](https://goreportcard.com/badge/github.com/SimonBaeumer/commander)](https://goreportcard.com/report/github.com/SimonBaeumer/commander)
-
+[![Maintainability](https://api.codeclimate.com/v1/badges/cc848165784e0f809a51/maintainability)](https://codeclimate.com/github/SimonBaeumer/commander/maintainability)
+[![Test Coverage](https://api.codeclimate.com/v1/badges/cc848165784e0f809a51/test_coverage)](https://codeclimate.com/github/SimonBaeumer/commander/test_coverage)
 # Commander
 
 Testing tool for command line applications.
diff --git a/commander.yaml b/commander.yaml
index 3885c67..3c96e4a 100644
--- a/commander.yaml
+++ b/commander.yaml
@@ -9,19 +9,24 @@ tests:
 
   it should execute tests:
     command: ./commander test ./integration/commander_test.yaml
-    stdout:
-      contains:
-        - ✓ it should exit with error code
+    stdout: ✓ it should exit with error code
     exit-code: 0
 
   it should assert that commander will fail:
     command: ./commander test ./integration/failing_suite.yaml
     stdout:
       contains:
-        - ✗ it will fail
+        - ✗ it will fail, on property 'ExitCode'
+        - "Count: 1, Failed: 1"
     exit-code: 1
 
   it should assert stderr:
     command: ">&2 echo hello"
     stderr: hello
+    exit-code: 0
+
+  it should assert exactly:
+    command: echo hello
+    stdout:
+      exactly: hello
     exit-code: 0
\ No newline at end of file
diff --git a/pkg/commander.go b/pkg/commander.go
index 95b548c..14e4ba4 100644
--- a/pkg/commander.go
+++ b/pkg/commander.go
@@ -53,7 +53,7 @@ func printFailures(results []runtime.TestResult) {
 
     for _, r := range results {
         if !r.ValidationResult.Success {
-            fmt.Println(au.Bold(au.Red("✗ " + r.TestCase.Title)))
+            fmt.Println(au.Bold(au.Red("✗ " + r.TestCase.Title + ", on property '" + r.FailedProperty + "'")))
             fmt.Println(r.ValidationResult.Diff)
         }
     }
diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go
index 313143f..26ad3b3 100644
--- a/pkg/runtime/runtime.go
+++ b/pkg/runtime/runtime.go
@@ -65,6 +65,7 @@ type CommandUnderTest struct {
 type TestResult struct {
     TestCase         TestCase
     ValidationResult ValidationResult
+    FailedProperty   string
 }
 
 // Start starts the given test suite
@@ -121,6 +122,7 @@ func runTest(test TestCase) TestResult {
         return TestResult{
             ValidationResult: validationResult,
             TestCase:         test,
+            FailedProperty:   Stdout,
         }
     }
 
@@ -129,6 +131,7 @@ func runTest(test TestCase) TestResult {
         return TestResult{
             ValidationResult: validationResult,
             TestCase:         test,
+            FailedProperty: Stderr,
         }
     }
 
@@ -138,6 +141,7 @@ func runTest(test TestCase) TestResult {
         return TestResult{
             ValidationResult: validationResult,
             TestCase: test,
+            FailedProperty: ExitCode,
         }
     }
 
diff --git a/pkg/runtime/validator.go b/pkg/runtime/validator.go
index a5beaa5..ebf6b5c 100644
--- a/pkg/runtime/validator.go
+++ b/pkg/runtime/validator.go
@@ -92,7 +92,6 @@ func (v EqualValidator) Validate(got interface{}, expected interface{}) Validati
 		}
 	}
 
-
 	diff := difflib.UnifiedDiff{
 		A: difflib.SplitLines(fmt.Sprintf("%d", got.(int))),
 		B: difflib.SplitLines(fmt.Sprintf("%d", expected.(int))),
diff --git a/pkg/suite/yaml_suite.go b/pkg/suite/yaml_suite.go
index 2b76b2b..d1fe620 100644
--- a/pkg/suite/yaml_suite.go
+++ b/pkg/suite/yaml_suite.go
@@ -119,7 +119,7 @@ func (y *YAMLConfig) convertToExpectedOut(value interface{}) runtime.ExpectedOut
     switch value.(type) {
     //If only a string was passed it is assigned to exactly automatically
     case string:
-        exp.Exactly = toString(value)
+        exp.Contains = []string{toString(value)}
         break
 
     //If there is nested map set the properties will be assigned to the contains


Test patch:
diff --git a/pkg/runtime/validator_test.go b/pkg/runtime/validator_test.go
new file mode 100644
index 0000000..7673a4e
--- /dev/null
+++ b/pkg/runtime/validator_test.go
@@ -0,0 +1,50 @@
+package runtime
+
+import (
+    "github.com/stretchr/testify/assert"
+    "testing"
+)
+
+func Test_NewValidator_Text(t *testing.T) {
+    got := NewValidator(Text)
+    assert.IsType(t, TextValidator{}, got)
+}
+
+func Test_NewValidator_Contains(t *testing.T) {
+    got := NewValidator(Contains)
+    assert.IsType(t, ContainsValidator{}, got)
+}
+
+func Test_NewValidator_Equal(t *testing.T) {
+    got := NewValidator(Equal)
+    assert.IsType(t, EqualValidator{}, got)
+}
+
+func TestTextValidator_Validate(t *testing.T) {
+    v := TextValidator{}
+    got := v.Validate("test", "test")
+    assert.True(t, got.Success)
+}
+
+func TestTextValidator_ValidateFails(t *testing.T) {
+    v := TextValidator{}
+    got := v.Validate("test", "unequal")
+    assert.False(t, got.Success)
+    assert.Contains(t, got.Diff, "+unequal")
+    assert.Contains(t, got.Diff, "-test")
+}
+
+func TestEqualValidator_Validate(t *testing.T) {
+    v := EqualValidator{}
+    got := v.Validate(1, 1)
+    assert.True(t, got.Success)
+}
+
+func TestEqualValidator_ValidateFails(t *testing.T) {
+    v := EqualValidator{}
+    got := v.Validate(1, 0)
+    assert.False(t, got.Success)
+    assert.Contains(t, got.Diff, "+0")
+    assert.Contains(t, got.Diff, "-1")
+}
+
diff --git a/pkg/suite/yaml_suite_test.go b/pkg/suite/yaml_suite_test.go
index da44dea..6d00723 100644
--- a/pkg/suite/yaml_suite_test.go
+++ b/pkg/suite/yaml_suite_test.go
@@ -22,8 +22,8 @@ tests:
 	assert.Equal(t, "echo hello", tests[0].Command.Cmd)
 	assert.Equal(t, 0, tests[0].Expected.ExitCode)
 	assert.Equal(t, "it should print hello", tests[0].Title)
-	assert.Equal(t, "hello", tests[0].Expected.Stdout.Exactly)
-	assert.Equal(t, "anything", tests[0].Expected.Stderr.Exactly)
+	assert.Equal(t, "hello", tests[0].Expected.Stdout.Contains[0])
+	assert.Equal(t, "anything", tests[0].Expected.Stderr.Contains[0])
 }
 
 func TestYAMLConfig_UnmarshalYAML_ShouldUseTitleAsCommand(t *testing.T) {