diff --git a/README.md b/README.md new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# diff --git a/analyse.go b/analyse.go index a5903ac..72f4658 100644 --- a/analyse.go +++ b/analyse.go @@ -2,6 +2,7 @@ package redhat import ( "bufio" + "fmt" "os" "sort" "strings" @@ -17,7 +18,7 @@ func (fa *FileAnalyser) AnalyseData() error { return err } - fa.transformToDataRows(contentMap) + fa.transformFromMapToDataRows(contentMap) fa.sortDataRows() return nil @@ -25,6 +26,7 @@ func (fa *FileAnalyser) AnalyseData() error { func (fa *FileAnalyser) parseContent(file *os.File, handler HandleLine) (map[string]int, error) { contentMap := make(map[string]int) + scanner := bufio.NewScanner(file) defer file.Close() @@ -34,7 +36,7 @@ func (fa *FileAnalyser) parseContent(file *os.File, handler HandleLine) (map[str } if err := scanner.Err(); err != nil { - return nil, err + return nil, fmt.Errorf("fail to read and process content: %s", err.Error()) } return contentMap, nil } @@ -44,11 +46,11 @@ func (fa *FileAnalyser) sortDataRows() { if firstItemHasMoreCount(fa, i, j) { return true } - return compareRowsWhenSameCount(fa, i, j) + return compareRowsWhenAreSameCount(fa, i, j) }) } -func (fa *FileAnalyser) transformToDataRows(contentMap map[string]int) { +func (fa *FileAnalyser) transformFromMapToDataRows(contentMap map[string]int) { for key, value := range contentMap { fa.dataRows = append(fa.dataRows, dataRow{ word: key, @@ -73,6 +75,6 @@ func firstItemHasMoreCount(fa *FileAnalyser, i int, j int) bool { return fa.dataRows[i].count > fa.dataRows[j].count } -func compareRowsWhenSameCount(fa *FileAnalyser, i int, j int) bool { +func compareRowsWhenAreSameCount(fa *FileAnalyser, i int, j int) bool { return (fa.dataRows[i].count == fa.dataRows[j].count) && fa.dataRows[i].word > fa.dataRows[j].word } diff --git a/cmd/main.go b/cmd/main.go index aa9bff0..e13acf2 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -13,9 +13,7 @@ const defaultTopLines = 10 func main() { args := os.Args if len(args) < 2 || len(args) > 3 { - panic( - `Please specify valid parameters: go run main.go [file path] [number of top lines] -e.g. go run main.go abc/def.txt or go run main.go abc/def.txt 10 `) + panic(`Usage: go run main.go [file path] [number of top lines]`) } filepath := args[1] diff --git a/print.go b/print.go index a449c54..e5d79c7 100644 --- a/print.go +++ b/print.go @@ -4,10 +4,17 @@ import "fmt" // Output print out the result with target format func (fa *FileAnalyser) Output(topLines int) []string { - resultRows := fa.dataRows[0:topLines] + var resultRows []dataRow + + if len(fa.dataRows) < 10 { + resultRows = fa.dataRows[0:len(fa.dataRows)] + } else { + resultRows = fa.dataRows[0:topLines] + } + reverseDataRows(resultRows) - outputArray := make([]string,0, len(resultRows)) + outputArray := make([]string, 0, len(resultRows)) for index := 0; index < len(resultRows); index++ { outputArray = append(outputArray, fmt.Sprintf("%d %s", resultRows[index].count, resultRows[index].word)) diff --git a/print_test.go b/print_test.go new file mode 100644 index 0000000..e1d93b1 --- /dev/null +++ b/print_test.go @@ -0,0 +1,142 @@ +package redhat + +import ( + "reflect" + "testing" +) + +func TestFileAnalyser_Output(t *testing.T) { + type args struct { + topLines int + } + + tests := []struct { + name string + fileAnalyser *FileAnalyser + args args + want []string + }{ + { + name: "should reverse and only return top 10 items, as well as transform to output style", + fileAnalyser: &FileAnalyser{ + file: nil, + dataRows: []dataRow{ + { + word: "and", + count: 9, + }, + { + word: "hello", + count: 9, + }, + { + word: "Go", + count: 7, + }, + { + word: "me", + count: 7, + }, + { + word: "the", + count: 6, + }, + { + word: "of", + count: 6, + }, + { + word: "shape", + count: 5, + }, + { + word: "libraries", + count: 4, + }, + { + word: "future", + count: 3, + }, + { + word: "Some", + count: 2, + }, + { + word: "Help", + count: 1, + }, + }, + }, + args: args{ + topLines: 10, + }, + want: []string{ + "2 Some", + "3 future", + "4 libraries", + "5 shape", + "6 of", + "6 the", + "7 me", + "7 Go", + "9 hello", + "9 and", + }, + }, + { + name: "should reverse and return all items when total items count is less than 10", + fileAnalyser: &FileAnalyser{ + file: nil, + dataRows: []dataRow{ + { + word: "the", + count: 6, + }, + { + word: "of", + count: 6, + }, + { + word: "shape", + count: 5, + }, + { + word: "libraries", + count: 4, + }, + { + word: "future", + count: 3, + }, + { + word: "Some", + count: 2, + }, + { + word: "Help", + count: 1, + }, + }, + }, + args: args{ + topLines: 10, + }, + want: []string{ + "1 Help", + "2 Some", + "3 future", + "4 libraries", + "5 shape", + "6 of", + "6 the", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.fileAnalyser.Output(tt.args.topLines); !reflect.DeepEqual(got, tt.want) { + t.Errorf("FileAnalyser.Output() = %v, want %v", got, tt.want) + } + }) + } +}