mirror of https://github.com/on4kjm/FLEcli.git
parent
0b9fb5bc78
commit
3eeda8fd79
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
||||
}
|
@ -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
|
@ -0,0 +1,7 @@
|
||||
date 2020-07-19
|
||||
mycall ON6ZQ/P
|
||||
mysota ON/ON-018
|
||||
|
||||
cw
|
||||
30m
|
||||
1150
|
Loading…
Reference in new issue