mirror of
https://github.com/on4kjm/FLEcli.git
synced 2025-01-18 13:01:09 +01:00
Improve tests coverage
This commit is contained in:
parent
0b9fb5bc78
commit
3eeda8fd79
23 changed files with 1024 additions and 111 deletions
|
@ -19,6 +19,7 @@ limitations under the License.
|
|||
import (
|
||||
"FLEcli/fleprocess"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -34,7 +35,7 @@ var csvCmd = &cobra.Command{
|
|||
// and usage of using your command. For example:
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
//if args is empty, throw an error
|
||||
//if args is empty, throw an error (Cobra will display the )
|
||||
if len(args) == 0 {
|
||||
//TODO: fix this ugly statement (because I am lazy)
|
||||
return fmt.Errorf("Missing input file %s", "")
|
||||
|
@ -47,9 +48,11 @@ var csvCmd = &cobra.Command{
|
|||
return fmt.Errorf("Too many arguments.%s", "")
|
||||
}
|
||||
|
||||
|
||||
//TODO: should return an error
|
||||
fleprocess.ProcessCsvCommand(inputFilename, outputCsvFilename, isInterpolateTime, isOverwriteCsv)
|
||||
if err := fleprocess.ProcessCsvCommand(inputFilename, outputCsvFilename, isInterpolateTime, isOverwriteCsv); err != nil {
|
||||
fmt.Println("\nUnable to generate CSV file:")
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -61,4 +64,3 @@ func init() {
|
|||
|
||||
csvCmd.PersistentFlags().BoolVarP(&isOverwriteCsv, "overwrite", "o", false, "Overwrites the output file if it exisits")
|
||||
}
|
||||
|
||||
|
|
|
@ -37,10 +37,10 @@ var loadCmd = &cobra.Command{
|
|||
//if args is empty, throw an error
|
||||
if len(args) == 0 {
|
||||
//TODO: fix this ugly statement (because I am lazy)
|
||||
return fmt.Errorf("Missing input file %s","")
|
||||
return fmt.Errorf("Missing input file %s", "")
|
||||
}
|
||||
if len(args) > 1 {
|
||||
return fmt.Errorf("Too many arguments.%s","")
|
||||
return fmt.Errorf("Too many arguments.%s", "")
|
||||
}
|
||||
inputFilename = args[0]
|
||||
fleprocess.LoadFile(inputFilename, isInterpolateTime)
|
||||
|
@ -53,5 +53,3 @@ func init() {
|
|||
|
||||
loadCmd.PersistentFlags().BoolVarP(&isInterpolateTime, "interpolate", "i", false, "Interpolates the missing time entries.")
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
//Documentation of SOTA CSV format: https://www.sotadata.org.uk/en/upload/activator/csv/info
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
//ProcessCsvCommand loads an FLE input to produce a SOTA CSV
|
||||
func ProcessCsvCommand(inputFilename, outputCsvFilename string, isInterpolateTime, isOverwriteCsv bool) {
|
||||
|
||||
verifiedOutputFilename, filenameWasOK := buildOutputFilename(outputCsvFilename, inputFilename, isOverwriteCsv, ".csv")
|
||||
|
||||
// if the output file could not be parsed correctly do noting
|
||||
if filenameWasOK {
|
||||
loadedLogFile, isLoadedOK := LoadFile(inputFilename, isInterpolateTime)
|
||||
|
||||
//TODO: move this in a function so that it can be more easily tested
|
||||
if isLoadedOK {
|
||||
if len(loadedLogFile) == 0 {
|
||||
fmt.Println("No useful data read. Aborting...")
|
||||
return
|
||||
}
|
||||
|
||||
//check if we have the necessary information for the type
|
||||
if loadedLogFile[0].MySOTA == "" {
|
||||
fmt.Println("Missing MY-SOTA reference. Aborting...")
|
||||
return
|
||||
}
|
||||
|
||||
outputCsv(verifiedOutputFilename, loadedLogFile)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ func ProcessAdifCommand(inputFilename, outputFilename string, isInterpolateTime,
|
|||
|
||||
// if the output file could not be parsed correctly do noting
|
||||
if filenameWasOK {
|
||||
loadedLogFile, isLoadedOK := LoadFile(inputFilename,isInterpolateTime)
|
||||
loadedLogFile, isLoadedOK := LoadFile(inputFilename, isInterpolateTime)
|
||||
|
||||
if isLoadedOK {
|
||||
if len(loadedLogFile) == 0 {
|
||||
|
|
|
@ -17,9 +17,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
@ -87,41 +85,11 @@ func buildAdif(fullLog []LogLine, isWWFF bool, isSOTA bool) (adifList []string)
|
|||
return adifList
|
||||
}
|
||||
|
||||
// writeFile writes the in-memory data (lines) to a file
|
||||
func writeFile(outputFile string, adifData []string) {
|
||||
|
||||
//TODO: check access rights
|
||||
f, err := os.Create(outputFile)
|
||||
checkFileError(err)
|
||||
|
||||
defer f.Close()
|
||||
|
||||
w := bufio.NewWriter(f)
|
||||
|
||||
lineCount := 0
|
||||
for _, adifLine := range adifData {
|
||||
_, err := w.WriteString(adifLine + "\n")
|
||||
checkFileError(err)
|
||||
|
||||
w.Flush()
|
||||
checkFileError(err)
|
||||
lineCount++
|
||||
}
|
||||
fmt.Printf("\nSuccessfully wrote %d lines to file \"%s\"\n", lineCount, outputFile)
|
||||
}
|
||||
|
||||
// adifElement generated the ADIF sub-element
|
||||
func adifElement(elementName, elementValue string) (element string) {
|
||||
return fmt.Sprintf("<%s:%d>%s ", strings.ToUpper(elementName), len(elementValue), elementValue)
|
||||
}
|
||||
|
||||
// checkFileError handles file related errors
|
||||
func checkFileError(e error) {
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
}
|
||||
|
||||
//adifDate converts a date in YYYY-MM-DD format to YYYYMMDD
|
||||
func adifDate(inputDate string) (outputDate string) {
|
||||
const FLEdateFormat = "2006-01-02"
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
|
|
@ -2,6 +2,22 @@ package fleprocess
|
|||
|
||||
import "testing"
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
func Test_getBraketedData(t *testing.T) {
|
||||
type args struct {
|
||||
inputLine string
|
||||
|
|
103
fleprocess/csv_process.go
Normal file
103
fleprocess/csv_process.go
Normal file
|
@ -0,0 +1,103 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
//Documentation of the SOTA CSV format: https://www.sotadata.org.uk/en/upload/activator/csv/info
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//ProcessCsvCommand loads an FLE input to produce a SOTA CSV
|
||||
func ProcessCsvCommand(inputFilename, outputCsvFilename string, isInterpolateTime, isOverwriteCsv bool) error {
|
||||
|
||||
if verifiedOutputFilename, filenameWasOK := buildOutputFilename(outputCsvFilename, inputFilename, isOverwriteCsv, ".csv"); filenameWasOK == true {
|
||||
if loadedLogFile, isLoadedOK := LoadFile(inputFilename, isInterpolateTime); isLoadedOK == true {
|
||||
if err := validateDataForSotaCsv(loadedLogFile); err != nil {
|
||||
return err
|
||||
}
|
||||
outputCsv(verifiedOutputFilename, loadedLogFile)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("There were input file parsing errors. Could not generate CSV file")
|
||||
}
|
||||
//TODO: we need something more explicit here
|
||||
return fmt.Errorf("Failed to compute or validate output file name")
|
||||
}
|
||||
|
||||
func validateDataForSotaCsv(loadedLogFile []LogLine) error {
|
||||
if len(loadedLogFile) == 0 {
|
||||
return fmt.Errorf("No QSO found")
|
||||
}
|
||||
|
||||
//MySOTA and MyCall are header values. If missing on the first line, it will be missing at every line
|
||||
if loadedLogFile[0].MySOTA == "" {
|
||||
return fmt.Errorf("Missing MY-SOTA reference")
|
||||
}
|
||||
if loadedLogFile[0].MyCall == "" {
|
||||
return fmt.Errorf("Missing MyCall")
|
||||
}
|
||||
|
||||
var errorsBuffer strings.Builder
|
||||
//We accumulate the errors messages
|
||||
for i := 0; i < len(loadedLogFile); i++ {
|
||||
|
||||
//Compute the error location for a meaning full error
|
||||
var errorLocation string
|
||||
if loadedLogFile[i].Time == "" {
|
||||
errorLocation = fmt.Sprintf("for log entry #%d", i+1)
|
||||
} else {
|
||||
errorLocation = fmt.Sprintf("for log entry at %s (#%d)", loadedLogFile[i].Time, i+1)
|
||||
}
|
||||
|
||||
if loadedLogFile[i].Date == "" {
|
||||
if errorsBuffer.String() != "" {
|
||||
errorsBuffer.WriteString(fmt.Sprintf(", "))
|
||||
}
|
||||
errorsBuffer.WriteString(fmt.Sprintf("missing date %s", errorLocation))
|
||||
}
|
||||
if loadedLogFile[i].Band == "" {
|
||||
if errorsBuffer.String() != "" {
|
||||
errorsBuffer.WriteString(fmt.Sprintf(", "))
|
||||
}
|
||||
errorsBuffer.WriteString(fmt.Sprintf("missing band %s", errorLocation))
|
||||
}
|
||||
if loadedLogFile[i].Mode == "" {
|
||||
if errorsBuffer.String() != "" {
|
||||
errorsBuffer.WriteString(fmt.Sprintf(", "))
|
||||
}
|
||||
errorsBuffer.WriteString(fmt.Sprintf("missing mode %s", errorLocation))
|
||||
}
|
||||
if loadedLogFile[i].Call == "" {
|
||||
if errorsBuffer.String() != "" {
|
||||
errorsBuffer.WriteString(fmt.Sprintf(", "))
|
||||
}
|
||||
errorsBuffer.WriteString(fmt.Sprintf("missing call %s", errorLocation))
|
||||
}
|
||||
if loadedLogFile[i].Time == "" {
|
||||
if errorsBuffer.String() != "" {
|
||||
errorsBuffer.WriteString(fmt.Sprintf(", "))
|
||||
}
|
||||
errorsBuffer.WriteString(fmt.Sprintf("missing QSO time %s", errorLocation))
|
||||
}
|
||||
}
|
||||
if errorsBuffer.String() != "" {
|
||||
return fmt.Errorf(errorsBuffer.String())
|
||||
}
|
||||
return nil
|
||||
}
|
80
fleprocess/csv_process_test.go
Normal file
80
fleprocess/csv_process_test.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package fleprocess
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_validateDataForSotaCsv(t *testing.T) {
|
||||
type args struct {
|
||||
loadedLogFile []LogLine
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want error
|
||||
}{
|
||||
{
|
||||
"Happy Case",
|
||||
args{loadedLogFile: []LogLine{
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "time", Call: "call"},
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "time", Call: "call"},
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "time", Call: "call"}},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"Missing Date",
|
||||
args{loadedLogFile: []LogLine{
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "12:01", Call: "call"},
|
||||
{Date: "", MyCall: "myCall", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "12:02", Call: "call"},
|
||||
{Date: "", MyCall: "myCall", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "12:03", Call: "call"}},
|
||||
},
|
||||
fmt.Errorf("missing date for log entry at 12:02 (#2), missing date for log entry at 12:03 (#3)"),
|
||||
},
|
||||
{
|
||||
"Missing MyCall",
|
||||
args{loadedLogFile: []LogLine{
|
||||
{Date: "date", MyCall: "", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "12:01", Call: "call"},
|
||||
{Date: "date", MyCall: "", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "12:02", Call: "call"},
|
||||
{Date: "date", MyCall: "", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "12:03", Call: "call"}},
|
||||
},
|
||||
fmt.Errorf("Missing MyCall"),
|
||||
},
|
||||
{
|
||||
"Missing MySota",
|
||||
args{loadedLogFile: []LogLine{
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "", Mode: "mode", Band: "band", Time: "time", Call: "call"},
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "", Mode: "mode", Band: "band", Time: "time", Call: "call"},
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "", Mode: "mode", Band: "band", Time: "time", Call: "call"}},
|
||||
},
|
||||
fmt.Errorf("Missing MY-SOTA reference"),
|
||||
},
|
||||
{
|
||||
"Misc. missing data (Band, Time, Mode, Call)",
|
||||
args{loadedLogFile: []LogLine{
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "mySota", Mode: "mode", Band: "", Time: "", Call: "call"},
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "mySota", Mode: "", Band: "band", Time: "12:02", Call: "call"},
|
||||
{Date: "date", MyCall: "myCall", MySOTA: "mySota", Mode: "mode", Band: "band", Time: "12:03", Call: ""}},
|
||||
},
|
||||
fmt.Errorf("missing band for log entry #1, missing QSO time for log entry #1, missing mode for log entry at 12:02 (#2), missing call for log entry at 12:03 (#3)"),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := validateDataForSotaCsv(tt.args.loadedLogFile)
|
||||
if tt.want == nil || got == nil {
|
||||
if tt.want == nil && got != nil {
|
||||
t.Errorf("validateDataForSotaCsv() = %v, want %v", got, nil)
|
||||
}
|
||||
if tt.want != nil && got == nil {
|
||||
t.Errorf("validateDataForSotaCsv() = %v, want %v", nil, tt.want)
|
||||
}
|
||||
} else {
|
||||
if got.Error() != tt.want.Error() {
|
||||
t.Errorf("validateDataForSotaCsv() = %v, want %v", got, tt.want)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -25,8 +25,6 @@ import (
|
|||
// outputAdif generates and writes data in ADIF format
|
||||
func outputCsv(outputFile string, fullLog []LogLine) {
|
||||
|
||||
//TODO: validate input data for combination
|
||||
|
||||
//convert the log data to an in-memory ADIF file
|
||||
csvData := buildCsv(fullLog)
|
||||
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
|
|
@ -73,10 +73,10 @@ func SprintHeaderValues(logLine LogLine) string {
|
|||
}
|
||||
|
||||
// Date, Time, band, mode, call, report sent, report rcvd, Notes
|
||||
var logLineFormat = "%-10s %-4s %-4s %-4s %-10s %-4s %-4s %s \n"
|
||||
var logLineFormat = "%-10s %-4s %-4s %-4s %-10s %-4s %-4s %s\n"
|
||||
|
||||
// SprintColumnTitles displays the column titles for a log line
|
||||
func SprintColumnTitles(logLine LogLine) string {
|
||||
func SprintColumnTitles() string {
|
||||
var output strings.Builder
|
||||
output.WriteString(fmt.Sprintf(logLineFormat, "Date", "Time", "Band", "Mode", "Call", "Sent", "Rcvd", "Notes"))
|
||||
output.WriteString(fmt.Sprintf(logLineFormat, "----", "----", "----", "----", "----", "----", "----", "----"))
|
||||
|
|
185
fleprocess/displayLog_test.go
Normal file
185
fleprocess/displayLog_test.go
Normal file
|
@ -0,0 +1,185 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSprintHeaderValues(t *testing.T) {
|
||||
type args struct {
|
||||
logLine LogLine
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
"Full Option",
|
||||
args{logLine: LogLine{MyCall: "on4kjm/p", Operator: "on4kjm", MyWWFF: "wwff", MySOTA: "sota"}},
|
||||
"MyCall on4kjm/p (on4kjm)\nMyWWFF wwff\nMySOTA sota\n",
|
||||
},
|
||||
{
|
||||
"Minimal",
|
||||
args{logLine: LogLine{MyCall: "on4kjm/p"}},
|
||||
"MyCall on4kjm/p\n",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := SprintHeaderValues(tt.args.logLine); got != tt.want {
|
||||
t.Errorf("SprintHeaderValues() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleSprintColumnTitles() {
|
||||
out := SprintColumnTitles()
|
||||
fmt.Print(out)
|
||||
//Output:
|
||||
//Date Time Band Mode Call Sent Rcvd Notes
|
||||
//---- ---- ---- ---- ---- ---- ---- ----
|
||||
}
|
||||
|
||||
func ExampleSprintLogRecord() {
|
||||
logLine := LogLine{
|
||||
Date: "date",
|
||||
MyCall: "myCall",
|
||||
Operator: "operator",
|
||||
MyWWFF: "myWwff",
|
||||
MySOTA: "mySota",
|
||||
QslMsgFromHeader: "QslMsgFromHeader",
|
||||
Nickname: "nickname",
|
||||
Mode: "mode",
|
||||
ModeType: "modeType",
|
||||
Band: "band",
|
||||
BandLowerLimit: 1.0,
|
||||
BandUpperLimit: 2.0,
|
||||
Frequency: "frequency",
|
||||
Time: "time",
|
||||
Call: "call",
|
||||
Comment: "comment",
|
||||
QSLmsg: "qslMessage",
|
||||
OMname: "omName",
|
||||
GridLoc: "gridLoc",
|
||||
RSTsent: "rstSent",
|
||||
RSTrcvd: "rstRcvd",
|
||||
SOTA: "sota",
|
||||
WWFF: "wwff",
|
||||
}
|
||||
out := SprintLogRecord(logLine)
|
||||
fmt.Print(out)
|
||||
|
||||
//output:
|
||||
//Date date
|
||||
//MyCall myCall
|
||||
//Operator operator
|
||||
//MyWWFF myWwff
|
||||
//MySOTA mySota
|
||||
//QslMsg QslMsgFromHeader
|
||||
//Nickname nickname
|
||||
//Mode mode
|
||||
//ModeType modeType
|
||||
//Band band
|
||||
// Lower 1.000000
|
||||
// Upper 2.000000
|
||||
//Frequency frequency
|
||||
//Time time
|
||||
//Call call
|
||||
//Comment comment
|
||||
//QSLmsg qslMessage
|
||||
//OMname omName
|
||||
//GridLoc gridLoc
|
||||
//RSTsent rstSent
|
||||
//RSTrcvd rstRcvd
|
||||
//SOTA sota
|
||||
//WWFF wwff
|
||||
|
||||
}
|
||||
|
||||
func TestSprintLogInColumn(t *testing.T) {
|
||||
type args struct {
|
||||
logLine LogLine
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantOutput string
|
||||
}{
|
||||
{
|
||||
"Full Option",
|
||||
args{logLine: LogLine{
|
||||
Date: "date",
|
||||
MyCall: "myCall",
|
||||
Operator: "operator",
|
||||
MyWWFF: "myWwff",
|
||||
MySOTA: "mySota",
|
||||
QslMsgFromHeader: "QslMsgFromHeader",
|
||||
Nickname: "nickname",
|
||||
Mode: "mode",
|
||||
ModeType: "modeType",
|
||||
Band: "band",
|
||||
BandLowerLimit: 1.0,
|
||||
BandUpperLimit: 2.0,
|
||||
Frequency: "frequency",
|
||||
Time: "time",
|
||||
Call: "call",
|
||||
Comment: "comment",
|
||||
QSLmsg: "qslMessage",
|
||||
OMname: "omName",
|
||||
GridLoc: "gridLoc",
|
||||
RSTsent: "rstSent",
|
||||
RSTrcvd: "rstRcvd",
|
||||
SOTA: "sota",
|
||||
WWFF: "wwff"},
|
||||
},
|
||||
"date time band mode call rstSent rstRcvd QRG: frequency [comment] [qslMessage] omName gridLoc wwff sota \n",
|
||||
},
|
||||
{
|
||||
"Minimal",
|
||||
args{logLine: LogLine{
|
||||
Date: "date",
|
||||
MyCall: "myCall",
|
||||
Operator: "operator",
|
||||
MyWWFF: "myWwff",
|
||||
MySOTA: "mySota",
|
||||
QslMsgFromHeader: "QslMsgFromHeader",
|
||||
Nickname: "nickname",
|
||||
Mode: "mode",
|
||||
ModeType: "modeType",
|
||||
Band: "band",
|
||||
BandLowerLimit: 1.0,
|
||||
BandUpperLimit: 2.0,
|
||||
Time: "time",
|
||||
Call: "call",
|
||||
RSTsent: "rstSent",
|
||||
RSTrcvd: "rstRcvd"},
|
||||
},
|
||||
"date time band mode call rstSent rstRcvd \n",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotOutput := SprintLogInColumn(tt.args.logLine); gotOutput != tt.wantOutput {
|
||||
t.Errorf("SprintLogInColumn() = %v, want %v", gotOutput, tt.wantOutput)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,5 +1,21 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -48,10 +49,10 @@ func LoadFile(inputFilename string, isInterpolateTime bool) (filleFullLog []LogL
|
|||
|
||||
file.Close()
|
||||
|
||||
regexpLineComment, _ := regexp.Compile("^#")
|
||||
regexpLineComment, _ := regexp.Compile("^[[:blank:]]*#")
|
||||
regexpOnlySpaces, _ := regexp.Compile("^\\s+$")
|
||||
regexpSingleMultiLineComment, _ := regexp.Compile("^{.+}$")
|
||||
regexpStartMultiLineComment, _ := regexp.Compile("^{")
|
||||
regexpSingleMultiLineComment, _ := regexp.Compile("^[[:blank:]]*{.+}$")
|
||||
regexpStartMultiLineComment, _ := regexp.Compile("^[[:blank:]]*{")
|
||||
regexpEndMultiLineComment, _ := regexp.Compile("}$")
|
||||
regexpHeaderMyCall, _ := regexp.Compile("(?i)^mycall ")
|
||||
regexpHeaderOperator, _ := regexp.Compile("(?i)^operator ")
|
||||
|
@ -121,8 +122,8 @@ func LoadFile(inputFilename string, isInterpolateTime bool) (filleFullLog []LogL
|
|||
if regexpHeaderMyCall.MatchString(eachline) {
|
||||
errorMsg := ""
|
||||
myCallList := regexpHeaderMyCall.Split(eachline, -1)
|
||||
if len(myCallList[1]) > 0 {
|
||||
headerMyCall, errorMsg = ValidateCall(myCallList[1])
|
||||
if len(strings.TrimSpace(myCallList[1])) > 0 {
|
||||
headerMyCall, errorMsg = ValidateCall(strings.TrimSpace(myCallList[1]))
|
||||
cleanedInput = append(cleanedInput, fmt.Sprintf("My call: %s", headerMyCall))
|
||||
if len(errorMsg) != 0 {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid myCall at line %d: %s (%s)", lineCount, myCallList[1], errorMsg))
|
||||
|
@ -136,8 +137,8 @@ func LoadFile(inputFilename string, isInterpolateTime bool) (filleFullLog []LogL
|
|||
if regexpHeaderOperator.MatchString(eachline) {
|
||||
errorMsg := ""
|
||||
myOperatorList := regexpHeaderOperator.Split(eachline, -1)
|
||||
if len(myOperatorList[1]) > 0 {
|
||||
headerOperator, errorMsg = ValidateCall(myOperatorList[1])
|
||||
if len(strings.TrimSpace(myOperatorList[1])) > 0 {
|
||||
headerOperator, errorMsg = ValidateCall(strings.TrimSpace(myOperatorList[1]))
|
||||
cleanedInput = append(cleanedInput, fmt.Sprintf("Operator: %s", headerOperator))
|
||||
if len(errorMsg) != 0 {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid Operator at line %d: %s (%s)", lineCount, myOperatorList[1], errorMsg))
|
||||
|
@ -151,8 +152,8 @@ func LoadFile(inputFilename string, isInterpolateTime bool) (filleFullLog []LogL
|
|||
if regexpHeaderMyWwff.MatchString(eachline) {
|
||||
errorMsg := ""
|
||||
myWwffList := regexpHeaderMyWwff.Split(eachline, -1)
|
||||
if len(myWwffList[1]) > 0 {
|
||||
headerMyWWFF, errorMsg = ValidateWwff(myWwffList[1])
|
||||
if len(strings.TrimSpace(myWwffList[1])) > 0 {
|
||||
headerMyWWFF, errorMsg = ValidateWwff(strings.TrimSpace(myWwffList[1]))
|
||||
cleanedInput = append(cleanedInput, fmt.Sprintf("My WWFF: %s", headerMyWWFF))
|
||||
if len(errorMsg) != 0 {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid \"My WWFF\" at line %d: %s (%s)", lineCount, myWwffList[1], errorMsg))
|
||||
|
@ -166,8 +167,8 @@ func LoadFile(inputFilename string, isInterpolateTime bool) (filleFullLog []LogL
|
|||
if regexpHeaderMySota.MatchString(eachline) {
|
||||
errorMsg := ""
|
||||
mySotaList := regexpHeaderMySota.Split(eachline, -1)
|
||||
if len(mySotaList[1]) > 0 {
|
||||
headerMySOTA, errorMsg = ValidateSota(mySotaList[1])
|
||||
if len(strings.TrimSpace(mySotaList[1])) > 0 {
|
||||
headerMySOTA, errorMsg = ValidateSota(strings.TrimSpace(mySotaList[1]))
|
||||
cleanedInput = append(cleanedInput, fmt.Sprintf("My Sota: %s", headerMySOTA))
|
||||
if len(errorMsg) != 0 {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid \"My SOTA\" at line %d: %s (%s)", lineCount, mySotaList[1], errorMsg))
|
||||
|
@ -191,8 +192,8 @@ func LoadFile(inputFilename string, isInterpolateTime bool) (filleFullLog []LogL
|
|||
//Nickname
|
||||
if regexpHeaderNickname.MatchString(eachline) {
|
||||
myNicknameList := regexpHeaderNickname.Split(eachline, -1)
|
||||
if len(myNicknameList[1]) > 0 {
|
||||
headerNickname = myNicknameList[1]
|
||||
if len(strings.TrimSpace(myNicknameList[1])) > 0 {
|
||||
headerNickname = strings.TrimSpace(myNicknameList[1])
|
||||
cleanedInput = append(cleanedInput, fmt.Sprintf("eQSL Nickmane: %s", headerNickname))
|
||||
}
|
||||
//If there is no data after the marker, we just skip the data.
|
||||
|
@ -316,10 +317,10 @@ func displayLogSimple(fullLog []LogLine) {
|
|||
for _, filledLogLine := range fullLog {
|
||||
if firstLine {
|
||||
fmt.Println(SprintHeaderValues(filledLogLine))
|
||||
fmt.Print(SprintColumnTitles(filledLogLine))
|
||||
fmt.Print(SprintColumnTitles())
|
||||
firstLine = false
|
||||
}
|
||||
fmt.Print(SprintLogInColumn(filledLogLine))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
373
fleprocess/load_file_test.go
Normal file
373
fleprocess/load_file_test.go
Normal file
|
@ -0,0 +1,373 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadFile_happyCase(t *testing.T) {
|
||||
|
||||
//Given
|
||||
dataArray := make([]string, 0)
|
||||
dataArray = append(dataArray, "{ Sample multi-line comment")
|
||||
dataArray = append(dataArray, " ( with quotes) Check: Logging > \"Contest Logging\"")
|
||||
dataArray = append(dataArray, " - Data item1")
|
||||
dataArray = append(dataArray, " - Data item2")
|
||||
dataArray = append(dataArray, " }")
|
||||
dataArray = append(dataArray, "{ one liner comment }")
|
||||
dataArray = append(dataArray, " { offset one liner comment }")
|
||||
dataArray = append(dataArray, " ")
|
||||
dataArray = append(dataArray, "# Header")
|
||||
dataArray = append(dataArray, "myCall on4kjm/p")
|
||||
dataArray = append(dataArray, "operator on4kjm")
|
||||
dataArray = append(dataArray, "nickname Portable")
|
||||
dataArray = append(dataArray, "myWwff onff-0258")
|
||||
dataArray = append(dataArray, "mySota on/on-001")
|
||||
dataArray = append(dataArray, "QslMsg This is a QSL message")
|
||||
dataArray = append(dataArray, " ")
|
||||
dataArray = append(dataArray, " #Log")
|
||||
dataArray = append(dataArray, "date 2020-05-23")
|
||||
dataArray = append(dataArray, "40m cw 0950 ik5zve/5 9 5")
|
||||
dataArray = append(dataArray, "on6zq")
|
||||
dataArray = append(dataArray, "0954 on4do")
|
||||
|
||||
temporaryDataFileName := createTestFile(dataArray)
|
||||
|
||||
//When
|
||||
loadedLogFile, isLoadedOK := LoadFile(temporaryDataFileName, true)
|
||||
|
||||
//Then
|
||||
if !isLoadedOK {
|
||||
t.Error("Test file could not be correctly processed")
|
||||
}
|
||||
if len(loadedLogFile) == 0 {
|
||||
t.Error("No data loaded")
|
||||
}
|
||||
|
||||
expectedValue := "ON4KJM/P"
|
||||
if loadedLogFile[0].MyCall != expectedValue {
|
||||
t.Errorf("Not the expected MyCall value: %s (expecting %s)", loadedLogFile[0].MyCall, expectedValue)
|
||||
}
|
||||
expectedValue = "ON4KJM"
|
||||
if loadedLogFile[0].Operator != expectedValue {
|
||||
t.Errorf("Not the expected Operator value: %s (expecting %s)", loadedLogFile[0].Operator, expectedValue)
|
||||
}
|
||||
expectedValue = "Portable"
|
||||
if loadedLogFile[0].Nickname != expectedValue {
|
||||
t.Errorf("Not the expected eQsl Nickname value: %s (expecting %s)", loadedLogFile[0].Nickname, expectedValue)
|
||||
}
|
||||
expectedValue = "ONFF-0258"
|
||||
if loadedLogFile[0].MyWWFF != expectedValue {
|
||||
t.Errorf("Not the expected MyWWFF value: %s (expecting %s)", loadedLogFile[0].MyWWFF, expectedValue)
|
||||
}
|
||||
expectedValue = "ON/ON-001"
|
||||
if loadedLogFile[0].MySOTA != expectedValue {
|
||||
t.Errorf("Not the expected MySOTA value: %s (expecting %s)", loadedLogFile[0].MySOTA, expectedValue)
|
||||
}
|
||||
expectedValue = "This is a QSL message"
|
||||
if loadedLogFile[0].QSLmsg != expectedValue {
|
||||
t.Errorf("Not the expected QSL Message from Header value: %s (expecting %s)", loadedLogFile[0].QSLmsg, expectedValue)
|
||||
}
|
||||
expectedValue = "IK5ZVE/5"
|
||||
if loadedLogFile[0].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[0] value: %s (expecting %s)", loadedLogFile[0].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0950"
|
||||
if loadedLogFile[0].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[0] value: %s (expecting %s)", loadedLogFile[0].Time, expectedValue)
|
||||
}
|
||||
expectedValue = "2020-05-23"
|
||||
if loadedLogFile[0].Date != expectedValue {
|
||||
t.Errorf("Not the expected Date[0] value: %s (expecting %s)", loadedLogFile[0].Date, expectedValue)
|
||||
}
|
||||
expectedValue = "ON6ZQ"
|
||||
if loadedLogFile[1].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[1] value: %s (expecting %s)", loadedLogFile[1].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0952"
|
||||
if loadedLogFile[1].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[1] value: %s (expecting %s)", loadedLogFile[1].Time, expectedValue)
|
||||
}
|
||||
expectedValue = "ON4DO"
|
||||
if loadedLogFile[2].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[2] value: %s (expecting %s)", loadedLogFile[2].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0954"
|
||||
if loadedLogFile[2].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[2] value: %s (expecting %s)", loadedLogFile[2].Time, expectedValue)
|
||||
}
|
||||
//Clean Up
|
||||
os.Remove(temporaryDataFileName)
|
||||
}
|
||||
|
||||
func TestLoadFile_wrongHeader(t *testing.T) {
|
||||
|
||||
//Given
|
||||
dataArray := make([]string, 0)
|
||||
dataArray = append(dataArray, "# Header")
|
||||
dataArray = append(dataArray, "myCall fooBar")
|
||||
dataArray = append(dataArray, "operator")
|
||||
dataArray = append(dataArray, "myWwff foobar")
|
||||
dataArray = append(dataArray, "mySota ")
|
||||
dataArray = append(dataArray, " ")
|
||||
dataArray = append(dataArray, " #Log")
|
||||
dataArray = append(dataArray, "date 2020-05-23")
|
||||
dataArray = append(dataArray, "40m cw 0950 ik5zve/5 9 5")
|
||||
dataArray = append(dataArray, "on6zq")
|
||||
dataArray = append(dataArray, "0954 on4do")
|
||||
|
||||
temporaryDataFileName := createTestFile(dataArray)
|
||||
|
||||
//When
|
||||
loadedLogFile, isLoadedOK := LoadFile(temporaryDataFileName, true)
|
||||
|
||||
//Then
|
||||
if isLoadedOK {
|
||||
t.Error("Test file processing should return with aerror")
|
||||
}
|
||||
if len(loadedLogFile) == 0 {
|
||||
t.Error("No data loaded")
|
||||
}
|
||||
|
||||
expectedValue := "*FOOBAR"
|
||||
if loadedLogFile[0].MyCall != expectedValue {
|
||||
t.Errorf("Not the expected MyCall value: %s (expecting %s)", loadedLogFile[0].MyCall, expectedValue)
|
||||
}
|
||||
expectedValue = ""
|
||||
if loadedLogFile[0].Operator != expectedValue {
|
||||
t.Errorf("Not the expected Operator value: %s (expecting %s)", loadedLogFile[0].Operator, expectedValue)
|
||||
}
|
||||
expectedValue = "*FOOBAR"
|
||||
if loadedLogFile[0].MyWWFF != expectedValue {
|
||||
t.Errorf("Not the expected MyWWFF value: %s (expecting %s)", loadedLogFile[0].MyWWFF, expectedValue)
|
||||
}
|
||||
expectedValue = ""
|
||||
if loadedLogFile[0].MySOTA != expectedValue {
|
||||
t.Errorf("Not the expected MySOTA value: %s (expecting %s)", loadedLogFile[0].MySOTA, expectedValue)
|
||||
}
|
||||
|
||||
expectedValue = "IK5ZVE/5"
|
||||
if loadedLogFile[0].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[0] value: %s (expecting %s)", loadedLogFile[0].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0950"
|
||||
if loadedLogFile[0].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[0] value: %s (expecting %s)", loadedLogFile[0].Time, expectedValue)
|
||||
}
|
||||
expectedValue = "2020-05-23"
|
||||
if loadedLogFile[0].Date != expectedValue {
|
||||
t.Errorf("Not the expected Date[0] value: %s (expecting %s)", loadedLogFile[0].Date, expectedValue)
|
||||
}
|
||||
expectedValue = "ON6ZQ"
|
||||
if loadedLogFile[1].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[1] value: %s (expecting %s)", loadedLogFile[1].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0952"
|
||||
if loadedLogFile[1].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[1] value: %s (expecting %s)", loadedLogFile[1].Time, expectedValue)
|
||||
}
|
||||
expectedValue = "ON4DO"
|
||||
if loadedLogFile[2].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[2] value: %s (expecting %s)", loadedLogFile[2].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0954"
|
||||
if loadedLogFile[2].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[2] value: %s (expecting %s)", loadedLogFile[2].Time, expectedValue)
|
||||
}
|
||||
//Clean Up
|
||||
os.Remove(temporaryDataFileName)
|
||||
}
|
||||
|
||||
//TODO: if the first call is wrong the infertime doesn't work
|
||||
|
||||
func TestLoadFile_wrongData(t *testing.T) {
|
||||
|
||||
//Given
|
||||
dataArray := make([]string, 0)
|
||||
dataArray = append(dataArray, "# Header")
|
||||
dataArray = append(dataArray, "myCall fooBar")
|
||||
dataArray = append(dataArray, "operator foobar")
|
||||
dataArray = append(dataArray, "myWwff foobar")
|
||||
dataArray = append(dataArray, "mySota foobar")
|
||||
dataArray = append(dataArray, " ")
|
||||
dataArray = append(dataArray, " #Log")
|
||||
dataArray = append(dataArray, "date 2020-05-23")
|
||||
dataArray = append(dataArray, "40m cw 0950 ik5zve 9 5")
|
||||
dataArray = append(dataArray, "on6zq")
|
||||
dataArray = append(dataArray, "42m 0954 on4do")
|
||||
|
||||
temporaryDataFileName := createTestFile(dataArray)
|
||||
|
||||
//When
|
||||
loadedLogFile, isLoadedOK := LoadFile(temporaryDataFileName, true)
|
||||
|
||||
//Then
|
||||
if isLoadedOK {
|
||||
t.Error("Test file processing should return with an error")
|
||||
}
|
||||
if len(loadedLogFile) == 0 {
|
||||
t.Error("No data loaded")
|
||||
}
|
||||
|
||||
expectedValue := "*FOOBAR"
|
||||
if loadedLogFile[0].MyCall != expectedValue {
|
||||
t.Errorf("Not the expected MyCall value: %s (expecting %s)", loadedLogFile[0].MyCall, expectedValue)
|
||||
}
|
||||
expectedValue = "*FOOBAR"
|
||||
if loadedLogFile[0].Operator != expectedValue {
|
||||
t.Errorf("Not the expected Operator value: %s (expecting %s)", loadedLogFile[0].Operator, expectedValue)
|
||||
}
|
||||
expectedValue = "*FOOBAR"
|
||||
if loadedLogFile[0].MyWWFF != expectedValue {
|
||||
t.Errorf("Not the expected MyWWFF value: %s (expecting %s)", loadedLogFile[0].MyWWFF, expectedValue)
|
||||
}
|
||||
expectedValue = "*FOOBAR"
|
||||
if loadedLogFile[0].MySOTA != expectedValue {
|
||||
t.Errorf("Not the expected MySOTA value: %s (expecting %s)", loadedLogFile[0].MySOTA, expectedValue)
|
||||
}
|
||||
|
||||
expectedValue = "IK5ZVE"
|
||||
if loadedLogFile[0].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[0] value: %s (expecting %s)", loadedLogFile[0].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0950"
|
||||
if loadedLogFile[0].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[0] value: %s (expecting %s)", loadedLogFile[0].Time, expectedValue)
|
||||
}
|
||||
expectedValue = "2020-05-23"
|
||||
if loadedLogFile[0].Date != expectedValue {
|
||||
t.Errorf("Not the expected Date[0] value: %s (expecting %s)", loadedLogFile[0].Date, expectedValue)
|
||||
}
|
||||
expectedValue = "ON6ZQ"
|
||||
if loadedLogFile[1].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[1] value: %s (expecting %s)", loadedLogFile[1].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0952"
|
||||
if loadedLogFile[1].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[1] value: %s (expecting %s)", loadedLogFile[1].Time, expectedValue)
|
||||
}
|
||||
expectedValue = "ON4DO"
|
||||
if loadedLogFile[2].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[2] value: %s (expecting %s)", loadedLogFile[2].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0954"
|
||||
if loadedLogFile[2].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[2] value: %s (expecting %s)", loadedLogFile[2].Time, expectedValue)
|
||||
}
|
||||
//Clean Up
|
||||
os.Remove(temporaryDataFileName)
|
||||
}
|
||||
|
||||
func TestLoadFile_firstCallWrong(t *testing.T) {
|
||||
|
||||
//Given
|
||||
dataArray := make([]string, 0)
|
||||
dataArray = append(dataArray, "# Header")
|
||||
dataArray = append(dataArray, "myCall fooBar")
|
||||
dataArray = append(dataArray, "operator foobar")
|
||||
dataArray = append(dataArray, "myWwff foobar")
|
||||
dataArray = append(dataArray, "mySota foobar")
|
||||
dataArray = append(dataArray, " ")
|
||||
dataArray = append(dataArray, " #Log")
|
||||
dataArray = append(dataArray, "date 2020-05-23")
|
||||
dataArray = append(dataArray, "40m cw 0950 on4kjm/p/qrp 9 5")
|
||||
dataArray = append(dataArray, "on6zq")
|
||||
dataArray = append(dataArray, "42m 0954 on4do")
|
||||
|
||||
temporaryDataFileName := createTestFile(dataArray)
|
||||
|
||||
//When
|
||||
loadedLogFile, isLoadedOK := LoadFile(temporaryDataFileName, true)
|
||||
|
||||
//Then
|
||||
if isLoadedOK {
|
||||
t.Error("Test file processing should return with an error")
|
||||
}
|
||||
if len(loadedLogFile) == 0 {
|
||||
t.Error("No data loaded")
|
||||
}
|
||||
|
||||
expectedValue := "*FOOBAR"
|
||||
if loadedLogFile[0].MyCall != expectedValue {
|
||||
t.Errorf("Not the expected MyCall value: %s (expecting %s)", loadedLogFile[0].MyCall, expectedValue)
|
||||
}
|
||||
expectedValue = "*FOOBAR"
|
||||
if loadedLogFile[0].Operator != expectedValue {
|
||||
t.Errorf("Not the expected Operator value: %s (expecting %s)", loadedLogFile[0].Operator, expectedValue)
|
||||
}
|
||||
expectedValue = "*FOOBAR"
|
||||
if loadedLogFile[0].MyWWFF != expectedValue {
|
||||
t.Errorf("Not the expected MyWWFF value: %s (expecting %s)", loadedLogFile[0].MyWWFF, expectedValue)
|
||||
}
|
||||
expectedValue = "*FOOBAR"
|
||||
if loadedLogFile[0].MySOTA != expectedValue {
|
||||
t.Errorf("Not the expected MySOTA value: %s (expecting %s)", loadedLogFile[0].MySOTA, expectedValue)
|
||||
}
|
||||
|
||||
expectedValue = "*ON4KJM/P/QRP"
|
||||
if loadedLogFile[0].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[0] value: %s (expecting %s)", loadedLogFile[0].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0950"
|
||||
if loadedLogFile[0].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[0] value: %s (expecting %s)", loadedLogFile[0].Time, expectedValue)
|
||||
}
|
||||
expectedValue = "2020-05-23"
|
||||
if loadedLogFile[0].Date != expectedValue {
|
||||
t.Errorf("Not the expected Date[0] value: %s (expecting %s)", loadedLogFile[0].Date, expectedValue)
|
||||
}
|
||||
expectedValue = "ON6ZQ"
|
||||
if loadedLogFile[1].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[1] value: %s (expecting %s)", loadedLogFile[1].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0952"
|
||||
if loadedLogFile[1].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[1] value: %s (expecting %s)", loadedLogFile[1].Time, expectedValue)
|
||||
}
|
||||
expectedValue = "ON4DO"
|
||||
if loadedLogFile[2].Call != expectedValue {
|
||||
t.Errorf("Not the expected Call[2] value: %s (expecting %s)", loadedLogFile[2].Call, expectedValue)
|
||||
}
|
||||
expectedValue = "0954"
|
||||
if loadedLogFile[2].Time != expectedValue {
|
||||
t.Errorf("Not the expected Time[2] value: %s (expecting %s)", loadedLogFile[2].Time, expectedValue)
|
||||
}
|
||||
//Clean Up
|
||||
os.Remove(temporaryDataFileName)
|
||||
}
|
||||
|
||||
//createTestFile creates and populates a test FLE input file.
|
||||
//Returns the created temporary filename.
|
||||
func createTestFile(dataArray []string) (tempFileName string) {
|
||||
//create random file name
|
||||
tmpfile, err := ioutil.TempFile("", "*.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Temporary file: %s", tmpfile.Name())
|
||||
|
||||
//Write the passed data to the file
|
||||
writeFile(tmpfile.Name(), dataArray)
|
||||
|
||||
//Return the temporaty filename
|
||||
return tmpfile.Name()
|
||||
}
|
|
@ -1,5 +1,21 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
@ -76,6 +92,11 @@ func TestParseLine(t *testing.T) {
|
|||
args{inputStr: "14.453 on4kjm", previousLine: LogLine{Mode: "SSB", Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35}},
|
||||
LogLine{Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35, Call: "ON4KJM", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "Frequency [14.453] is invalid for 20m band.",
|
||||
},
|
||||
{
|
||||
"Parse frequency out of limit with no band defined",
|
||||
args{inputStr: "14.453 on4kjm", previousLine: LogLine{Mode: "SSB"}},
|
||||
LogLine{Call: "ON4KJM", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "Unable to load frequency [14.453]: no band defined for that frequency.",
|
||||
},
|
||||
{
|
||||
"parse partial RST (sent) - CW",
|
||||
args{inputStr: "1230 on4kjm 5", previousLine: LogLine{Mode: "CW", ModeType: "CW"}},
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
|
53
fleprocess/write_file.go
Normal file
53
fleprocess/write_file.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package fleprocess
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// writeFile writes the in-memory data (lines) to a file
|
||||
func writeFile(outputFile string, dataArray []string) {
|
||||
|
||||
//TODO: check access rights
|
||||
f, err := os.Create(outputFile)
|
||||
checkFileError(err)
|
||||
|
||||
defer f.Close()
|
||||
|
||||
w := bufio.NewWriter(f)
|
||||
|
||||
lineCount := 0
|
||||
for _, dataLine := range dataArray {
|
||||
_, err := w.WriteString(dataLine + "\n")
|
||||
checkFileError(err)
|
||||
|
||||
w.Flush()
|
||||
checkFileError(err)
|
||||
lineCount++
|
||||
}
|
||||
fmt.Printf("\nSuccessfully wrote %d lines to file \"%s\"\n", lineCount, outputFile)
|
||||
}
|
||||
|
||||
// checkFileError handles file related errors
|
||||
func checkFileError(e error) {
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
}
|
67
fleprocess/write_file_test.go
Normal file
67
fleprocess/write_file_test.go
Normal file
|
@ -0,0 +1,67 @@
|
|||
package fleprocess
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const writeFileTestDir string = "test2_dir"
|
||||
const writeFileTestFname string = "testFile.txt"
|
||||
|
||||
func Test_writeFile(t *testing.T) {
|
||||
|
||||
dataArray := make([]string, 0)
|
||||
dataArray = append(dataArray, "foo")
|
||||
dataArray = append(dataArray, "bar")
|
||||
|
||||
writeFile(writeFileTestFname, dataArray)
|
||||
|
||||
//Open and read the file we have just created
|
||||
file, err := os.Open(writeFileTestFname)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
var readLines []string
|
||||
for scanner.Scan() {
|
||||
readLines = append(readLines, scanner.Text())
|
||||
}
|
||||
if error := scanner.Err(); error != nil {
|
||||
t.Error(error)
|
||||
}
|
||||
file.Close()
|
||||
|
||||
//Compare with what we have got
|
||||
if len(dataArray) != len(readLines) {
|
||||
t.Error("The number of lines read doesn't match the lines written")
|
||||
}
|
||||
for i, v := range readLines {
|
||||
if v != dataArray[i] {
|
||||
t.Error("Didn't read the expected data")
|
||||
}
|
||||
}
|
||||
|
||||
// //detete test file
|
||||
os.Remove(writeFileTestFname)
|
||||
|
||||
}
|
11
test/data/fle-3-error.txt
Normal file
11
test/data/fle-3-error.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
date 2020-07-19
|
||||
mycall ON6ZQ/P
|
||||
mysota ON/ON-018
|
||||
|
||||
#mode is missing
|
||||
30m
|
||||
1150
|
||||
|
||||
55 ix1ihr
|
||||
cw f8dgf
|
||||
56 ea2dt
|
7
test/data/fle-4-no-qso.txt
Normal file
7
test/data/fle-4-no-qso.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
date 2020-07-19
|
||||
mycall ON6ZQ/P
|
||||
mysota ON/ON-018
|
||||
|
||||
cw
|
||||
30m
|
||||
1150
|
Loading…
Reference in a new issue