Browse Source

Move FieldsN to utility file and add tests.

Ian Adam Naval 5 years ago
parent
commit
7fbc8ebc61
6 changed files with 118 additions and 52 deletions
  1. 13
    0
      common_test.go
  2. 28
    0
      process_test.go
  3. 12
    52
      ps/main.go
  4. 7
    0
      ps/main_test.go
  5. 44
    0
      utils.go
  6. 14
    0
      utils_test.go

+ 13
- 0
common_test.go View File

@@ -0,0 +1,13 @@
1
+package jsh
2
+
3
+import "testing"
4
+
5
+func TestToJson(t *testing.T) {
6
+	fixture := JshOutput{[]string{}, []string{}}
7
+	json := fixture.ToJson()
8
+	expected := "{\"StdOut\":[],\"StdErr\":[]}"
9
+	actual := *json
10
+	if actual != expected {
11
+		t.Error("Empty fixture did not match:\n%s != %s", expected, actual)
12
+	}
13
+}

+ 28
- 0
process_test.go View File

@@ -0,0 +1,28 @@
1
+package jsh
2
+
3
+import "testing"
4
+
5
+func TestNewProcess(t *testing.T) {
6
+	tooManyArgs := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"}
7
+	_, err := NewProcess(tooManyArgs)
8
+	if err == nil {
9
+		t.Errorf("Passing 12 strings should raise an error")
10
+	}
11
+
12
+	tooFewArgs := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}
13
+	_, err = NewProcess(tooFewArgs)
14
+	if err == nil {
15
+		t.Errorf("Passing 10 strings should raise an error")
16
+	}
17
+
18
+	justRightArgs := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"}
19
+	proc, err := NewProcess(justRightArgs)
20
+	if err != nil {
21
+		t.Errorf("Passing 11 strings should not raise an error")
22
+	}
23
+	expected := Process{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"}
24
+	actual := *proc
25
+	if expected != actual {
26
+		t.Errorf("Proc was incorrectly generated:\n%s != %s", expected, actual)
27
+	}
28
+}

+ 12
- 52
ps/main.go View File

@@ -4,49 +4,25 @@ import (
4 4
 	"flag"
5 5
 	"fmt"
6 6
 	"jsh"
7
-	"math"
8 7
 	"os"
9 8
 	"os/exec"
10 9
 	"strings"
11
-	"unicode"
12 10
 )
13 11
 
