From 96351d3ad71776758deafbc4b59ade3cb8fcb80f Mon Sep 17 00:00:00 2001 From: Charles Iliya Krempeaux Date: Mon, 8 Aug 2022 10:01:41 -0700 Subject: [PATCH] opt.Optional[T] --- README.md | 7 +- doc.go | 43 ---- go.mod | 3 + go.sum | 0 optional.go | 171 +++++++++++++ optional_get_test.go | 380 ++++++++++++++++++++++++++++ optional_gostring_test.go | 191 ++++++++++++++ optional_whennothing_test.go | 139 ++++++++++ optional_whensomething_test.go | 446 +++++++++++++++++++++++++++++++++ 9 files changed, 1332 insertions(+), 48 deletions(-) delete mode 100644 doc.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 optional.go create mode 100644 optional_get_test.go create mode 100644 optional_gostring_test.go create mode 100644 optional_whennothing_test.go create mode 100644 optional_whensomething_test.go diff --git a/README.md b/README.md index 33b7527..989b945 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,8 @@ # go-opt -Package **opt** provides alternatives to Go's built-in types (bool, float64, int64, string, time.Time) -that also let you express a "lack of a value"; for the Go programming language; -these are similar to "option types" or "maybe types" in some other programming languages. - -(Code for this was generated using https://github.com/reiver/gogen-optiontype ) +Package **opt** implements an **optional-type**, for the Go programming language. +In other programming languages, an **optional-type** might be know as: a **option type**, or a **maybe type**. ## Documention diff --git a/doc.go b/doc.go deleted file mode 100644 index 0a36449..0000000 --- a/doc.go +++ /dev/null @@ -1,43 +0,0 @@ -/* -Package opt has a number of sub-packages provides alternatives to Go's built-in types (bool, float64, int64, string, time.Time) -that also let you express a "lack of a value"; for the Go programming language; these are similar to "option types" or "maybe types" -in some other programming languages. - -Example: - - var s optstring.NullableType - - // ... - - switch s { - case optstring.NoneNullable(): - //@TODO - case optstring.Null(): - //@TODO - case optstring.SomeNullable("Hello world!"): - //@TODO - case optstring.SomeNullable("apple banana cherry"): - //@TODO - default: - //@TODO - } - -Example: - - var s optstring.Type - - // ... - - switch s { - case optstring.None(): - //@TODO - case optstring.Some("Hello world!"): - //@TODO - case optstring.Some("apple banana cherry"): - //@TODO - default: - //@TODO - } -*/ -package opt - diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..94f0417 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/reiver/go-opt + +go 1.18 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/optional.go b/optional.go new file mode 100644 index 0000000..e467800 --- /dev/null +++ b/optional.go @@ -0,0 +1,171 @@ +package opt + +import ( + "fmt" +) + +// Optional represents an optional value. +// +// In other programming languages this is know as: an option type, or a maybe type. +// +// For example: +// +// var op opt.Optional[string] = opt.Something("once twice thrice fource") +// +// // ... +// +// value, found := op.Get() +// if found { +// fmt.Println("value:", value) +// } else{ +// fmt.Println("nothing") +// } +// +// Also, for example: +// +// var op opt.Optional[uint8] = opt.Something[uint8](101) +// +// // ... +// +// value, found := op.Get() +// if found { +// fmt.Println("value:", value) +// } else{ +// fmt.Println("nothing") +// } +type Optional[T any] struct { + value T + something bool +} + +// Nothing returns an optional-type with nothing in it. +// +// For example, here is an optional-type that can hold a string with nothing in it: +// +// var op opt.Optional[string] = opt.Nothing[string]() +// +// Note that the default value for any optional-type is nothing. +// So the following code it equivalent to it: +// +// var op opt.Optional[string] +// +// Also, for example, here is an optional-type that can hold a uint8 with nothing in it: +// +// var op opt.Optional[uint8] = opt.Nothing[uint8]() +// +// Again, note that the default value for any optional-type is nothing. +// So the following code it equivalent to it: +// +// var op opt.Optional[uint8] +func Nothing[T any]() Optional[T] { + var nothing Optional[T] + + return nothing +} + +// Something returns a optional-type with something in it. +// +// For example, here is an optional-type with the string "once twice thrice fource" in it: +// +// var op opt.Optional[string] = opt.Something("once twice thrice fource") +// +// And, for example, here is an optional-type with the uint8 101 in it: +// +// +// var op opt.Optional[uint8] = opt.Something(uint8(101)) +func Something[T any](value T) Optional[T] { + return Optional[T]{ + something:true, + value:value, + } +} + +// Get return the value inside of the optional-type if it is holding something. +// +// Example usage: +// +// var op opt.Optional[string] +// +// // ... +// +// value, found := op.Get() +// +// if found { +// fmt.Println("VALUE:", value) +// } else { +// fmt.Println("nothing") +// } +func (receiver Optional[T]) Get() (T, bool) { + return receiver.value, receiver.something +} + +// GoString makes it that when the fmt.Fprintf(), fmt.Printf(), and fmt.Sprintf() family of functions +// renders this type with the %#v verb, that it will be easier to understand. +// +// For example: +// +// var op opt.Optional[string] = opt.Something("once twice thrice fource") +// +// // ... +// +// fmt.Printf("op = %#v", op) +// +// // Output: +// // op = opt.Something[string]("once twice thrice fource") +// +// Also, for example: +// +// var op opt.Optional[uint8] = opt.Nothing[uint8]() +// +// // ... +// +// fmt.Printf("op = %#v", op) +// +// // Output: +// // op = opt.Nothing[uint8]() +func (receiver Optional[T]) GoString() string { + if !receiver.something { + return fmt.Sprintf("opt.Nothing[%T]()", receiver.value) + } + + return fmt.Sprintf("opt.Something[%T](%#v)", receiver.value, receiver.value) +} + +// WhenNothing will call ‘fn’ when ‘receiver’ is holding nothing. +// +// It will not call ‘fn’ when ‘receier’ is hold something. +// +// For example: +// +// var op opt.Optional = opt.Nothing[string] +// +// // ... +// +// op.WhenNothing(func(){ +// //@TODO +// }) +func (receiver Optional[T]) WhenNothing(fn func()) { + if !receiver.something { + fn() + } +} + +// WhenSomething will ‘fn’ when ‘receiver’ is holding something. +// The value that ‘receiver’ is holding will be passed as a parameter to the function ‘fn’. +// +// It will not call ‘fn’ when ‘receiver’ is hold nothing. +// +// For example: +// +// var op opt.Optional = opt.Something("once twice thrice fource") +// +// // ... +// +// op.WhenSomething(func(value string){ +// //@TODO +// }) +func (receiver Optional[T]) WhenSomething(fn func(T)) { + if receiver.something { + fn(receiver.value) + } +} diff --git a/optional_get_test.go b/optional_get_test.go new file mode 100644 index 0000000..e455f69 --- /dev/null +++ b/optional_get_test.go @@ -0,0 +1,380 @@ +package opt_test + +import ( + "github.com/reiver/go-opt" + + "testing" +) + +func TestOptional_Get_string(t *testing.T) { + + tests := []struct{ + Optional opt.Optional[string] + ExpectedValue string + ExpectedSomething bool + }{ + { + Optional: opt.Nothing[string](), + ExpectedValue: "", + ExpectedSomething: false, + }, + + + + { + Optional: opt.Something(""), + ExpectedValue: "", + ExpectedSomething: true, + }, + { + Optional: opt.Something("once twice thrice fource"), + ExpectedValue: "once twice thrice fource", + ExpectedSomething: true, + }, + { + Optional: opt.Something("😈"), + ExpectedValue: "😈", + ExpectedSomething: true, + }, + { + Optional: opt.Something("۰۱۲۳۴۵۶۷۸۹"), + ExpectedValue: "۰۱۲۳۴۵۶۷۸۹", + ExpectedSomething: true, + }, + } + + for testNumber, test := range tests { + + value, something := test.Optional.Get() + + { + expected := test.ExpectedSomething + actual := something + + if expected != actual { + t.Errorf("For test #%d, the actual something-flag is not what was expected.", testNumber) + t.Logf("EXPECTED FLAG: %t", expected) + t.Logf("ACTUAL FLAG: %t", actual) + t.Logf("OPTIONAL: %#v", test.Optional) + /////////////////////// CONTINUE + continue + } + } + + { + expected := test.ExpectedValue + actual := value + + if expected != actual { + t.Errorf("For test #%d, the actual value is not what was expected.", testNumber) + t.Logf("EXPECTED VALUE: %q", expected) + t.Logf("ACTUAL VALUE: %q", actual) + t.Logf("OPTIONAL: %#v", test.Optional) + /////////////////////// CONTINUE + continue + } + } + } +} + +func TestOptional_Get_int8(t *testing.T) { + + tests := []struct{ + Optional opt.Optional[int8] + ExpectedValue int8 + ExpectedSomething bool + }{ + { + Optional: opt.Nothing[int8](), + ExpectedValue: 0, + ExpectedSomething: false, + }, + + + + { + Optional: opt.Something(int8(-127)), + ExpectedValue: int8(-127), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-126)), + ExpectedValue: int8(-126), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-125)), + ExpectedValue: int8(-125), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-124)), + ExpectedValue: int8(-124), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-123)), + ExpectedValue: int8(-123), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-122)), + ExpectedValue: int8(-122), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-121)), + ExpectedValue: int8(-121), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-120)), + ExpectedValue: int8(-120), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-9)), + ExpectedValue: int8(-9), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-8)), + ExpectedValue: int8(-8), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-7)), + ExpectedValue: int8(-7), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-6)), + ExpectedValue: int8(-6), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-5)), + ExpectedValue: int8(-5), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-4)), + ExpectedValue: int8(-4), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-3)), + ExpectedValue: int8(-3), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-2)), + ExpectedValue: int8(-2), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(-1)), + ExpectedValue: int8(-1), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(0)), + ExpectedValue: int8(0), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(1)), + ExpectedValue: int8(1), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(2)), + ExpectedValue: int8(2), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(3)), + ExpectedValue: int8(3), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(4)), + ExpectedValue: int8(4), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(5)), + ExpectedValue: int8(5), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(6)), + ExpectedValue: int8(6), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(7)), + ExpectedValue: int8(7), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(8)), + ExpectedValue: int8(8), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(9)), + ExpectedValue: int8(9), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(120)), + ExpectedValue: int8(120), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(121)), + ExpectedValue: int8(121), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(122)), + ExpectedValue: int8(122), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(123)), + ExpectedValue: int8(123), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(124)), + ExpectedValue: int8(124), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(125)), + ExpectedValue: int8(125), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(126)), + ExpectedValue: int8(126), + ExpectedSomething: true, + }, + { + Optional: opt.Something(int8(127)), + ExpectedValue: int8(127), + ExpectedSomething: true, + }, + } + + for testNumber, test := range tests { + + value, something := test.Optional.Get() + + { + expected := test.ExpectedSomething + actual := something + + if expected != actual { + t.Errorf("For test #%d, the actual something-flag is not what was expected.", testNumber) + t.Logf("EXPECTED FLAG: %t", expected) + t.Logf("ACTUAL FLAG: %t", actual) + t.Logf("OPTIONAL: %#v", test.Optional) + /////////////////////// CONTINUE + continue + } + } + + { + expected := test.ExpectedValue + actual := value + + if expected != actual { + t.Errorf("For test #%d, the actual value is not what was expected.", testNumber) + t.Logf("EXPECTED VALUE: %q", expected) + t.Logf("ACTUAL VALUE: %q", actual) + t.Logf("OPTIONAL: %#v", test.Optional) + /////////////////////// CONTINUE + continue + } + } + } +} + +func TestOptional_Get_uint8(t *testing.T) { + + tests := []struct{ + Optional opt.Optional[uint8] + ExpectedValue uint8 + ExpectedSomething bool + }{ + { + Optional: opt.Nothing[uint8](), + ExpectedValue: 0, + ExpectedSomething: false, + }, + + + + { + Optional: opt.Something(uint8(0)), + ExpectedValue: uint8(0), + ExpectedSomething: true, + }, + { + Optional: opt.Something(uint8(1)), + ExpectedValue: uint8(1), + ExpectedSomething: true, + }, + { + Optional: opt.Something(uint8(2)), + ExpectedValue: uint8(2), + ExpectedSomething: true, + }, + { + Optional: opt.Something(uint8(254)), + ExpectedValue: uint8(254), + ExpectedSomething: true, + }, + { + Optional: opt.Something(uint8(255)), + ExpectedValue: uint8(255), + ExpectedSomething: true, + }, + } + + for testNumber, test := range tests { + + value, something := test.Optional.Get() + + { + expected := test.ExpectedSomething + actual := something + + if expected != actual { + t.Errorf("For test #%d, the actual something-flag is not what was expected.", testNumber) + t.Logf("EXPECTED FLAG: %t", expected) + t.Logf("ACTUAL FLAG: %t", actual) + t.Logf("OPTIONAL: %#v", test.Optional) + /////////////////////// CONTINUE + continue + } + } + + { + expected := test.ExpectedValue + actual := value + + if expected != actual { + t.Errorf("For test #%d, the actual value is not what was expected.", testNumber) + t.Logf("EXPECTED VALUE: %q", expected) + t.Logf("ACTUAL VALUE: %q", actual) + t.Logf("OPTIONAL: %#v", test.Optional) + /////////////////////// CONTINUE + continue + } + } + } +} diff --git a/optional_gostring_test.go b/optional_gostring_test.go new file mode 100644 index 0000000..d79b866 --- /dev/null +++ b/optional_gostring_test.go @@ -0,0 +1,191 @@ +package opt_test + +import ( + "github.com/reiver/go-opt" + + "fmt" + + "testing" +) + +func TestOptional_GoString(t *testing.T) { + + tests := []struct{ + Value any + Expected string + }{ + { + Value: "", + Expected: `opt.Something[string]("")`, + }, + { + Value: "once twice thrice fource", + Expected: `opt.Something[string]("once twice thrice fource")`, + }, + { + Value: "apple banana cherry", + Expected: `opt.Something[string]("apple banana cherry")`, + }, + + + + { + Value: uint8 (0x0), + Expected: `opt.Something[uint8](0x0)`, + }, + { + Value: uint8 (0x1), + Expected: `opt.Something[uint8](0x1)`, + }, + { + Value: uint8 (0x2), + Expected: `opt.Something[uint8](0x2)`, + }, + { + Value: uint8 (0xfe), + Expected: `opt.Something[uint8](0xfe)`, + }, + { + Value: uint8 (0xff), + Expected: `opt.Something[uint8](0xff)`, + }, + + + + { + Value: uint16 (0x0), + Expected: `opt.Something[uint16](0x0)`, + }, + { + Value: uint16 (0x1), + Expected: `opt.Something[uint16](0x1)`, + }, + { + Value: uint16 (0x2), + Expected: `opt.Something[uint16](0x2)`, + }, + { + Value: uint16 (0xfe), + Expected: `opt.Something[uint16](0xfe)`, + }, + { + Value: uint16 (0xff), + Expected: `opt.Something[uint16](0xff)`, + }, + { + Value: uint16 (0x100), + Expected: `opt.Something[uint16](0x100)`, + }, + { + Value: uint16 (0x101), + Expected: `opt.Something[uint16](0x101)`, + }, + { + Value: uint16 (0x102), + Expected: `opt.Something[uint16](0x102)`, + }, + { + Value: uint16 (0xfffe), + Expected: `opt.Something[uint16](0xfffe)`, + }, + { + Value: uint16 (0xffff), + Expected: `opt.Something[uint16](0xffff)`, + }, + + + + { + Value: struct { A string; B int }{A:"joeblow",B:7}, + Expected: `opt.Something[struct { A string; B int }](struct { A string; B int }{A:"joeblow", B:7})`, + }, + } + + for testNumber, test := range tests { + + op := opt.Something(test.Value) + gostring := op.GoString() + + + { + expected := test.Expected + actual := gostring + + if expected != actual { + t.Errorf("For test #%d, the actual go-string is not what was expected.", testNumber) + t.Logf("EXPECTED: %q", expected) + t.Logf("ACTUAL: %q", actual) + t.Logf("VALUE-TYPE: %T", test.Value) + t.Logf("VALUE: %#v", test.Value) + //////////////////////// CONTINUE + continue + } + } + } +} + +func TestOptional_GoString_nothing(t *testing.T) { + + tests := []struct{ + Optional fmt.GoStringer + Expected string + }{ + { + Optional: opt.Nothing[string](), + Expected: `opt.Nothing[string]()`, + }, + + + + { + Optional: opt.Nothing[int8](), + Expected: `opt.Nothing[int8]()`, + }, + { + Optional: opt.Nothing[int16](), + Expected: `opt.Nothing[int16]()`, + }, + { + Optional: opt.Nothing[int32](), + Expected: `opt.Nothing[int32]()`, + }, + { + Optional: opt.Nothing[int64](), + Expected: `opt.Nothing[int64]()`, + }, + + + + { + Optional: opt.Nothing[uint8](), + Expected: `opt.Nothing[uint8]()`, + }, + { + Optional: opt.Nothing[uint16](), + Expected: `opt.Nothing[uint16]()`, + }, + { + Optional: opt.Nothing[uint32](), + Expected: `opt.Nothing[uint32]()`, + }, + { + Optional: opt.Nothing[uint64](), + Expected: `opt.Nothing[uint64]()`, + }, + } + + for testNumber, test := range tests { + + expected := test.Expected + actual := test.Optional.GoString() + + if expected != actual { + t.Errorf("For test #%d, the actual go-string value is not what was expected.", testNumber) + t.Logf("EXPECTED GO-STRING: %q", expected) + t.Logf("ACTUAL GO-STRING: %q", actual) + t.Logf("TYPE: %T", test.Optional) + /////////////// CONTINUE + continue + } + } +} diff --git a/optional_whennothing_test.go b/optional_whennothing_test.go new file mode 100644 index 0000000..48f37ad --- /dev/null +++ b/optional_whennothing_test.go @@ -0,0 +1,139 @@ +package opt_test + +import ( + "github.com/reiver/go-opt" + + "testing" +) + +func TestOptional_WhenNothing(t *testing.T) { + + + tests := []struct{ + Optional interface{WhenNothing(func())} + }{ + { + Optional: opt.Nothing[string](), + }, + + + + { + Optional: opt.Nothing[int](), + }, + { + Optional: opt.Nothing[int8](), + }, + { + Optional: opt.Nothing[int16](), + }, + { + Optional: opt.Nothing[int32](), + }, + { + Optional: opt.Nothing[int64](), + }, + + + + { + Optional: opt.Nothing[uint](), + }, + { + Optional: opt.Nothing[uint8](), + }, + { + Optional: opt.Nothing[uint16](), + }, + { + Optional: opt.Nothing[uint32](), + }, + { + Optional: opt.Nothing[uint64](), + }, + } + + for testNumber, test := range tests { + + var worked bool = false + + test.Optional.WhenNothing(func(){ + + worked = true + }) + + if !worked { + t.Errorf("For test #%d, the call to the method did not seem work.", testNumber) + t.Logf("WORKED: %t", worked) + t.Logf("OPTIONAL: (%T) %#v", test.Optional, test.Optional) + //////////////// CONTINUE + continue + } + } +} + +func TestOptional_WhenNothing_something(t *testing.T) { + + + tests := []struct{ + Optional interface{WhenNothing(func())} + }{ + { + Optional: opt.Something[string]("once twice thrice fource"), + }, + + + + { + Optional: opt.Something[int](-1), + }, + { + Optional: opt.Something[int8](-101), + }, + { + Optional: opt.Something[int16](-10101), + }, + { + Optional: opt.Something[int32](-1010101), + }, + { + Optional: opt.Something[int64](-101010101), + }, + + + + { + Optional: opt.Something[uint](1), + }, + { + Optional: opt.Something[uint8](101), + }, + { + Optional: opt.Something[uint16](10101), + }, + { + Optional: opt.Something[uint32](1010101), + }, + { + Optional: opt.Something[uint64](101010101), + }, + } + + for testNumber, test := range tests { + + var worked bool = false + + test.Optional.WhenNothing(func(){ + + worked = true + }) + + if worked { + t.Errorf("For test #%d, the call to the method worked, but it should not have.", testNumber) + t.Logf("WORKED: %t", worked) + t.Logf("OPTIONAL: (%T) %#v", test.Optional, test.Optional) + //////////////// CONTINUE + continue + } + } +} diff --git a/optional_whensomething_test.go b/optional_whensomething_test.go new file mode 100644 index 0000000..d04c760 --- /dev/null +++ b/optional_whensomething_test.go @@ -0,0 +1,446 @@ +package opt_test + +import ( + "github.com/reiver/go-opt" + + "testing" +) + +func TestOptional_WhenSomething_string(t *testing.T) { + + + tests := []struct{ + Optional interface{WhenSomething(func(string))} + Expected string + }{ + { + Optional: opt.Something[string](""), + Expected: "", + }, + { + Optional: opt.Something[string]("once twice thrice fource"), + Expected: "once twice thrice fource", + }, + { + Optional: opt.Something[string]("apple banana cherry"), + Expected: "apple banana cherry", + }, + { + Optional: opt.Something[string]("😈"), + Expected: "😈", + }, + { + Optional: opt.Something[string]("۰۱۲۳۴۵۶۷۸۹"), + Expected: "۰۱۲۳۴۵۶۷۸۹", + }, + } + + for testNumber, test := range tests { + + var worked bool = false + var value string = "-<([-RaNdOmNeSs])>-" + + test.Optional.WhenSomething(func(v string){ + + worked = true + value = v + }) + + if !worked { + t.Errorf("For test #%d, the call to the method did not seem work.", testNumber) + t.Logf("WORKED: %t", worked) + t.Logf("OPTIONAL: (%T) %#v", test.Optional, test.Optional) + /////////////// CONTINUE + continue + } + + { + expected := test.Expected + actual := value + + if expected != actual { + t.Errorf("For test #%d, the actual value is not what was expected", testNumber) + t.Logf("EXPECTED: %q", expected) + t.Logf("EXPECTED: %q", actual) + t.Logf("WORKED: %t", worked) + /////////////////////// CONTINUE + continue + } + } + } +} + +func TestOptional_WhenSomething_stringNothing(t *testing.T) { + + var worked bool = false + + opt.Nothing[string]().WhenSomething(func(v string){ + + worked = true + }) + + if worked { + t.Errorf("The call to the method worked, but it should not have.") + t.Logf("WORKED: %t", worked) +//////////////// RETURN + return + } +} + +func TestOptional_WhenSomething_int8(t *testing.T) { + + + tests := []struct{ + Optional interface{WhenSomething(func(int8))} + Expected int8 + }{ + { + Optional: opt.Something[int8](-127), + Expected: -127, + }, + { + Optional: opt.Something[int8](-126), + Expected: -126, + }, + { + Optional: opt.Something[int8](-125), + Expected: -125, + }, + { + Optional: opt.Something[int8](-124), + Expected: -124, + }, + { + Optional: opt.Something[int8](-123), + Expected: -123, + }, + { + Optional: opt.Something[int8](-122), + Expected: -122, + }, + { + Optional: opt.Something[int8](-121), + Expected: -121, + }, + { + Optional: opt.Something[int8](-120), + Expected: -120, + }, + { + Optional: opt.Something[int8](-9), + Expected: -9, + }, + { + Optional: opt.Something[int8](-8), + Expected: -8, + }, + { + Optional: opt.Something[int8](-7), + Expected: -7, + }, + { + Optional: opt.Something[int8](-6), + Expected: -6, + }, + { + Optional: opt.Something[int8](-5), + Expected: -5, + }, + { + Optional: opt.Something[int8](-4), + Expected: -4, + }, + { + Optional: opt.Something[int8](-3), + Expected: -3, + }, + { + Optional: opt.Something[int8](-2), + Expected: -2, + }, + { + Optional: opt.Something[int8](-1), + Expected: -1, + }, + { + Optional: opt.Something[int8](0), + Expected: 0, + }, + { + Optional: opt.Something[int8](1), + Expected: 1, + }, + { + Optional: opt.Something[int8](2), + Expected: 2, + }, + { + Optional: opt.Something[int8](3), + Expected: 3, + }, + { + Optional: opt.Something[int8](4), + Expected: 4, + }, + { + Optional: opt.Something[int8](5), + Expected: 5, + }, + { + Optional: opt.Something[int8](6), + Expected: 6, + }, + { + Optional: opt.Something[int8](7), + Expected: 7, + }, + { + Optional: opt.Something[int8](8), + Expected: 8, + }, + { + Optional: opt.Something[int8](9), + Expected: 9, + }, + { + Optional: opt.Something[int8](120), + Expected: 120, + }, + { + Optional: opt.Something[int8](121), + Expected: 121, + }, + { + Optional: opt.Something[int8](122), + Expected: 122, + }, + { + Optional: opt.Something[int8](123), + Expected: 123, + }, + { + Optional: opt.Something[int8](124), + Expected: 124, + }, + { + Optional: opt.Something[int8](125), + Expected: 125, + }, + { + Optional: opt.Something[int8](126), + Expected: 126, + }, + { + Optional: opt.Something[int8](127), + Expected: 127, + }, + } + + for testNumber, test := range tests { + + var worked bool = false + var value int8 = -101 + + test.Optional.WhenSomething(func(v int8){ + + worked = true + value = v + }) + + if !worked { + t.Errorf("For test #%d, the call to the method did not seem work.", testNumber) + t.Logf("WORKED: %t", worked) + t.Logf("OPTIONAL: (%T) %#v", test.Optional, test.Optional) + //////////////// CONTINUE + continue + } + + { + expected := test.Expected + actual := value + + if expected != actual { + t.Errorf("For test #%d, the actual value is not what was expected", testNumber) + t.Logf("EXPECTED: %d", expected) + t.Logf("EXPECTED: %d", actual) + t.Logf("WORKED: %t", worked) + /////////////////////// CONTINUE + continue + } + } + } +} + +func TestOptional_WhenSomething_int8Nothing(t *testing.T) { + + var worked bool = false + + opt.Nothing[int8]().WhenSomething(func(v int8){ + + worked = true + }) + + if worked { + t.Errorf("The call to the method worked, but it should not have.") + t.Logf("WORKED: %t", worked) +//////////////// RETURN + return + } +} + +func TestOptional_WhenSomething_uint8(t *testing.T) { + + + tests := []struct{ + Optional interface{WhenSomething(func(uint8))} + Expected uint8 + }{ + { + Optional: opt.Something[uint8](0), + Expected: 0, + }, + { + Optional: opt.Something[uint8](1), + Expected: 1, + }, + { + Optional: opt.Something[uint8](2), + Expected: 2, + }, + { + Optional: opt.Something[uint8](3), + Expected: 3, + }, + { + Optional: opt.Something[uint8](4), + Expected: 4, + }, + { + Optional: opt.Something[uint8](5), + Expected: 5, + }, + { + Optional: opt.Something[uint8](6), + Expected: 6, + }, + { + Optional: opt.Something[uint8](7), + Expected: 7, + }, + { + Optional: opt.Something[uint8](8), + Expected: 8, + }, + { + Optional: opt.Something[uint8](9), + Expected: 9, + }, + { + Optional: opt.Something[uint8](120), + Expected: 120, + }, + { + Optional: opt.Something[uint8](121), + Expected: 121, + }, + { + Optional: opt.Something[uint8](122), + Expected: 122, + }, + { + Optional: opt.Something[uint8](123), + Expected: 123, + }, + { + Optional: opt.Something[uint8](124), + Expected: 124, + }, + { + Optional: opt.Something[uint8](125), + Expected: 125, + }, + { + Optional: opt.Something[uint8](126), + Expected: 126, + }, + { + Optional: opt.Something[uint8](127), + Expected: 127, + }, + { + Optional: opt.Something[uint8](250), + Expected: 250, + }, + { + Optional: opt.Something[uint8](251), + Expected: 251, + }, + { + Optional: opt.Something[uint8](252), + Expected: 252, + }, + { + Optional: opt.Something[uint8](253), + Expected: 253, + }, + { + Optional: opt.Something[uint8](254), + Expected: 254, + }, + { + Optional: opt.Something[uint8](255), + Expected: 255, + }, + } + + for testNumber, test := range tests { + + var worked bool = false + var value uint8 = 101 + + test.Optional.WhenSomething(func(v uint8){ + + worked = true + value = v + }) + + if !worked { + t.Errorf("For test #%d, the call to the method did not seem work.", testNumber) + t.Logf("WORKED: %t", worked) + t.Logf("OPTIONAL: (%T) %#v", test.Optional, test.Optional) + //////////////// CONTINUE + continue + } + + { + expected := test.Expected + actual := value + + if expected != actual { + t.Errorf("For test #%d, the actual value is not what was expected", testNumber) + t.Logf("EXPECTED: %d", expected) + t.Logf("EXPECTED: %d", actual) + t.Logf("WORKED: %t", worked) + /////////////////////// CONTINUE + continue + } + } + } +} + +func TestOptional_WhenSomething_uint8Nothing(t *testing.T) { + + var worked bool = false + + opt.Nothing[uint8]().WhenSomething(func(v uint8){ + + worked = true + }) + + if worked { + t.Errorf("The call to the method worked, but it should not have.") + t.Logf("WORKED: %t", worked) +//////////////// RETURN + return + } +}