-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
241 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package conflict | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
var commands = []struct { | ||
command string | ||
ok bool | ||
}{ | ||
{"time", true}, | ||
{"foobar", false}, | ||
} | ||
|
||
func TestRun(t *testing.T) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package editor | ||
|
||
import ( | ||
"bufio" | ||
"io" | ||
"os" | ||
"strings" | ||
) | ||
|
||
// Content represents a the in- and output of an extedit session. | ||
type Content struct { | ||
c []string | ||
reader io.Reader | ||
} | ||
|
||
func (c Content) Read(b []byte) (int, error) { | ||
return c.reader.Read(b) | ||
} | ||
|
||
func (c Content) String() string { | ||
return strings.Join(c.c, "\n") | ||
} | ||
|
||
// contentFromReader creates a new Content object by scanning an io.Reader using a bufio.SplitFunc | ||
func contentFromReader(content io.Reader, split bufio.SplitFunc) (Content, error) { | ||
c := Content{} | ||
scanner := bufio.NewScanner(content) | ||
scanner.Split(split) | ||
|
||
for scanner.Scan() { | ||
c.c = append(c.c, scanner.Text()) | ||
} | ||
c.reader = strings.NewReader(c.String()) | ||
|
||
return c, scanner.Err() | ||
} | ||
|
||
func contentFromFile(filename string, split bufio.SplitFunc) (Content, error) { | ||
file, err := os.Open(filename) | ||
if err != nil { | ||
return Content{}, err | ||
} | ||
defer file.Close() | ||
|
||
return contentFromReader(file, split) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package editor | ||
|
||
import ( | ||
"bufio" | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
|
||
"github.com/mkchoi212/fac/conflict" | ||
) | ||
|
||
const defaultEditor = "vim" | ||
|
||
type Session struct { | ||
input Content | ||
result Content | ||
SplitFunc bufio.SplitFunc | ||
} | ||
|
||
// Open starts a text-editor with the contents of content. | ||
// It returns edited content after user closes the editor | ||
func Open(conf *conflict.Conflict) (output []string, err error) { | ||
s := NewSession() | ||
|
||
lines := append([]string{}, conf.LocalLines...) | ||
lines = append(lines, "=======\n") | ||
lines = append(lines, conf.IncomingLines...) | ||
|
||
content := strings.NewReader(strings.Join(lines, "")) | ||
input, err := contentFromReader(content, s.SplitFunc) | ||
|
||
if err != nil { | ||
return | ||
} | ||
|
||
fileName, err := writeTmpFile(input) | ||
if err != nil { | ||
return | ||
} | ||
|
||
cmd := editorCmd(fileName) | ||
err = cmd.Run() | ||
if err != nil { | ||
return | ||
} | ||
|
||
newContent, err := contentFromFile(fileName, s.SplitFunc) | ||
if err != nil { | ||
return | ||
} | ||
|
||
output = newContent.c | ||
|
||
return | ||
} | ||
|
||
func NewSession() *Session { | ||
return &Session{SplitFunc: bufio.ScanLines} | ||
} | ||
|
||
// writeTmpFile writes content to a temporary file and returns | ||
// the path to the file | ||
func writeTmpFile(content io.Reader) (string, error) { | ||
f, err := ioutil.TempFile("", "") | ||
|
||
if err != nil { | ||
return "", err | ||
} | ||
|
||
io.Copy(f, content) | ||
f.Close() | ||
return f.Name(), nil | ||
} | ||
|
||
// editorCmd creates a os/exec.Cmd to open | ||
// filename in an editor ready to be run() | ||
func editorCmd(filename string) *exec.Cmd { | ||
editorPath := os.Getenv("EDITOR") | ||
if editorPath == "" { | ||
editorPath = defaultEditor | ||
} | ||
editor := exec.Command(editorPath, filename) | ||
|
||
editor.Stdin = os.Stdin | ||
editor.Stdout = os.Stdout | ||
editor.Stderr = os.Stderr | ||
|
||
return editor | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,83 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"io/ioutil" | ||
"os" | ||
"reflect" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/mkchoi212/fac/color" | ||
"github.com/mkchoi212/fac/conflict" | ||
) | ||
|
||
func TestFinalizeChanges(t *testing.T) { | ||
c := conflict.Conflict{} | ||
c.Choice = Local | ||
c.Start = 4 | ||
c.End = 10 | ||
c.LocalPureLines = []string{ | ||
"$ go get github.com/mkchoi212/fac\n", | ||
var dummyFile = conflict.File{Name: "Foobar"} | ||
var dummyConflicts = []*conflict.Conflict{ | ||
{Choice: conflict.Local, File: &dummyFile}, | ||
{Choice: conflict.Local, File: &dummyFile}, | ||
{Choice: 0, File: &dummyFile}, | ||
} | ||
|
||
var expected_two_resolved = []string{ | ||
"[32;1m✔ Foobar: 0[0m", | ||
"[32;1m✔ Foobar: 0[0m", | ||
"[31;1m✘ Foobar: 0[0m", | ||
"", | ||
"Resolved [31;2m2 [0mconflict(s) out of [31;2m3[0m", | ||
} | ||
|
||
var expected_all_resolved = []string{ | ||
"[32;1m✔ Foobar: 0[0m", | ||
"[32;1m✔ Foobar: 0[0m", | ||
"[32;1m✔ Foobar: 0[0m", | ||
"[32;1m", | ||
"Fixed All Conflicts 🎉[0m", | ||
"", | ||
} | ||
|
||
func TestPrintHelp(t *testing.T) { | ||
var b bytes.Buffer | ||
printHelp(&b) | ||
|
||
out := b.String() | ||
if out != color.Blue(color.Regular, instruction) { | ||
t.Errorf("PrintHelp failed: wanted blue colored %s..., got %s", instruction[:45], out) | ||
} | ||
} | ||
|
||
func TestSummary(t *testing.T) { | ||
// Capture stdout | ||
oldStdout := os.Stdout | ||
r, w, _ := os.Pipe() | ||
os.Stdout = w | ||
|
||
printSummary(dummyConflicts) | ||
dummyConflicts[2].Choice = conflict.Local | ||
printSummary(dummyConflicts) | ||
|
||
dummyLines := []string{ | ||
"## 👷 Installation\n", | ||
"Execute:\n", | ||
"```bash\n", | ||
"<<<<<<< Updated upstream:assets/README.md\n", | ||
"$ go get github.com/mkchoi212/fac\n", | ||
"||||||| merged common ancestors\n", | ||
"$ go get github.com/parliament/fac\n", | ||
"=======\n", | ||
"$ go get github.com/parliament/facc\n", | ||
">>>>>>> Stashed changes:README.md\n", | ||
"```\n", | ||
w.Close() | ||
out, _ := ioutil.ReadAll(r) | ||
os.Stdout = oldStdout | ||
output := strings.Split(string(out), "\n") | ||
expected := append(expected_two_resolved, expected_all_resolved...) | ||
|
||
if len(expected) != len(output) { | ||
t.Errorf("Summary failed: got \n%v, wanted \n%v", output, expected) | ||
} | ||
|
||
output := strings.Join(FinalizeChanges([]conflict.Conflict{c}, dummyLines), "") | ||
expected := strings.Join([]string{ | ||
"## 👷 Installation\n", | ||
"Execute:\n", | ||
"```bash\n", | ||
"$ go get github.com/mkchoi212/fac\n", | ||
"```\n", | ||
}, "") | ||
|
||
if output != expected { | ||
t.Errorf("FinalizeChanges was incorrect: got \n%s, want \n%s", output, expected) | ||
for i := range expected { | ||
expectedLine := []byte(expected[i]) | ||
outputLine := []byte(output[i]) | ||
// Remove ESC bytes | ||
outputLine = bytes.Trim(outputLine, string([]byte{27})) | ||
|
||
if len(expectedLine) == 0 { | ||
continue | ||
} | ||
|
||
if !(reflect.DeepEqual(expectedLine, outputLine)) { | ||
t.Errorf("Summary failed: got %s, wanted %s", outputLine, expectedLine) | ||
} | ||
} | ||
} |