14
-// FieldsN slices s into substrings after each instance of a whitespace
15
-// character (according to unicode.IsSpace) and returns a slice of those
16
-// substrings. The slice's length is guaranteed to be at most maxN, and
17
-// all leftover fields are put into the last substring.
18
-func FieldsN(s string, maxN int) []string {
19
-	// First count the fields.
20
-	n := 0
21
-	inField := false
22
-	for _, rune := range s {
23
-		wasInField := inField
24
-		inField = !unicode.IsSpace(rune)
25
-		if inField && !wasInField {
26
-			n++
27
-		}
28
-	}
29
-	n = int(math.Min(float64(n), float64(maxN)))
12
+// Converts raw output of "ps" into a slice of Process objects
13
+func PsOutputToProcesses(out string) *[]jsh.Process {
14
+	processes := []jsh.Process{}
15
+	lines := strings.Split(out, "\n")
16
+	header, procs := lines[0], lines[1:]
17
+	numFields := len(strings.Fields(header))
30 18
 
31
-	// Now create them.
32
-	a := make([]string, n)
33
-	na := 0
34
-	fieldStart := -1 // Set to -1 when looking for start of field.
35
-	for i, rune := range s {
36
-		if unicode.IsSpace(rune) && na+1 < maxN {
37
-			if fieldStart >= 0 {
38
-				a[na] = s[fieldStart:i]
39
-				na++
40
-				fieldStart = -1
41
-			}
42
-		} else if fieldStart == -1 {
43
-			fieldStart = i
19
+	for _, proc := range procs {
20
+		p, err := jsh.NewProcess(jsh.FieldsN(proc, numFields))
21
+		if err == nil {
22
+			processes = append(processes, *p)
44 23
 		}
45 24
 	}
46
-	if fieldStart >= 0 { // Last field might end at EOF.
47
-		a[na] = s[fieldStart:]
48
-	}
49
-	return a
25
+	return &processes
50 26
 }
51 27
 
52 28
 // Falls back to procps-ng passing the space-separated arguments in the given
@@ -68,27 +44,11 @@ func fallbackCompletely() *[]byte {
68 44
 	return fallbackCompletelyWithArgs(nil)
69 45
 }
70 46
 
71
-// Converts raw output of "ps" into a slice of Process objects
72
-func psOutputToProcesses(out string) *[]jsh.Process {
73
-	processes := []jsh.Process{}
74
-	lines := strings.Split(out, "\n")
75
-	header, procs := lines[0], lines[1:]
76
-	numFields := len(strings.Fields(header))
77
-
78
-	for _, proc := range procs {
79
-		p, err := jsh.NewProcess(FieldsN(proc, numFields))
80
-		if err == nil {
81
-			processes = append(processes, *p)
82
-		}
83
-	}
84
-	return &processes
85
-}
86
-
87 47
 func runJsonMode() {
88 48
 	// Run procps-ng "ps" with full output
89 49
 	psOut := string(*fallbackCompletelyWithArgs([]string{"auxww"}))
90 50
 
91
-	processesPtr := psOutputToProcesses(psOut)
51
+	processesPtr := PsOutputToProcesses(psOut)
92 52
 	finalOut := jsh.JshOutput{*processesPtr, []string{}}
93 53
 	fmt.Printf("%s", *finalOut.ToJson())
94 54
 }

+ 7
- 0
ps/main_test.go View File

@@ -0,0 +1,7 @@
1
+package main
2
+
3
+import "testing"
4
+
5
+func TestPsOutputToProcesses(t *testing.T) {
6
+
7
+}

+ 44
- 0
utils.go View File

@@ -0,0 +1,44 @@
1
+package jsh
2
+
3
+import (
4
+	"math"
5
+	"unicode"
6
+)
7
+
8
+// FieldsN slices s into substrings after each instance of a whitespace
9
+// character (according to unicode.IsSpace) and returns a slice of those
10
+// substrings. The slice's length is guaranteed to be at most maxN, and
11
+// all leftover fields are put into the last substring.
12
+func FieldsN(s string, maxN int) []string {
13
+	// First count the fields.
14
+	n := 0
15
+	inField := false
16
+	for _, rune := range s {
17
+		wasInField := inField
18
+		inField = !unicode.IsSpace(rune)
19
+		if inField && !wasInField {
20
+			n++
21
+		}
22
+	}
23
+	n = int(math.Min(float64(n), float64(maxN)))
24
+
25
+	// Now create them.
26
+	a := make([]string, n)
27
+	na := 0
28
+	fieldStart := -1 // Set to -1 when looking for start of field.
29
+	for i, rune := range s {
30
+		if unicode.IsSpace(rune) && na+1 < maxN {
31
+			if fieldStart >= 0 {
32
+				a[na] = s[fieldStart:i]
33
+				na++
34
+				fieldStart = -1
35
+			}
36
+		} else if fieldStart == -1 {
37
+			fieldStart = i
38
+		}
39
+	}
40
+	if fieldStart >= 0 { // Last field might end at EOF.
41
+		a[na] = s[fieldStart:]
42
+	}
43
+	return a
44
+}

+ 14
- 0
utils_test.go View File

@@ -0,0 +1,14 @@
1
+package jsh
2
+
3
+import "testing"
4
+
5
+func TestFieldsN(t *testing.T) {
6
+	testString := "Potatoes are the best strings for testing."
7
+	for i := 1; i <= 10; i++ {
8
+		fields := FieldsN(testString, i)
9
+		fieldsLength := len(fields)
10
+		if fieldsLength > i {
11
+			t.Errorf("Expected at most %d fields, got %d", i, fieldsLength)
12
+		}
13
+	}
14
+}

Loading…
Cancel
Save