Refactor to ensure carriage returns are removed, plus tests
This commit is contained in:
parent
93ac645279
commit
7a8abf8d41
69
main.go
69
main.go
|
@ -31,12 +31,13 @@ import (
|
|||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var outFile bytes.Buffer
|
||||
var re = regexp.MustCompile(`.+\t.*\t.*\t.*`)
|
||||
|
||||
func errorExit(e error, msg string) {
|
||||
if e != nil {
|
||||
|
@ -45,67 +46,64 @@ func errorExit(e error, msg string) {
|
|||
}
|
||||
}
|
||||
|
||||
func buildComment(ln string, eof bool) string {
|
||||
func buildInfoText(ln string) string {
|
||||
var out strings.Builder
|
||||
if eof && ln == "" {
|
||||
return out.String()
|
||||
}
|
||||
out.Grow(20 + len(ln))
|
||||
out.WriteString("i")
|
||||
out.WriteString(strings.TrimRight(ln, "\n\r"))
|
||||
out.WriteString(ln)
|
||||
out.WriteString("\tfalse\tnull.host\t1")
|
||||
if !eof {
|
||||
out.WriteString("\n")
|
||||
}
|
||||
out.WriteString("\n")
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func deconstructComment(ln string) string {
|
||||
func deconstructInfoText(ln string) string {
|
||||
text := strings.SplitN(ln, "\t", 2)
|
||||
comment := text[0]
|
||||
if len(comment) > 1 {
|
||||
return comment[1:] + "\n"
|
||||
infotext := text[0]
|
||||
if len(infotext) > 1 {
|
||||
return infotext[1:] + "\n"
|
||||
}
|
||||
return "\n"
|
||||
}
|
||||
|
||||
func readFile(path string, buildComments bool) {
|
||||
func readFile(path string, build bool) bytes.Buffer {
|
||||
file, err := os.Open(path)
|
||||
errorExit(err, fmt.Sprintf("Unable to open file for reading: %s\n", path))
|
||||
defer file.Close()
|
||||
return processFile(file, build)
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`.+\t.*\t.*\t.*`)
|
||||
reader := bufio.NewReader(file)
|
||||
func processFile(file io.Reader, build bool) bytes.Buffer {
|
||||
scanner := bufio.NewScanner(file)
|
||||
var outFile bytes.Buffer
|
||||
|
||||
if buildComments {
|
||||
for {
|
||||
l, e := reader.ReadString('\n')
|
||||
eof := e != nil
|
||||
if build {
|
||||
for scanner.Scan() {
|
||||
l := scanner.Text()
|
||||
if exp := re.MatchString(l); exp {
|
||||
outFile.WriteString(l)
|
||||
outFile.WriteString("\n")
|
||||
} else {
|
||||
outFile.WriteString(buildComment(l, eof))
|
||||
}
|
||||
if eof {
|
||||
break
|
||||
outFile.WriteString(buildInfoText(l))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for {
|
||||
l, e := reader.ReadString('\n')
|
||||
for scanner.Scan() {
|
||||
l := scanner.Text()
|
||||
if exp := re.MatchString(l); exp && l[0] == 'i' {
|
||||
outFile.WriteString(deconstructComment(l))
|
||||
outFile.WriteString(deconstructInfoText(l))
|
||||
} else {
|
||||
outFile.WriteString(l)
|
||||
}
|
||||
if e != nil {
|
||||
break
|
||||
outFile.WriteString("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
errorExit(err, fmt.Sprintf("Error while reading file\n"))
|
||||
}
|
||||
return outFile
|
||||
}
|
||||
|
||||
func writeFile(path string) {
|
||||
func writeFile(path string, outFile bytes.Buffer) {
|
||||
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0)
|
||||
errorExit(err, fmt.Sprintf("Unable to open file for writing: %s\n", path))
|
||||
defer file.Close()
|
||||
|
@ -127,14 +125,14 @@ default
|
|||
}
|
||||
|
||||
func main() {
|
||||
deconstructCommentLinks := flag.Bool("d", false, "Deconstruct a gophermap's info text lines back to plain text")
|
||||
//command-line flags and responses
|
||||
deconstructInfoTextLines := flag.Bool("d", false, "Deconstruct a gophermap's info text lines back to plain text")
|
||||
header := flag.String("head", "", "Path to a file containing header content")
|
||||
footer := flag.String("foot", "", "Path to a file containing footer content")
|
||||
stdout := flag.Bool("stdout", false, "Instead of writing changes to a file, return them to stdout")
|
||||
flag.Usage = PrintHelp
|
||||
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
|
||||
if l := len(args); l != 1 {
|
||||
|
@ -142,6 +140,7 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
//main program
|
||||
if *header != "" {
|
||||
fmt.Println("Header functionality is not built yet, proceeding with general gophermap conversion...")
|
||||
}
|
||||
|
@ -150,12 +149,12 @@ func main() {
|
|||
fmt.Println("Footer functionality is not built yet, proceeding with general gophermap conversion...")
|
||||
}
|
||||
|
||||
readFile(args[0], !*deconstructCommentLinks)
|
||||
outFile := readFile(args[0], !*deconstructInfoTextLines)
|
||||
|
||||
if *stdout {
|
||||
fmt.Print(outFile.String())
|
||||
} else {
|
||||
writeFile(args[0])
|
||||
writeFile(args[0], outFile)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var buildInfoTextTestCases = []struct {
|
||||
testInput string
|
||||
expectedOutput string
|
||||
}{
|
||||
{
|
||||
//Plain line of text is converted to info text
|
||||
"A line of text",
|
||||
"iA line of text false null.host 1\n",
|
||||
},
|
||||
}
|
||||
|
||||
var processFileTestCases = []struct {
|
||||
gophermap string
|
||||
plaintext string
|
||||
}{
|
||||
{
|
||||
//Plain line of text is converted to info text
|
||||
"iA line of text false null.host 1\n",
|
||||
"A line of text\n",
|
||||
},
|
||||
|
||||
{
|
||||
//Gopher submenu is not converted
|
||||
"1Floodgap Home /home gopher.floodgap.com 70\n",
|
||||
"1Floodgap Home /home gopher.floodgap.com 70\n",
|
||||
},
|
||||
{
|
||||
//HTML file is not converted
|
||||
"hhttp://tildegit.org/sloum/bombadillo url:http://tildegit.org/sloum/bombadillo colorfield.space 70\n",
|
||||
"hhttp://tildegit.org/sloum/bombadillo url:http://tildegit.org/sloum/bombadillo colorfield.space 70\n",
|
||||
},
|
||||
}
|
||||
|
||||
var carriagereturnTestCases = []struct {
|
||||
testInput string
|
||||
expectedOutput string
|
||||
build bool
|
||||
}{
|
||||
{
|
||||
//Plaintext to gophermap
|
||||
"A test line with a carriage return\r\n",
|
||||
"iA test line with a carriage return false null.host 1\n",
|
||||
true,
|
||||
},
|
||||
{
|
||||
//Gophermap to plaintext
|
||||
"iA test line with a cr false null.host 1\r\n",
|
||||
"A test line with a cr\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
//HTML file
|
||||
"hhttp://tildegit.org/sloum/bombadillo url:http://tildegit.org/sloum/bombadillo colorfield.space 70\r\n",
|
||||
"hhttp://tildegit.org/sloum/bombadillo url:http://tildegit.org/sloum/bombadillo colorfield.space 70\n",
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
func TestBuildInfoText(t *testing.T) {
|
||||
for testNumber, testCase := range buildInfoTextTestCases {
|
||||
testOutput := buildInfoText(testCase.testInput)
|
||||
if testCase.expectedOutput != testOutput {
|
||||
t.Errorf(`buildInfoText test case %d failed. Expected "%s", got "%s"`,
|
||||
testNumber,
|
||||
testCase.expectedOutput,
|
||||
testOutput,
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessFileBuild(t *testing.T) {
|
||||
for testNum, testCase := range processFileTestCases {
|
||||
testOutput := processFile(strings.NewReader(testCase.plaintext), true)
|
||||
if testCase.gophermap != testOutput.String() {
|
||||
t.Errorf(`processFile build test case %d failed. Expected "%s", got "%s"`,
|
||||
testNum,
|
||||
testCase.plaintext,
|
||||
testOutput.String(),
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessFileDecon(t *testing.T) {
|
||||
for testNum, testCase := range processFileTestCases {
|
||||
testOutput := processFile(strings.NewReader(testCase.gophermap), false)
|
||||
if testCase.plaintext != testOutput.String() {
|
||||
t.Errorf(`processFile decon test case %d failed. Expected "%s", got "%s"`,
|
||||
testNum,
|
||||
testCase.plaintext,
|
||||
testOutput.String(),
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCarriageReturnsAreExpunged(t *testing.T) {
|
||||
for testNum, testCase := range carriagereturnTestCases {
|
||||
testOutput := processFile(strings.NewReader(testCase.testInput), testCase.build)
|
||||
if testCase.expectedOutput != testOutput.String() {
|
||||
t.Errorf(`CR test case %d failed. Expected "%s", got "%s"`,
|
||||
testNum,
|
||||
testCase.expectedOutput,
|
||||
testOutput.String(),
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue