From 40f13d1673d8634ea4831eb8db20ff2757fd4db0 Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Fri, 26 Jan 2024 13:08:12 -0500 Subject: [PATCH 01/10] local tc --- schema/util_test.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/schema/util_test.go b/schema/util_test.go index b1dafae..d74140e 100644 --- a/schema/util_test.go +++ b/schema/util_test.go @@ -22,11 +22,16 @@ func performSerializationTest[T any]( ) { t.Helper() for name, tc := range testCases { + // The call to t.Parallel() means that referencing the tc + // from the outer scope won't produce the proper value, so + // we need to place it in a variable, localTC, scoped inside + // the loop body. + localTC := tc t.Run(name, func(t *testing.T) { t.Helper() - unserialized, err := typeUnderTest.UnserializeType(tc.SerializedValue) + unserialized, err := typeUnderTest.UnserializeType(localTC.SerializedValue) if err != nil { - if tc.ExpectError { + if localTC.ExpectError { return } t.Fatal(err) @@ -34,10 +39,10 @@ func performSerializationTest[T any]( if err := typeUnderTest.ValidateType(unserialized); err != nil { t.Fatal(err) } - if !compareUnserialized(unserialized, tc.ExpectUnserializedValue) { + if !compareUnserialized(unserialized, localTC.ExpectUnserializedValue) { t.Fatalf( "Unexpected unserialized value, expected: %v, got: %v", - tc.ExpectUnserializedValue, + localTC.ExpectUnserializedValue, unserialized, ) } @@ -45,11 +50,11 @@ func performSerializationTest[T any]( if err != nil { t.Fatal(err) } - if !compareSerialized(serialized, tc.ExpectedSerializedValue) { + if !compareSerialized(serialized, localTC.ExpectedSerializedValue) { t.Fatalf( "Serialized value mismatch, expected: %v (%T), got: %v (%T)", - tc.ExpectedSerializedValue, - tc.ExpectedSerializedValue, + localTC.ExpectedSerializedValue, + localTC.ExpectedSerializedValue, serialized, serialized, ) From fdb4953eaa453f6a398d828aee1ac4adaf658561 Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Fri, 26 Jan 2024 16:33:16 -0500 Subject: [PATCH 02/10] another range local variable --- schema/bool_test.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/schema/bool_test.go b/schema/bool_test.go index bca40e0..046f6de 100644 --- a/schema/bool_test.go +++ b/schema/bool_test.go @@ -152,17 +152,22 @@ var boolTestSerializationCases = map[string]struct { func TestBoolSerializationCycle(t *testing.T) { for name, tc := range boolTestSerializationCases { + // The call to t.Parallel() means that referencing the tc + // from the outer scope won't produce the proper value, so + // we need to place it in a variable, localTC, scoped inside + // the loop body. + localTC := tc t.Run(name, func(t *testing.T) { var boolType schema.Bool = schema.NewBoolSchema() - output, err := boolType.Unserialize(tc.input) + output, err := boolType.Unserialize(localTC.input) if err != nil { - if tc.expectedError { + if localTC.expectedError { return } - t.Fatalf("Failed to unserialize %v: %v", tc.input, err) + t.Fatalf("Failed to unserialize %v: %v", localTC.input, err) } - if output != tc.output { - t.Fatalf("Unexpected unserialize output for %v: %v", tc.input, output) + if output != localTC.output { + t.Fatalf("Unexpected unserialize output for %v: %v", localTC.input, output) } if err := boolType.Validate(output); err != nil { From 8509ca28ff46c0c6954f7e181d9a3e01897943df Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Fri, 26 Jan 2024 16:54:49 -0500 Subject: [PATCH 03/10] rewrite comment --- schema/bool_test.go | 7 ++++--- schema/units_test.go | 17 +++++++++++------ schema/util_test.go | 7 ++++--- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/schema/bool_test.go b/schema/bool_test.go index 046f6de..146f1d7 100644 --- a/schema/bool_test.go +++ b/schema/bool_test.go @@ -151,10 +151,11 @@ var boolTestSerializationCases = map[string]struct { } func TestBoolSerializationCycle(t *testing.T) { + t.Parallel() for name, tc := range boolTestSerializationCases { - // The call to t.Parallel() means that referencing the tc - // from the outer scope won't produce the proper value, so - // we need to place it in a variable, localTC, scoped inside + // When executed in parallel, referencing tc from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTC, scoped inside // the loop body. localTC := tc t.Run(name, func(t *testing.T) { diff --git a/schema/units_test.go b/schema/units_test.go index 51f3bd1..2d64cf5 100644 --- a/schema/units_test.go +++ b/schema/units_test.go @@ -35,17 +35,22 @@ func TestUnitsParseInt(t *testing.T) { } for testCase, testData := range testMatrix { + // When executed in parallel, referencing testData from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTestData, scoped inside + // the loop body. + localTestData := testData t.Run(testCase, func(t *testing.T) { - result, err := testData.units.ParseInt(testData.input) + result, err := localTestData.units.ParseInt(localTestData.input) if err != nil { t.Fatal(err) } - if result != testData.expected { - t.Fatalf("Result mismatch, expected: %d, got: %d", testData.expected, result) + if result != localTestData.expected { + t.Fatalf("Result mismatch, expected: %d, got: %d", localTestData.expected, result) } - formatted := testData.units.FormatShortInt(result) - if formatted != testData.input { - t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", testData.input, formatted) + formatted := localTestData.units.FormatShortInt(result) + if formatted != localTestData.input { + t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) } }) } diff --git a/schema/util_test.go b/schema/util_test.go index d74140e..06e78b7 100644 --- a/schema/util_test.go +++ b/schema/util_test.go @@ -21,10 +21,11 @@ func performSerializationTest[T any]( compareSerialized func(a any, b any) bool, ) { t.Helper() + t.Parallel() for name, tc := range testCases { - // The call to t.Parallel() means that referencing the tc - // from the outer scope won't produce the proper value, so - // we need to place it in a variable, localTC, scoped inside + // When executed in parallel, referencing tc from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTC, scoped inside // the loop body. localTC := tc t.Run(name, func(t *testing.T) { From ea13a549e41ae5054cfa788061a041bc747777af Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Mon, 29 Jan 2024 18:22:53 -0500 Subject: [PATCH 04/10] move call to parallelize test --- schema/enum_int_test.go | 1 + schema/enum_string_test.go | 1 + schema/float_test.go | 2 + schema/int_test.go | 2 + schema/pattern_test.go | 1 + schema/units_test.go | 160 ++++++++++++++++++------------------- schema/util_test.go | 1 - 7 files changed, 87 insertions(+), 81 deletions(-) diff --git a/schema/enum_int_test.go b/schema/enum_int_test.go index 5d5d2d1..6dbe00c 100644 --- a/schema/enum_int_test.go +++ b/schema/enum_int_test.go @@ -197,6 +197,7 @@ var testIntEnumSerializationDataSet = map[string]serializationTestCase[int64]{ } func TestIntEnumSerialization(t *testing.T) { + t.Parallel() performSerializationTest[int64]( t, schema.NewIntEnumSchema(map[int64]*schema.DisplayValue{ diff --git a/schema/enum_string_test.go b/schema/enum_string_test.go index dd8871d..48056c0 100644 --- a/schema/enum_string_test.go +++ b/schema/enum_string_test.go @@ -64,6 +64,7 @@ var testStringEnumSerializationDataSet = map[string]serializationTestCase[string } func TestStringEnumSerialization(t *testing.T) { + t.Parallel() performSerializationTest[string]( t, schema.NewStringEnumSchema(map[string]*schema.DisplayValue{ diff --git a/schema/float_test.go b/schema/float_test.go index 1cbf0f9..0e9b73c 100644 --- a/schema/float_test.go +++ b/schema/float_test.go @@ -197,6 +197,7 @@ var testFloatSerializationDataSet = map[string]serializationTestCase[float64]{ } func TestFloatSerialization(t *testing.T) { + t.Parallel() performSerializationTest[float64]( t, schema.NewFloatSchema( @@ -215,6 +216,7 @@ func TestFloatSerialization(t *testing.T) { } func TestFloatSerializationNoValidation(t *testing.T) { + t.Parallel() performSerializationTest[float64]( t, schema.NewFloatSchema(nil, nil, nil), diff --git a/schema/int_test.go b/schema/int_test.go index b8a9ba2..b610628 100644 --- a/schema/int_test.go +++ b/schema/int_test.go @@ -169,6 +169,7 @@ var testIntSerializationDataSet = map[string]serializationTestCase[int64]{ } func TestIntSerialization(t *testing.T) { + t.Parallel() performSerializationTest[int64]( t, schema.NewIntSchema(schema.IntPointer(5), schema.IntPointer(10), schema.UnitBytes), @@ -190,6 +191,7 @@ func TestDurationSerialization(t *testing.T) { } func TestIntSerializationNoValidation(t *testing.T) { + t.Parallel() performSerializationTest[int64]( t, schema.NewIntSchema(nil, nil, nil), diff --git a/schema/pattern_test.go b/schema/pattern_test.go index 24743b8..10fc72e 100644 --- a/schema/pattern_test.go +++ b/schema/pattern_test.go @@ -25,6 +25,7 @@ func ExamplePatternSchema() { } func TestPatternType(t *testing.T) { + t.Parallel() performSerializationTest[*regexp.Regexp]( t, schema.NewPatternSchema(), diff --git a/schema/units_test.go b/schema/units_test.go index 2d64cf5..288c9fd 100644 --- a/schema/units_test.go +++ b/schema/units_test.go @@ -1,92 +1,92 @@ package schema_test import ( - "testing" + "testing" - "go.flow.arcalot.io/pluginsdk/schema" + "go.flow.arcalot.io/pluginsdk/schema" ) func TestUnitsParseInt(t *testing.T) { - testMatrix := map[string]struct { - input string - units *schema.UnitsDefinition - expected int64 - }{ - "5m5s": { - "5m5s", - schema.UnitDurationNanoseconds, - 305000000000, - }, - "1%": { - "1%", - schema.UnitPercentage, - 1, - }, - "1kB": { - "1kB", - schema.UnitBytes, - 1024, - }, - "1char": { - "1char", - schema.UnitCharacters, - 1, - }, - } - - for testCase, testData := range testMatrix { - // When executed in parallel, referencing testData from the - // outer scope will not produce the proper value, so we need - // to bind it to a variable, localTestData, scoped inside - // the loop body. - localTestData := testData - t.Run(testCase, func(t *testing.T) { - result, err := localTestData.units.ParseInt(localTestData.input) - if err != nil { - t.Fatal(err) - } - if result != localTestData.expected { - t.Fatalf("Result mismatch, expected: %d, got: %d", localTestData.expected, result) - } - formatted := localTestData.units.FormatShortInt(result) - if formatted != localTestData.input { - t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) - } - }) - } + testMatrix := map[string]struct { + input string + units *schema.UnitsDefinition + expected int64 + }{ + "5m5s": { + "5m5s", + schema.UnitDurationNanoseconds, + 305000000000, + }, + "1%": { + "1%", + schema.UnitPercentage, + 1, + }, + "1kB": { + "1kB", + schema.UnitBytes, + 1024, + }, + "1char": { + "1char", + schema.UnitCharacters, + 1, + }, + } + + for testCase, testData := range testMatrix { + // When executed in parallel, referencing testData from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTestData, scoped inside + // the loop body. + localTestData := testData + t.Run(testCase, func(t *testing.T) { + result, err := localTestData.units.ParseInt(localTestData.input) + if err != nil { + t.Fatal(err) + } + if result != localTestData.expected { + t.Fatalf("Result mismatch, expected: %d, got: %d", localTestData.expected, result) + } + formatted := localTestData.units.FormatShortInt(result) + if formatted != localTestData.input { + t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) + } + }) + } } func TestUnitsParseFloat(t *testing.T) { - testMatrix := map[string]struct { - input string - units *schema.UnitsDefinition - expected float64 - }{ - "5m5s": { - "5m5.1s", - schema.UnitDurationSeconds, - 305.1, - }, - "1.1%": { - "1.1%", - schema.UnitPercentage, - 1.1, - }, - } + testMatrix := map[string]struct { + input string + units *schema.UnitsDefinition + expected float64 + }{ + "5m5s": { + "5m5.1s", + schema.UnitDurationSeconds, + 305.1, + }, + "1.1%": { + "1.1%", + schema.UnitPercentage, + 1.1, + }, + } - for testCase, testData := range testMatrix { - t.Run(testCase, func(t *testing.T) { - result, err := testData.units.ParseFloat(testData.input) - if err != nil { - t.Fatal(err) - } - if result != testData.expected { - t.Fatalf("Result mismatch, expected: %f, got: %f", testData.expected, result) - } - formatted := testData.units.FormatShortFloat(result) - if formatted != testData.input { - t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", testData.input, formatted) - } - }) - } + for testCase, testData := range testMatrix { + t.Run(testCase, func(t *testing.T) { + result, err := testData.units.ParseFloat(testData.input) + if err != nil { + t.Fatal(err) + } + if result != testData.expected { + t.Fatalf("Result mismatch, expected: %f, got: %f", testData.expected, result) + } + formatted := testData.units.FormatShortFloat(result) + if formatted != testData.input { + t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", testData.input, formatted) + } + }) + } } diff --git a/schema/util_test.go b/schema/util_test.go index 06e78b7..1b47292 100644 --- a/schema/util_test.go +++ b/schema/util_test.go @@ -21,7 +21,6 @@ func performSerializationTest[T any]( compareSerialized func(a any, b any) bool, ) { t.Helper() - t.Parallel() for name, tc := range testCases { // When executed in parallel, referencing tc from the // outer scope will not produce the proper value, so we need From 2213eafe7777173a451eceef4343375cca224491 Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Mon, 29 Jan 2024 18:26:22 -0500 Subject: [PATCH 05/10] gofmt --- schema/units_test.go | 160 +++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/schema/units_test.go b/schema/units_test.go index 288c9fd..2d64cf5 100644 --- a/schema/units_test.go +++ b/schema/units_test.go @@ -1,92 +1,92 @@ package schema_test import ( - "testing" + "testing" - "go.flow.arcalot.io/pluginsdk/schema" + "go.flow.arcalot.io/pluginsdk/schema" ) func TestUnitsParseInt(t *testing.T) { - testMatrix := map[string]struct { - input string - units *schema.UnitsDefinition - expected int64 - }{ - "5m5s": { - "5m5s", - schema.UnitDurationNanoseconds, - 305000000000, - }, - "1%": { - "1%", - schema.UnitPercentage, - 1, - }, - "1kB": { - "1kB", - schema.UnitBytes, - 1024, - }, - "1char": { - "1char", - schema.UnitCharacters, - 1, - }, - } - - for testCase, testData := range testMatrix { - // When executed in parallel, referencing testData from the - // outer scope will not produce the proper value, so we need - // to bind it to a variable, localTestData, scoped inside - // the loop body. - localTestData := testData - t.Run(testCase, func(t *testing.T) { - result, err := localTestData.units.ParseInt(localTestData.input) - if err != nil { - t.Fatal(err) - } - if result != localTestData.expected { - t.Fatalf("Result mismatch, expected: %d, got: %d", localTestData.expected, result) - } - formatted := localTestData.units.FormatShortInt(result) - if formatted != localTestData.input { - t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) - } - }) - } + testMatrix := map[string]struct { + input string + units *schema.UnitsDefinition + expected int64 + }{ + "5m5s": { + "5m5s", + schema.UnitDurationNanoseconds, + 305000000000, + }, + "1%": { + "1%", + schema.UnitPercentage, + 1, + }, + "1kB": { + "1kB", + schema.UnitBytes, + 1024, + }, + "1char": { + "1char", + schema.UnitCharacters, + 1, + }, + } + + for testCase, testData := range testMatrix { + // When executed in parallel, referencing testData from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTestData, scoped inside + // the loop body. + localTestData := testData + t.Run(testCase, func(t *testing.T) { + result, err := localTestData.units.ParseInt(localTestData.input) + if err != nil { + t.Fatal(err) + } + if result != localTestData.expected { + t.Fatalf("Result mismatch, expected: %d, got: %d", localTestData.expected, result) + } + formatted := localTestData.units.FormatShortInt(result) + if formatted != localTestData.input { + t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) + } + }) + } } func TestUnitsParseFloat(t *testing.T) { - testMatrix := map[string]struct { - input string - units *schema.UnitsDefinition - expected float64 - }{ - "5m5s": { - "5m5.1s", - schema.UnitDurationSeconds, - 305.1, - }, - "1.1%": { - "1.1%", - schema.UnitPercentage, - 1.1, - }, - } + testMatrix := map[string]struct { + input string + units *schema.UnitsDefinition + expected float64 + }{ + "5m5s": { + "5m5.1s", + schema.UnitDurationSeconds, + 305.1, + }, + "1.1%": { + "1.1%", + schema.UnitPercentage, + 1.1, + }, + } - for testCase, testData := range testMatrix { - t.Run(testCase, func(t *testing.T) { - result, err := testData.units.ParseFloat(testData.input) - if err != nil { - t.Fatal(err) - } - if result != testData.expected { - t.Fatalf("Result mismatch, expected: %f, got: %f", testData.expected, result) - } - formatted := testData.units.FormatShortFloat(result) - if formatted != testData.input { - t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", testData.input, formatted) - } - }) - } + for testCase, testData := range testMatrix { + t.Run(testCase, func(t *testing.T) { + result, err := testData.units.ParseFloat(testData.input) + if err != nil { + t.Fatal(err) + } + if result != testData.expected { + t.Fatalf("Result mismatch, expected: %f, got: %f", testData.expected, result) + } + formatted := testData.units.FormatShortFloat(result) + if formatted != testData.input { + t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", testData.input, formatted) + } + }) + } } From 05da0460e1d76c9b723011f7bcc437efe9b05dc7 Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Tue, 30 Jan 2024 11:39:38 -0500 Subject: [PATCH 06/10] early instantiate units regex cache --- schema/bool_test.go | 2 +- schema/enum_int_test.go | 1 - schema/enum_string_test.go | 1 - schema/float_test.go | 2 -- schema/int_test.go | 2 -- schema/pattern_test.go | 1 - schema/units.go | 4 +++- schema/units_test.go | 2 ++ schema/util_test.go | 2 ++ 9 files changed, 8 insertions(+), 9 deletions(-) diff --git a/schema/bool_test.go b/schema/bool_test.go index 146f1d7..9c37211 100644 --- a/schema/bool_test.go +++ b/schema/bool_test.go @@ -151,7 +151,6 @@ var boolTestSerializationCases = map[string]struct { } func TestBoolSerializationCycle(t *testing.T) { - t.Parallel() for name, tc := range boolTestSerializationCases { // When executed in parallel, referencing tc from the // outer scope will not produce the proper value, so we need @@ -159,6 +158,7 @@ func TestBoolSerializationCycle(t *testing.T) { // the loop body. localTC := tc t.Run(name, func(t *testing.T) { + t.Parallel() var boolType schema.Bool = schema.NewBoolSchema() output, err := boolType.Unserialize(localTC.input) if err != nil { diff --git a/schema/enum_int_test.go b/schema/enum_int_test.go index 6dbe00c..5d5d2d1 100644 --- a/schema/enum_int_test.go +++ b/schema/enum_int_test.go @@ -197,7 +197,6 @@ var testIntEnumSerializationDataSet = map[string]serializationTestCase[int64]{ } func TestIntEnumSerialization(t *testing.T) { - t.Parallel() performSerializationTest[int64]( t, schema.NewIntEnumSchema(map[int64]*schema.DisplayValue{ diff --git a/schema/enum_string_test.go b/schema/enum_string_test.go index 48056c0..dd8871d 100644 --- a/schema/enum_string_test.go +++ b/schema/enum_string_test.go @@ -64,7 +64,6 @@ var testStringEnumSerializationDataSet = map[string]serializationTestCase[string } func TestStringEnumSerialization(t *testing.T) { - t.Parallel() performSerializationTest[string]( t, schema.NewStringEnumSchema(map[string]*schema.DisplayValue{ diff --git a/schema/float_test.go b/schema/float_test.go index 0e9b73c..1cbf0f9 100644 --- a/schema/float_test.go +++ b/schema/float_test.go @@ -197,7 +197,6 @@ var testFloatSerializationDataSet = map[string]serializationTestCase[float64]{ } func TestFloatSerialization(t *testing.T) { - t.Parallel() performSerializationTest[float64]( t, schema.NewFloatSchema( @@ -216,7 +215,6 @@ func TestFloatSerialization(t *testing.T) { } func TestFloatSerializationNoValidation(t *testing.T) { - t.Parallel() performSerializationTest[float64]( t, schema.NewFloatSchema(nil, nil, nil), diff --git a/schema/int_test.go b/schema/int_test.go index b610628..b8a9ba2 100644 --- a/schema/int_test.go +++ b/schema/int_test.go @@ -169,7 +169,6 @@ var testIntSerializationDataSet = map[string]serializationTestCase[int64]{ } func TestIntSerialization(t *testing.T) { - t.Parallel() performSerializationTest[int64]( t, schema.NewIntSchema(schema.IntPointer(5), schema.IntPointer(10), schema.UnitBytes), @@ -191,7 +190,6 @@ func TestDurationSerialization(t *testing.T) { } func TestIntSerializationNoValidation(t *testing.T) { - t.Parallel() performSerializationTest[int64]( t, schema.NewIntSchema(nil, nil, nil), diff --git a/schema/pattern_test.go b/schema/pattern_test.go index 10fc72e..24743b8 100644 --- a/schema/pattern_test.go +++ b/schema/pattern_test.go @@ -25,7 +25,6 @@ func ExamplePatternSchema() { } func TestPatternType(t *testing.T) { - t.Parallel() performSerializationTest[*regexp.Regexp]( t, schema.NewPatternSchema(), diff --git a/schema/units.go b/schema/units.go index 44a11d9..d842718 100644 --- a/schema/units.go +++ b/schema/units.go @@ -129,10 +129,12 @@ type Units interface { // NewUnits defines a new set of UnitsDefinition with the given parameters. func NewUnits(baseUnit *UnitDefinition, multipliers map[int64]*UnitDefinition) *UnitsDefinition { - return &UnitsDefinition{ + ud := &UnitsDefinition{ BaseUnitValue: baseUnit, MultipliersValue: multipliers, } + //ud.updateReCache() + return ud } type UnitsDefinition struct { diff --git a/schema/units_test.go b/schema/units_test.go index 2d64cf5..18871d7 100644 --- a/schema/units_test.go +++ b/schema/units_test.go @@ -41,6 +41,7 @@ func TestUnitsParseInt(t *testing.T) { // the loop body. localTestData := testData t.Run(testCase, func(t *testing.T) { + t.Parallel() result, err := localTestData.units.ParseInt(localTestData.input) if err != nil { t.Fatal(err) @@ -76,6 +77,7 @@ func TestUnitsParseFloat(t *testing.T) { for testCase, testData := range testMatrix { t.Run(testCase, func(t *testing.T) { + t.Parallel() result, err := testData.units.ParseFloat(testData.input) if err != nil { t.Fatal(err) diff --git a/schema/util_test.go b/schema/util_test.go index 1b47292..867a17d 100644 --- a/schema/util_test.go +++ b/schema/util_test.go @@ -29,6 +29,8 @@ func performSerializationTest[T any]( localTC := tc t.Run(name, func(t *testing.T) { t.Helper() + //panic("help!") + t.Parallel() unserialized, err := typeUnderTest.UnserializeType(localTC.SerializedValue) if err != nil { if localTC.ExpectError { From 9ddcc18628e0cf9b262a9688d4672921037214a7 Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Tue, 30 Jan 2024 11:42:42 -0500 Subject: [PATCH 07/10] add call to parallel test --- schema/units.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/units.go b/schema/units.go index d842718..866e09f 100644 --- a/schema/units.go +++ b/schema/units.go @@ -133,7 +133,7 @@ func NewUnits(baseUnit *UnitDefinition, multipliers map[int64]*UnitDefinition) * BaseUnitValue: baseUnit, MultipliersValue: multipliers, } - //ud.updateReCache() + ud.updateReCache() return ud } From 4f6e9bd3bce776809e671b3f6dbe58934cb90612 Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Thu, 1 Feb 2024 18:33:41 -0500 Subject: [PATCH 08/10] remove t.Parallel() --- .github/workflows/build.yml | 10 +- schema/bool_test.go | 385 ++++++++++++++++++------------------ schema/units_test.go | 165 ++++++++-------- schema/util_test.go | 106 +++++----- 4 files changed, 336 insertions(+), 330 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b6c6db1..10f1c4e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,8 @@ on: branches: - main pull_request: +env: + go_version: 1.21.6 jobs: golangci-lint: name: golangci-lint @@ -11,6 +13,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Pin Golang version for linting + uses: actions/setup-go@v5 + with: + go-version: ${{ env.go_version }} - name: Run golangci-lint uses: golangci/golangci-lint-action@v3 with: @@ -24,7 +30,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.21.6 + go-version: ${{ env.go_version }} - name: Set up gotestfmt uses: GoTestTools/gotestfmt-action@v2 - uses: actions/cache@v4 @@ -67,7 +73,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.21.6 + go-version: ${{ env.go_version }} - uses: actions/cache@v4 with: path: | diff --git a/schema/bool_test.go b/schema/bool_test.go index 9c37211..17ede43 100644 --- a/schema/bool_test.go +++ b/schema/bool_test.go @@ -1,224 +1,223 @@ package schema_test import ( - "encoding/json" - "fmt" - "go.arcalot.io/assert" - "testing" + "encoding/json" + "fmt" + "go.arcalot.io/assert" + "testing" - "go.flow.arcalot.io/pluginsdk/schema" + "go.flow.arcalot.io/pluginsdk/schema" ) func ExampleBoolSchema() { - boolType := schema.NewBoolSchema() - - // Unserialize a bool: - unserializedValue, err := boolType.Unserialize(true) - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Validate: - if err := boolType.Validate(unserializedValue); err != nil { - panic(err) - } - - // Serialize: - serializedValue, err := boolType.Serialize(unserializedValue) - if err != nil { - panic(err) - } - fmt.Println(serializedValue) - - // Print protocol type ID - fmt.Println(boolType.TypeID()) - - // Output: true - // true - // bool + boolType := schema.NewBoolSchema() + + // Unserialize a bool: + unserializedValue, err := boolType.Unserialize(true) + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Validate: + if err := boolType.Validate(unserializedValue); err != nil { + panic(err) + } + + // Serialize: + serializedValue, err := boolType.Serialize(unserializedValue) + if err != nil { + panic(err) + } + fmt.Println(serializedValue) + + // Print protocol type ID + fmt.Println(boolType.TypeID()) + + // Output: true + // true + // bool } func ExampleBoolSchema_unserialize() { - boolType := schema.NewBoolSchema() - - // Unserialize a bool: - unserializedValue, err := boolType.Unserialize(true) - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Unserialize an int: - unserializedValue, err = boolType.Unserialize(1) - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Unserialize a string like this: - unserializedValue, err = boolType.Unserialize("true") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Or like this: - unserializedValue, err = boolType.Unserialize("yes") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Or like this: - unserializedValue, err = boolType.Unserialize("y") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Or like this: - unserializedValue, err = boolType.Unserialize("enable") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Or like this: - unserializedValue, err = boolType.Unserialize("enable") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Output: true - // true - // true - // true - // true - // true - // true + boolType := schema.NewBoolSchema() + + // Unserialize a bool: + unserializedValue, err := boolType.Unserialize(true) + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Unserialize an int: + unserializedValue, err = boolType.Unserialize(1) + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Unserialize a string like this: + unserializedValue, err = boolType.Unserialize("true") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Or like this: + unserializedValue, err = boolType.Unserialize("yes") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Or like this: + unserializedValue, err = boolType.Unserialize("y") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Or like this: + unserializedValue, err = boolType.Unserialize("enable") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Or like this: + unserializedValue, err = boolType.Unserialize("enable") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Output: true + // true + // true + // true + // true + // true + // true } func TestBoolAliasSerialization(t *testing.T) { - type T bool + type T bool - s := schema.NewBoolSchema() - serializedData, err := s.Serialize(T(true)) - assert.NoError(t, err) - assert.Equals(t, serializedData.(bool), true) + s := schema.NewBoolSchema() + serializedData, err := s.Serialize(T(true)) + assert.NoError(t, err) + assert.Equals(t, serializedData.(bool), true) } var boolTestSerializationCases = map[string]struct { - input interface{} - expectedError bool - output bool + input interface{} + expectedError bool + output bool }{ - "true": {input: "true", output: true}, - "false": {input: "false", output: false}, - "2": {input: "2", expectedError: true}, - "int-2": {input: 2, expectedError: true}, - "1": {input: "1", output: true}, - "int-1": {input: 1, output: true}, - "uint-1": {input: uint(1), output: true}, - "int64-1": {input: int64(1), output: true}, - "int32-1": {input: int32(1), output: true}, - "int16-1": {input: int16(1), output: true}, - "int8-1": {input: int8(1), output: true}, - "uint64-1": {input: uint64(1), output: true}, - "uint32-1": {input: uint32(1), output: true}, - "uint16-1": {input: uint16(1), output: true}, - "uint8-1": {input: uint8(1), output: true}, - "0": {input: "0", output: false}, - "int-0": {input: 0, output: false}, - "uint-0": {input: uint(0), output: false}, - "int64-0": {input: int64(0), output: false}, - "int32-0": {input: int32(0), output: false}, - "int16-0": {input: int16(0), output: false}, - "int8-0": {input: int8(0), output: false}, - "uint64-0": {input: uint64(0), output: false}, - "uint32-0": {input: uint32(0), output: false}, - "uint16-0": {input: uint16(0), output: false}, - "uint8-0": {input: uint8(0), output: false}, - "yes": {input: "yes", output: true}, - "no": {input: "no", output: false}, - "y": {input: "y", output: true}, - "n": {input: "n", output: false}, - "enable": {input: "enable", output: true}, - "disable": {input: "disable", output: false}, - "enabled": {input: "enabled", output: true}, - "disabled": {input: "disabled", output: false}, + "true": {input: "true", output: true}, + "false": {input: "false", output: false}, + "2": {input: "2", expectedError: true}, + "int-2": {input: 2, expectedError: true}, + "1": {input: "1", output: true}, + "int-1": {input: 1, output: true}, + "uint-1": {input: uint(1), output: true}, + "int64-1": {input: int64(1), output: true}, + "int32-1": {input: int32(1), output: true}, + "int16-1": {input: int16(1), output: true}, + "int8-1": {input: int8(1), output: true}, + "uint64-1": {input: uint64(1), output: true}, + "uint32-1": {input: uint32(1), output: true}, + "uint16-1": {input: uint16(1), output: true}, + "uint8-1": {input: uint8(1), output: true}, + "0": {input: "0", output: false}, + "int-0": {input: 0, output: false}, + "uint-0": {input: uint(0), output: false}, + "int64-0": {input: int64(0), output: false}, + "int32-0": {input: int32(0), output: false}, + "int16-0": {input: int16(0), output: false}, + "int8-0": {input: int8(0), output: false}, + "uint64-0": {input: uint64(0), output: false}, + "uint32-0": {input: uint32(0), output: false}, + "uint16-0": {input: uint16(0), output: false}, + "uint8-0": {input: uint8(0), output: false}, + "yes": {input: "yes", output: true}, + "no": {input: "no", output: false}, + "y": {input: "y", output: true}, + "n": {input: "n", output: false}, + "enable": {input: "enable", output: true}, + "disable": {input: "disable", output: false}, + "enabled": {input: "enabled", output: true}, + "disabled": {input: "disabled", output: false}, } func TestBoolSerializationCycle(t *testing.T) { - for name, tc := range boolTestSerializationCases { - // When executed in parallel, referencing tc from the - // outer scope will not produce the proper value, so we need - // to bind it to a variable, localTC, scoped inside - // the loop body. - localTC := tc - t.Run(name, func(t *testing.T) { - t.Parallel() - var boolType schema.Bool = schema.NewBoolSchema() - output, err := boolType.Unserialize(localTC.input) - if err != nil { - if localTC.expectedError { - return - } - t.Fatalf("Failed to unserialize %v: %v", localTC.input, err) - } - if output != localTC.output { - t.Fatalf("Unexpected unserialize output for %v: %v", localTC.input, output) - } - - if err := boolType.Validate(output); err != nil { - t.Fatalf("Failed to validate %v: %v", output, err) - } - - serialized, err := boolType.Serialize(output) - if err != nil { - t.Fatalf("Failed to serialize %v: %v", output, err) - } - if serialized != output { - t.Fatalf("Invalid value after serialization: %v", serialized) - } - }) - } + for name, tc := range boolTestSerializationCases { + // When executed in parallel, referencing tc from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTC, scoped inside + // the loop body. + localTC := tc + t.Run(name, func(t *testing.T) { + var boolType schema.Bool = schema.NewBoolSchema() + output, err := boolType.Unserialize(localTC.input) + if err != nil { + if localTC.expectedError { + return + } + t.Fatalf("Failed to unserialize %v: %v", localTC.input, err) + } + if output != localTC.output { + t.Fatalf("Unexpected unserialize output for %v: %v", localTC.input, output) + } + + if err := boolType.Validate(output); err != nil { + t.Fatalf("Failed to validate %v: %v", output, err) + } + + serialized, err := boolType.Serialize(output) + if err != nil { + t.Fatalf("Failed to serialize %v: %v", output, err) + } + if serialized != output { + t.Fatalf("Invalid value after serialization: %v", serialized) + } + }) + } } func TestBoolJSONMarshal(t *testing.T) { - j, err := json.Marshal(schema.NewBoolSchema()) - if err != nil { - t.Fatal(err) - } - if string(j) != "{}" { - t.Fatalf("Unexpected JSON output: %s", j) - } - boolType := schema.NewBoolSchema() - if err := json.Unmarshal(j, &boolType); err != nil { - t.Fatal(err) - } + j, err := json.Marshal(schema.NewBoolSchema()) + if err != nil { + t.Fatal(err) + } + if string(j) != "{}" { + t.Fatalf("Unexpected JSON output: %s", j) + } + boolType := schema.NewBoolSchema() + if err := json.Unmarshal(j, &boolType); err != nil { + t.Fatal(err) + } } func TestBoolSchema(t *testing.T) { - assert.Equals(t, schema.NewBoolSchema().TypeID(), schema.TypeIDBool) + assert.Equals(t, schema.NewBoolSchema().TypeID(), schema.TypeIDBool) } func TestBoolSchema_ValidateCompatibility(t *testing.T) { - s1 := schema.NewBoolSchema() - assert.NoError(t, s1.ValidateCompatibility(s1)) // Itself - assert.NoError(t, s1.ValidateCompatibility(true)) // a literal - assert.NoError(t, s1.ValidateCompatibility(false)) // a literal - assert.Error(t, s1.ValidateCompatibility(schema.NewStringSchema(nil, nil, nil))) - assert.Error(t, s1.ValidateCompatibility(schema.NewIntSchema(nil, nil, nil))) - assert.Error(t, s1.ValidateCompatibility(schema.NewListSchema(schema.NewBoolSchema(), nil, nil))) - assert.Error(t, s1.ValidateCompatibility(schema.NewFloatSchema(nil, nil, nil))) - assert.Error(t, s1.ValidateCompatibility(schema.NewDisplayValue(nil, nil, nil))) - assert.NoError(t, s1.ValidateCompatibility(0)) // 0 and 1 are interpreted as booleans - assert.NoError(t, s1.ValidateCompatibility(1)) // 0 and 1 are interpreted as booleans - assert.Error(t, s1.ValidateCompatibility(2)) - assert.Error(t, s1.ValidateCompatibility(1.5)) - assert.Error(t, s1.ValidateCompatibility("test")) - assert.Error(t, s1.ValidateCompatibility([]string{})) - assert.Error(t, s1.ValidateCompatibility(map[string]any{})) + s1 := schema.NewBoolSchema() + assert.NoError(t, s1.ValidateCompatibility(s1)) // Itself + assert.NoError(t, s1.ValidateCompatibility(true)) // a literal + assert.NoError(t, s1.ValidateCompatibility(false)) // a literal + assert.Error(t, s1.ValidateCompatibility(schema.NewStringSchema(nil, nil, nil))) + assert.Error(t, s1.ValidateCompatibility(schema.NewIntSchema(nil, nil, nil))) + assert.Error(t, s1.ValidateCompatibility(schema.NewListSchema(schema.NewBoolSchema(), nil, nil))) + assert.Error(t, s1.ValidateCompatibility(schema.NewFloatSchema(nil, nil, nil))) + assert.Error(t, s1.ValidateCompatibility(schema.NewDisplayValue(nil, nil, nil))) + assert.NoError(t, s1.ValidateCompatibility(0)) // 0 and 1 are interpreted as booleans + assert.NoError(t, s1.ValidateCompatibility(1)) // 0 and 1 are interpreted as booleans + assert.Error(t, s1.ValidateCompatibility(2)) + assert.Error(t, s1.ValidateCompatibility(1.5)) + assert.Error(t, s1.ValidateCompatibility("test")) + assert.Error(t, s1.ValidateCompatibility([]string{})) + assert.Error(t, s1.ValidateCompatibility(map[string]any{})) } diff --git a/schema/units_test.go b/schema/units_test.go index 18871d7..02eaf91 100644 --- a/schema/units_test.go +++ b/schema/units_test.go @@ -1,94 +1,97 @@ package schema_test import ( - "testing" + "testing" - "go.flow.arcalot.io/pluginsdk/schema" + "go.flow.arcalot.io/pluginsdk/schema" ) func TestUnitsParseInt(t *testing.T) { - testMatrix := map[string]struct { - input string - units *schema.UnitsDefinition - expected int64 - }{ - "5m5s": { - "5m5s", - schema.UnitDurationNanoseconds, - 305000000000, - }, - "1%": { - "1%", - schema.UnitPercentage, - 1, - }, - "1kB": { - "1kB", - schema.UnitBytes, - 1024, - }, - "1char": { - "1char", - schema.UnitCharacters, - 1, - }, - } + testMatrix := map[string]struct { + input string + units *schema.UnitsDefinition + expected int64 + }{ + "5m5s": { + "5m5s", + schema.UnitDurationNanoseconds, + 305000000000, + }, + "1%": { + "1%", + schema.UnitPercentage, + 1, + }, + "1kB": { + "1kB", + schema.UnitBytes, + 1024, + }, + "1char": { + "1char", + schema.UnitCharacters, + 1, + }, + } - for testCase, testData := range testMatrix { - // When executed in parallel, referencing testData from the - // outer scope will not produce the proper value, so we need - // to bind it to a variable, localTestData, scoped inside - // the loop body. - localTestData := testData - t.Run(testCase, func(t *testing.T) { - t.Parallel() - result, err := localTestData.units.ParseInt(localTestData.input) - if err != nil { - t.Fatal(err) - } - if result != localTestData.expected { - t.Fatalf("Result mismatch, expected: %d, got: %d", localTestData.expected, result) - } - formatted := localTestData.units.FormatShortInt(result) - if formatted != localTestData.input { - t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) - } - }) - } + for testCase, testData := range testMatrix { + // When executed in parallel, referencing testData from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTestData, scoped inside + // the loop body. + localTestData := testData + t.Run(testCase, func(t *testing.T) { + result, err := localTestData.units.ParseInt(localTestData.input) + if err != nil { + t.Fatal(err) + } + if result != localTestData.expected { + t.Fatalf("Result mismatch, expected: %d, got: %d", localTestData.expected, result) + } + formatted := localTestData.units.FormatShortInt(result) + if formatted != localTestData.input { + t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) + } + }) + } } func TestUnitsParseFloat(t *testing.T) { - testMatrix := map[string]struct { - input string - units *schema.UnitsDefinition - expected float64 - }{ - "5m5s": { - "5m5.1s", - schema.UnitDurationSeconds, - 305.1, - }, - "1.1%": { - "1.1%", - schema.UnitPercentage, - 1.1, - }, - } + testMatrix := map[string]struct { + input string + units *schema.UnitsDefinition + expected float64 + }{ + "5m5s": { + "5m5.1s", + schema.UnitDurationSeconds, + 305.1, + }, + "1.1%": { + "1.1%", + schema.UnitPercentage, + 1.1, + }, + } - for testCase, testData := range testMatrix { - t.Run(testCase, func(t *testing.T) { - t.Parallel() - result, err := testData.units.ParseFloat(testData.input) - if err != nil { - t.Fatal(err) - } - if result != testData.expected { - t.Fatalf("Result mismatch, expected: %f, got: %f", testData.expected, result) - } - formatted := testData.units.FormatShortFloat(result) - if formatted != testData.input { - t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", testData.input, formatted) - } - }) - } + for testCase, testData := range testMatrix { + // When executed in parallel, referencing testData from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTestData, scoped inside + // the loop body. + localTestData := testData + t.Run(testCase, func(t *testing.T) { + result, err := localTestData.units.ParseFloat(localTestData.input) + if err != nil { + t.Fatal(err) + } + if result != localTestData.expected { + t.Fatalf("Result mismatch, expected: %f, got: %f", localTestData.expected, result) + } + formatted := localTestData.units.FormatShortFloat(result) + if formatted != localTestData.input { + t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) + } + }) + } } diff --git a/schema/util_test.go b/schema/util_test.go index 867a17d..acff651 100644 --- a/schema/util_test.go +++ b/schema/util_test.go @@ -1,66 +1,64 @@ package schema_test import ( - "testing" + "testing" - "go.flow.arcalot.io/pluginsdk/schema" + "go.flow.arcalot.io/pluginsdk/schema" ) type serializationTestCase[T any] struct { - SerializedValue any - ExpectError bool - ExpectUnserializedValue T - ExpectedSerializedValue any + SerializedValue any + ExpectError bool + ExpectUnserializedValue T + ExpectedSerializedValue any } func performSerializationTest[T any]( - t *testing.T, - typeUnderTest schema.TypedType[T], - testCases map[string]serializationTestCase[T], - compareUnserialized func(a T, b T) bool, - compareSerialized func(a any, b any) bool, + t *testing.T, + typeUnderTest schema.TypedType[T], + testCases map[string]serializationTestCase[T], + compareUnserialized func(a T, b T) bool, + compareSerialized func(a any, b any) bool, ) { - t.Helper() - for name, tc := range testCases { - // When executed in parallel, referencing tc from the - // outer scope will not produce the proper value, so we need - // to bind it to a variable, localTC, scoped inside - // the loop body. - localTC := tc - t.Run(name, func(t *testing.T) { - t.Helper() - //panic("help!") - t.Parallel() - unserialized, err := typeUnderTest.UnserializeType(localTC.SerializedValue) - if err != nil { - if localTC.ExpectError { - return - } - t.Fatal(err) - } - if err := typeUnderTest.ValidateType(unserialized); err != nil { - t.Fatal(err) - } - if !compareUnserialized(unserialized, localTC.ExpectUnserializedValue) { - t.Fatalf( - "Unexpected unserialized value, expected: %v, got: %v", - localTC.ExpectUnserializedValue, - unserialized, - ) - } - serialized, err := typeUnderTest.SerializeType(unserialized) - if err != nil { - t.Fatal(err) - } - if !compareSerialized(serialized, localTC.ExpectedSerializedValue) { - t.Fatalf( - "Serialized value mismatch, expected: %v (%T), got: %v (%T)", - localTC.ExpectedSerializedValue, - localTC.ExpectedSerializedValue, - serialized, - serialized, - ) - } - }) - } + t.Helper() + for name, tc := range testCases { + // When executed in parallel, referencing tc from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTC, scoped inside + // the loop body. + localTC := tc + t.Run(name, func(t *testing.T) { + t.Helper() + unserialized, err := typeUnderTest.UnserializeType(localTC.SerializedValue) + if err != nil { + if localTC.ExpectError { + return + } + t.Fatal(err) + } + if err := typeUnderTest.ValidateType(unserialized); err != nil { + t.Fatal(err) + } + if !compareUnserialized(unserialized, localTC.ExpectUnserializedValue) { + t.Fatalf( + "Unexpected unserialized value, expected: %v, got: %v", + localTC.ExpectUnserializedValue, + unserialized, + ) + } + serialized, err := typeUnderTest.SerializeType(unserialized) + if err != nil { + t.Fatal(err) + } + if !compareSerialized(serialized, localTC.ExpectedSerializedValue) { + t.Fatalf( + "Serialized value mismatch, expected: %v (%T), got: %v (%T)", + localTC.ExpectedSerializedValue, + localTC.ExpectedSerializedValue, + serialized, + serialized, + ) + } + }) + } } From 2c1f6be1f9760d9a3bdcb7fb61b9171ac4880175 Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Thu, 1 Feb 2024 18:34:02 -0500 Subject: [PATCH 09/10] gomft --- schema/bool_test.go | 384 +++++++++++++++++++++---------------------- schema/units_test.go | 168 +++++++++---------- schema/util_test.go | 104 ++++++------ 3 files changed, 328 insertions(+), 328 deletions(-) diff --git a/schema/bool_test.go b/schema/bool_test.go index 17ede43..8256e77 100644 --- a/schema/bool_test.go +++ b/schema/bool_test.go @@ -1,223 +1,223 @@ package schema_test import ( - "encoding/json" - "fmt" - "go.arcalot.io/assert" - "testing" + "encoding/json" + "fmt" + "go.arcalot.io/assert" + "testing" - "go.flow.arcalot.io/pluginsdk/schema" + "go.flow.arcalot.io/pluginsdk/schema" ) func ExampleBoolSchema() { - boolType := schema.NewBoolSchema() - - // Unserialize a bool: - unserializedValue, err := boolType.Unserialize(true) - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Validate: - if err := boolType.Validate(unserializedValue); err != nil { - panic(err) - } - - // Serialize: - serializedValue, err := boolType.Serialize(unserializedValue) - if err != nil { - panic(err) - } - fmt.Println(serializedValue) - - // Print protocol type ID - fmt.Println(boolType.TypeID()) - - // Output: true - // true - // bool + boolType := schema.NewBoolSchema() + + // Unserialize a bool: + unserializedValue, err := boolType.Unserialize(true) + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Validate: + if err := boolType.Validate(unserializedValue); err != nil { + panic(err) + } + + // Serialize: + serializedValue, err := boolType.Serialize(unserializedValue) + if err != nil { + panic(err) + } + fmt.Println(serializedValue) + + // Print protocol type ID + fmt.Println(boolType.TypeID()) + + // Output: true + // true + // bool } func ExampleBoolSchema_unserialize() { - boolType := schema.NewBoolSchema() - - // Unserialize a bool: - unserializedValue, err := boolType.Unserialize(true) - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Unserialize an int: - unserializedValue, err = boolType.Unserialize(1) - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Unserialize a string like this: - unserializedValue, err = boolType.Unserialize("true") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Or like this: - unserializedValue, err = boolType.Unserialize("yes") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Or like this: - unserializedValue, err = boolType.Unserialize("y") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Or like this: - unserializedValue, err = boolType.Unserialize("enable") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Or like this: - unserializedValue, err = boolType.Unserialize("enable") - if err != nil { - panic(err) - } - fmt.Println(unserializedValue) - - // Output: true - // true - // true - // true - // true - // true - // true + boolType := schema.NewBoolSchema() + + // Unserialize a bool: + unserializedValue, err := boolType.Unserialize(true) + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Unserialize an int: + unserializedValue, err = boolType.Unserialize(1) + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Unserialize a string like this: + unserializedValue, err = boolType.Unserialize("true") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Or like this: + unserializedValue, err = boolType.Unserialize("yes") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Or like this: + unserializedValue, err = boolType.Unserialize("y") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Or like this: + unserializedValue, err = boolType.Unserialize("enable") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Or like this: + unserializedValue, err = boolType.Unserialize("enable") + if err != nil { + panic(err) + } + fmt.Println(unserializedValue) + + // Output: true + // true + // true + // true + // true + // true + // true } func TestBoolAliasSerialization(t *testing.T) { - type T bool + type T bool - s := schema.NewBoolSchema() - serializedData, err := s.Serialize(T(true)) - assert.NoError(t, err) - assert.Equals(t, serializedData.(bool), true) + s := schema.NewBoolSchema() + serializedData, err := s.Serialize(T(true)) + assert.NoError(t, err) + assert.Equals(t, serializedData.(bool), true) } var boolTestSerializationCases = map[string]struct { - input interface{} - expectedError bool - output bool + input interface{} + expectedError bool + output bool }{ - "true": {input: "true", output: true}, - "false": {input: "false", output: false}, - "2": {input: "2", expectedError: true}, - "int-2": {input: 2, expectedError: true}, - "1": {input: "1", output: true}, - "int-1": {input: 1, output: true}, - "uint-1": {input: uint(1), output: true}, - "int64-1": {input: int64(1), output: true}, - "int32-1": {input: int32(1), output: true}, - "int16-1": {input: int16(1), output: true}, - "int8-1": {input: int8(1), output: true}, - "uint64-1": {input: uint64(1), output: true}, - "uint32-1": {input: uint32(1), output: true}, - "uint16-1": {input: uint16(1), output: true}, - "uint8-1": {input: uint8(1), output: true}, - "0": {input: "0", output: false}, - "int-0": {input: 0, output: false}, - "uint-0": {input: uint(0), output: false}, - "int64-0": {input: int64(0), output: false}, - "int32-0": {input: int32(0), output: false}, - "int16-0": {input: int16(0), output: false}, - "int8-0": {input: int8(0), output: false}, - "uint64-0": {input: uint64(0), output: false}, - "uint32-0": {input: uint32(0), output: false}, - "uint16-0": {input: uint16(0), output: false}, - "uint8-0": {input: uint8(0), output: false}, - "yes": {input: "yes", output: true}, - "no": {input: "no", output: false}, - "y": {input: "y", output: true}, - "n": {input: "n", output: false}, - "enable": {input: "enable", output: true}, - "disable": {input: "disable", output: false}, - "enabled": {input: "enabled", output: true}, - "disabled": {input: "disabled", output: false}, + "true": {input: "true", output: true}, + "false": {input: "false", output: false}, + "2": {input: "2", expectedError: true}, + "int-2": {input: 2, expectedError: true}, + "1": {input: "1", output: true}, + "int-1": {input: 1, output: true}, + "uint-1": {input: uint(1), output: true}, + "int64-1": {input: int64(1), output: true}, + "int32-1": {input: int32(1), output: true}, + "int16-1": {input: int16(1), output: true}, + "int8-1": {input: int8(1), output: true}, + "uint64-1": {input: uint64(1), output: true}, + "uint32-1": {input: uint32(1), output: true}, + "uint16-1": {input: uint16(1), output: true}, + "uint8-1": {input: uint8(1), output: true}, + "0": {input: "0", output: false}, + "int-0": {input: 0, output: false}, + "uint-0": {input: uint(0), output: false}, + "int64-0": {input: int64(0), output: false}, + "int32-0": {input: int32(0), output: false}, + "int16-0": {input: int16(0), output: false}, + "int8-0": {input: int8(0), output: false}, + "uint64-0": {input: uint64(0), output: false}, + "uint32-0": {input: uint32(0), output: false}, + "uint16-0": {input: uint16(0), output: false}, + "uint8-0": {input: uint8(0), output: false}, + "yes": {input: "yes", output: true}, + "no": {input: "no", output: false}, + "y": {input: "y", output: true}, + "n": {input: "n", output: false}, + "enable": {input: "enable", output: true}, + "disable": {input: "disable", output: false}, + "enabled": {input: "enabled", output: true}, + "disabled": {input: "disabled", output: false}, } func TestBoolSerializationCycle(t *testing.T) { - for name, tc := range boolTestSerializationCases { - // When executed in parallel, referencing tc from the - // outer scope will not produce the proper value, so we need - // to bind it to a variable, localTC, scoped inside - // the loop body. - localTC := tc - t.Run(name, func(t *testing.T) { - var boolType schema.Bool = schema.NewBoolSchema() - output, err := boolType.Unserialize(localTC.input) - if err != nil { - if localTC.expectedError { - return - } - t.Fatalf("Failed to unserialize %v: %v", localTC.input, err) - } - if output != localTC.output { - t.Fatalf("Unexpected unserialize output for %v: %v", localTC.input, output) - } - - if err := boolType.Validate(output); err != nil { - t.Fatalf("Failed to validate %v: %v", output, err) - } - - serialized, err := boolType.Serialize(output) - if err != nil { - t.Fatalf("Failed to serialize %v: %v", output, err) - } - if serialized != output { - t.Fatalf("Invalid value after serialization: %v", serialized) - } - }) - } + for name, tc := range boolTestSerializationCases { + // When executed in parallel, referencing tc from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTC, scoped inside + // the loop body. + localTC := tc + t.Run(name, func(t *testing.T) { + var boolType schema.Bool = schema.NewBoolSchema() + output, err := boolType.Unserialize(localTC.input) + if err != nil { + if localTC.expectedError { + return + } + t.Fatalf("Failed to unserialize %v: %v", localTC.input, err) + } + if output != localTC.output { + t.Fatalf("Unexpected unserialize output for %v: %v", localTC.input, output) + } + + if err := boolType.Validate(output); err != nil { + t.Fatalf("Failed to validate %v: %v", output, err) + } + + serialized, err := boolType.Serialize(output) + if err != nil { + t.Fatalf("Failed to serialize %v: %v", output, err) + } + if serialized != output { + t.Fatalf("Invalid value after serialization: %v", serialized) + } + }) + } } func TestBoolJSONMarshal(t *testing.T) { - j, err := json.Marshal(schema.NewBoolSchema()) - if err != nil { - t.Fatal(err) - } - if string(j) != "{}" { - t.Fatalf("Unexpected JSON output: %s", j) - } - boolType := schema.NewBoolSchema() - if err := json.Unmarshal(j, &boolType); err != nil { - t.Fatal(err) - } + j, err := json.Marshal(schema.NewBoolSchema()) + if err != nil { + t.Fatal(err) + } + if string(j) != "{}" { + t.Fatalf("Unexpected JSON output: %s", j) + } + boolType := schema.NewBoolSchema() + if err := json.Unmarshal(j, &boolType); err != nil { + t.Fatal(err) + } } func TestBoolSchema(t *testing.T) { - assert.Equals(t, schema.NewBoolSchema().TypeID(), schema.TypeIDBool) + assert.Equals(t, schema.NewBoolSchema().TypeID(), schema.TypeIDBool) } func TestBoolSchema_ValidateCompatibility(t *testing.T) { - s1 := schema.NewBoolSchema() - assert.NoError(t, s1.ValidateCompatibility(s1)) // Itself - assert.NoError(t, s1.ValidateCompatibility(true)) // a literal - assert.NoError(t, s1.ValidateCompatibility(false)) // a literal - assert.Error(t, s1.ValidateCompatibility(schema.NewStringSchema(nil, nil, nil))) - assert.Error(t, s1.ValidateCompatibility(schema.NewIntSchema(nil, nil, nil))) - assert.Error(t, s1.ValidateCompatibility(schema.NewListSchema(schema.NewBoolSchema(), nil, nil))) - assert.Error(t, s1.ValidateCompatibility(schema.NewFloatSchema(nil, nil, nil))) - assert.Error(t, s1.ValidateCompatibility(schema.NewDisplayValue(nil, nil, nil))) - assert.NoError(t, s1.ValidateCompatibility(0)) // 0 and 1 are interpreted as booleans - assert.NoError(t, s1.ValidateCompatibility(1)) // 0 and 1 are interpreted as booleans - assert.Error(t, s1.ValidateCompatibility(2)) - assert.Error(t, s1.ValidateCompatibility(1.5)) - assert.Error(t, s1.ValidateCompatibility("test")) - assert.Error(t, s1.ValidateCompatibility([]string{})) - assert.Error(t, s1.ValidateCompatibility(map[string]any{})) + s1 := schema.NewBoolSchema() + assert.NoError(t, s1.ValidateCompatibility(s1)) // Itself + assert.NoError(t, s1.ValidateCompatibility(true)) // a literal + assert.NoError(t, s1.ValidateCompatibility(false)) // a literal + assert.Error(t, s1.ValidateCompatibility(schema.NewStringSchema(nil, nil, nil))) + assert.Error(t, s1.ValidateCompatibility(schema.NewIntSchema(nil, nil, nil))) + assert.Error(t, s1.ValidateCompatibility(schema.NewListSchema(schema.NewBoolSchema(), nil, nil))) + assert.Error(t, s1.ValidateCompatibility(schema.NewFloatSchema(nil, nil, nil))) + assert.Error(t, s1.ValidateCompatibility(schema.NewDisplayValue(nil, nil, nil))) + assert.NoError(t, s1.ValidateCompatibility(0)) // 0 and 1 are interpreted as booleans + assert.NoError(t, s1.ValidateCompatibility(1)) // 0 and 1 are interpreted as booleans + assert.Error(t, s1.ValidateCompatibility(2)) + assert.Error(t, s1.ValidateCompatibility(1.5)) + assert.Error(t, s1.ValidateCompatibility("test")) + assert.Error(t, s1.ValidateCompatibility([]string{})) + assert.Error(t, s1.ValidateCompatibility(map[string]any{})) } diff --git a/schema/units_test.go b/schema/units_test.go index 02eaf91..b05d7ab 100644 --- a/schema/units_test.go +++ b/schema/units_test.go @@ -1,97 +1,97 @@ package schema_test import ( - "testing" + "testing" - "go.flow.arcalot.io/pluginsdk/schema" + "go.flow.arcalot.io/pluginsdk/schema" ) func TestUnitsParseInt(t *testing.T) { - testMatrix := map[string]struct { - input string - units *schema.UnitsDefinition - expected int64 - }{ - "5m5s": { - "5m5s", - schema.UnitDurationNanoseconds, - 305000000000, - }, - "1%": { - "1%", - schema.UnitPercentage, - 1, - }, - "1kB": { - "1kB", - schema.UnitBytes, - 1024, - }, - "1char": { - "1char", - schema.UnitCharacters, - 1, - }, - } + testMatrix := map[string]struct { + input string + units *schema.UnitsDefinition + expected int64 + }{ + "5m5s": { + "5m5s", + schema.UnitDurationNanoseconds, + 305000000000, + }, + "1%": { + "1%", + schema.UnitPercentage, + 1, + }, + "1kB": { + "1kB", + schema.UnitBytes, + 1024, + }, + "1char": { + "1char", + schema.UnitCharacters, + 1, + }, + } - for testCase, testData := range testMatrix { - // When executed in parallel, referencing testData from the - // outer scope will not produce the proper value, so we need - // to bind it to a variable, localTestData, scoped inside - // the loop body. - localTestData := testData - t.Run(testCase, func(t *testing.T) { - result, err := localTestData.units.ParseInt(localTestData.input) - if err != nil { - t.Fatal(err) - } - if result != localTestData.expected { - t.Fatalf("Result mismatch, expected: %d, got: %d", localTestData.expected, result) - } - formatted := localTestData.units.FormatShortInt(result) - if formatted != localTestData.input { - t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) - } - }) - } + for testCase, testData := range testMatrix { + // When executed in parallel, referencing testData from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTestData, scoped inside + // the loop body. + localTestData := testData + t.Run(testCase, func(t *testing.T) { + result, err := localTestData.units.ParseInt(localTestData.input) + if err != nil { + t.Fatal(err) + } + if result != localTestData.expected { + t.Fatalf("Result mismatch, expected: %d, got: %d", localTestData.expected, result) + } + formatted := localTestData.units.FormatShortInt(result) + if formatted != localTestData.input { + t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) + } + }) + } } func TestUnitsParseFloat(t *testing.T) { - testMatrix := map[string]struct { - input string - units *schema.UnitsDefinition - expected float64 - }{ - "5m5s": { - "5m5.1s", - schema.UnitDurationSeconds, - 305.1, - }, - "1.1%": { - "1.1%", - schema.UnitPercentage, - 1.1, - }, - } + testMatrix := map[string]struct { + input string + units *schema.UnitsDefinition + expected float64 + }{ + "5m5s": { + "5m5.1s", + schema.UnitDurationSeconds, + 305.1, + }, + "1.1%": { + "1.1%", + schema.UnitPercentage, + 1.1, + }, + } - for testCase, testData := range testMatrix { - // When executed in parallel, referencing testData from the - // outer scope will not produce the proper value, so we need - // to bind it to a variable, localTestData, scoped inside - // the loop body. - localTestData := testData - t.Run(testCase, func(t *testing.T) { - result, err := localTestData.units.ParseFloat(localTestData.input) - if err != nil { - t.Fatal(err) - } - if result != localTestData.expected { - t.Fatalf("Result mismatch, expected: %f, got: %f", localTestData.expected, result) - } - formatted := localTestData.units.FormatShortFloat(result) - if formatted != localTestData.input { - t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) - } - }) - } + for testCase, testData := range testMatrix { + // When executed in parallel, referencing testData from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTestData, scoped inside + // the loop body. + localTestData := testData + t.Run(testCase, func(t *testing.T) { + result, err := localTestData.units.ParseFloat(localTestData.input) + if err != nil { + t.Fatal(err) + } + if result != localTestData.expected { + t.Fatalf("Result mismatch, expected: %f, got: %f", localTestData.expected, result) + } + formatted := localTestData.units.FormatShortFloat(result) + if formatted != localTestData.input { + t.Fatalf("Formatted result doesn't match input, expected: %s, got: %s", localTestData.input, formatted) + } + }) + } } diff --git a/schema/util_test.go b/schema/util_test.go index acff651..1b47292 100644 --- a/schema/util_test.go +++ b/schema/util_test.go @@ -1,64 +1,64 @@ package schema_test import ( - "testing" + "testing" - "go.flow.arcalot.io/pluginsdk/schema" + "go.flow.arcalot.io/pluginsdk/schema" ) type serializationTestCase[T any] struct { - SerializedValue any - ExpectError bool - ExpectUnserializedValue T - ExpectedSerializedValue any + SerializedValue any + ExpectError bool + ExpectUnserializedValue T + ExpectedSerializedValue any } func performSerializationTest[T any]( - t *testing.T, - typeUnderTest schema.TypedType[T], - testCases map[string]serializationTestCase[T], - compareUnserialized func(a T, b T) bool, - compareSerialized func(a any, b any) bool, + t *testing.T, + typeUnderTest schema.TypedType[T], + testCases map[string]serializationTestCase[T], + compareUnserialized func(a T, b T) bool, + compareSerialized func(a any, b any) bool, ) { - t.Helper() - for name, tc := range testCases { - // When executed in parallel, referencing tc from the - // outer scope will not produce the proper value, so we need - // to bind it to a variable, localTC, scoped inside - // the loop body. - localTC := tc - t.Run(name, func(t *testing.T) { - t.Helper() - unserialized, err := typeUnderTest.UnserializeType(localTC.SerializedValue) - if err != nil { - if localTC.ExpectError { - return - } - t.Fatal(err) - } - if err := typeUnderTest.ValidateType(unserialized); err != nil { - t.Fatal(err) - } - if !compareUnserialized(unserialized, localTC.ExpectUnserializedValue) { - t.Fatalf( - "Unexpected unserialized value, expected: %v, got: %v", - localTC.ExpectUnserializedValue, - unserialized, - ) - } - serialized, err := typeUnderTest.SerializeType(unserialized) - if err != nil { - t.Fatal(err) - } - if !compareSerialized(serialized, localTC.ExpectedSerializedValue) { - t.Fatalf( - "Serialized value mismatch, expected: %v (%T), got: %v (%T)", - localTC.ExpectedSerializedValue, - localTC.ExpectedSerializedValue, - serialized, - serialized, - ) - } - }) - } + t.Helper() + for name, tc := range testCases { + // When executed in parallel, referencing tc from the + // outer scope will not produce the proper value, so we need + // to bind it to a variable, localTC, scoped inside + // the loop body. + localTC := tc + t.Run(name, func(t *testing.T) { + t.Helper() + unserialized, err := typeUnderTest.UnserializeType(localTC.SerializedValue) + if err != nil { + if localTC.ExpectError { + return + } + t.Fatal(err) + } + if err := typeUnderTest.ValidateType(unserialized); err != nil { + t.Fatal(err) + } + if !compareUnserialized(unserialized, localTC.ExpectUnserializedValue) { + t.Fatalf( + "Unexpected unserialized value, expected: %v, got: %v", + localTC.ExpectUnserializedValue, + unserialized, + ) + } + serialized, err := typeUnderTest.SerializeType(unserialized) + if err != nil { + t.Fatal(err) + } + if !compareSerialized(serialized, localTC.ExpectedSerializedValue) { + t.Fatalf( + "Serialized value mismatch, expected: %v (%T), got: %v (%T)", + localTC.ExpectedSerializedValue, + localTC.ExpectedSerializedValue, + serialized, + serialized, + ) + } + }) + } } From 89f36e9a56e0b5065be0e44edd69a439c1f100c5 Mon Sep 17 00:00:00 2001 From: Matthew F Leader Date: Fri, 2 Feb 2024 13:14:14 -0500 Subject: [PATCH 10/10] remove update cache --- schema/units.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/schema/units.go b/schema/units.go index 866e09f..44a11d9 100644 --- a/schema/units.go +++ b/schema/units.go @@ -129,12 +129,10 @@ type Units interface { // NewUnits defines a new set of UnitsDefinition with the given parameters. func NewUnits(baseUnit *UnitDefinition, multipliers map[int64]*UnitDefinition) *UnitsDefinition { - ud := &UnitsDefinition{ + return &UnitsDefinition{ BaseUnitValue: baseUnit, MultipliersValue: multipliers, } - ud.updateReCache() - return ud } type UnitsDefinition struct {