Repository: exercism/cli
Pull request #445 (2017-08-16 14:56:44)

[nextercism] Refactor open command
This implements a function to load up solutions in a slice of paths, and then in the second commit, refactors the open command to use the new function.


Patch:
diff --git a/cmd/open.go b/cmd/open.go
index 5448928..c1b0cff 100644
--- a/cmd/open.go
+++ b/cmd/open.go
@@ -2,7 +2,6 @@ package cmd
 
 import (
 	"fmt"
-	"os"
 
 	"github.com/exercism/cli/browser"
 	"github.com/exercism/cli/config"
@@ -33,16 +32,8 @@ the solution you want to see on the website.
 		paths, err := ws.Locate(args[0])
 		BailOnError(err)
 
-		var solutions []*workspace.Solution
-
-		for _, path := range paths {
-			solution, err := workspace.NewSolution(path)
-			if err != nil {
-				fmt.Fprintf(os.Stderr, err.Error())
-				continue
-			}
-			solutions = append(solutions, solution)
-		}
+		solutions, err := workspace.NewSolutions(paths)
+		BailOnError(err)
 
 		if len(solutions) == 0 {
 			return
diff --git a/fixtures/solutions/alpha/.solution.json b/fixtures/solutions/alpha/.solution.json
new file mode 100644
index 0000000..139f811
--- /dev/null
+++ b/fixtures/solutions/alpha/.solution.json
@@ -0,0 +1,1 @@
+{"id": "alpha"}
diff --git a/fixtures/solutions/bravo/.solution.json b/fixtures/solutions/bravo/.solution.json
new file mode 100644
index 0000000..c1348f5
--- /dev/null
+++ b/fixtures/solutions/bravo/.solution.json
@@ -0,0 +1,1 @@
+{"id": "bravo"}
diff --git a/fixtures/solutions/charlie/.solution.json b/fixtures/solutions/charlie/.solution.json
new file mode 100644
index 0000000..a9135f4
--- /dev/null
+++ b/fixtures/solutions/charlie/.solution.json
@@ -0,0 +1,1 @@
+{"id": "charlie"}
diff --git a/fixtures/solutions/delta/.keep b/fixtures/solutions/delta/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/workspace/solutions.go b/workspace/solutions.go
index 5b97709..b285d0f 100644
--- a/workspace/solutions.go
+++ b/workspace/solutions.go
@@ -13,6 +13,20 @@ import (
 // Solutions is a collection of solutions to interactively choose from.
 type Solutions []*Solution
 
+// NewSolutions loads up the solution metadata for each of the provided paths.
+func NewSolutions(paths []string) (Solutions, error) {
+	var solutions []*Solution
+
+	for _, path := range paths {
+		solution, err := NewSolution(path)
+		if err != nil {
+			return []*Solution{}, err
+		}
+		solutions = append(solutions, solution)
+	}
+	return solutions, nil
+}
+
 // Pick lets a user interactively select a solution from a list.
 func (sx Solutions) Pick(prompt string) (*Solution, error) {
 	// If there's just one, then we're done here.


Test patch:
diff --git a/workspace/solutions_test.go b/workspace/solutions_test.go
index 27175d4..400d7ff 100644
--- a/workspace/solutions_test.go
+++ b/workspace/solutions_test.go
@@ -1,11 +1,40 @@
 package workspace
 
 import (
+	"path/filepath"
+	"runtime"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
 )
 
+func TestNewSolutions(t *testing.T) {
+	_, cwd, _, _ := runtime.Caller(0)
+	root := filepath.Join(cwd, "..", "..", "fixtures", "solutions")
+
+	paths := []string{
+		filepath.Join(root, "alpha"),
+		filepath.Join(root, "bravo"),
+		filepath.Join(root, "charlie"),
+	}
+	sx, err := NewSolutions(paths)
+	assert.NoError(t, err)
+
+	if assert.Equal(t, 3, len(sx)) {
+		assert.Equal(t, "alpha", sx[0].ID)
+		assert.Equal(t, "bravo", sx[1].ID)
+		assert.Equal(t, "charlie", sx[2].ID)
+	}
+
+	paths = []string{
+		filepath.Join(root, "alpha"),
+		filepath.Join(root, "delta"),
+		filepath.Join(root, "bravo"),
+	}
+	_, err = NewSolutions(paths)
+	assert.Error(t, err)
+}
+
 func TestSolutions(t *testing.T) {
 	solutions := []*Solution{
 		{Track: "a", Exercise: "foo"},