github.com/KEINOS/go-countline@v1.1.0/cl/_alt/alt_test.go (about) 1 // ============================================================================ 2 // 3 // Alternate implementations of CountLines function 4 // 5 // ============================================================================ 6 // 7 // This file contains the alternate implementations of CountLines(). 8 // We benchmark them to see which one is the fastest. 9 // 10 // Note that all implementations MUST pass the test for specifications. 11 // See the "Spec Tests" section below. 12 // 13 //nolint:revive,stylecheck 14 package _alt 15 16 import ( 17 "bytes" 18 "io" 19 "testing" 20 21 "github.com/KEINOS/go-countline/cl/spec" 22 "github.com/pkg/errors" 23 "github.com/stretchr/testify/require" 24 ) 25 26 // ============================================================================ 27 // Tests 28 // ============================================================================ 29 // Specification tests for alternate implementations of CountLines(). 30 31 //nolint:paralleltest 32 func TestCountLines_specs(t *testing.T) { 33 for _, targetFunc := range []struct { 34 name string 35 fn func(io.Reader) (int, error) 36 }{ 37 // Add the alternate implementations here. 38 {"CountLinesAlt1", CountLinesAlt1}, 39 {"CountLinesAlt2", CountLinesAlt2}, 40 {"CountLinesAlt3", CountLinesAlt3}, 41 {"CountLinesAlt4", CountLinesAlt4}, 42 {"CountLinesAlt5", CountLinesAlt5}, 43 } { 44 t.Run(targetFunc.name, func(t *testing.T) { 45 spec.RunSpecTest(t, targetFunc.name, targetFunc.fn) 46 }) 47 48 t.Run(targetFunc.name+"_nil_input", func(t *testing.T) { 49 numLines, err := targetFunc.fn(nil) 50 51 require.Error(t, err, "should return an error on nil input") 52 require.Equal(t, 0, numLines, "returned number of lines should be 0 on error") 53 }) 54 55 t.Run(targetFunc.name+"_io_read_fail", func(t *testing.T) { 56 dummyReader := &DummyReader{msg: "forced error"} 57 58 numLines, err := targetFunc.fn(dummyReader) 59 60 require.Error(t, err, "it should return an error on io.Reader read failure") 61 require.Equal(t, 0, numLines, "returned number of lines should be 0 on error") 62 require.Contains(t, err.Error(), "forced error", "the returned error should contain the reason of the error") 63 }) 64 65 t.Run(targetFunc.name+"_zero_padded", func(t *testing.T) { 66 // Create a dummy reader with zero-padded/capped bytes 67 dummyReader := bytes.NewReader(make([]byte, 1024)) 68 69 _, err := targetFunc.fn(dummyReader) 70 71 require.NoError(t, err, "it should not return an error on zero padded/empty capped byte slice input") 72 }) 73 } 74 } 75 76 // DummyReader is a dummy io.Reader that returns an error on Read(). 77 type DummyReader struct { 78 msg string 79 } 80 81 // Read implements io.Reader interface. This method always returns an error with the msg field. 82 func (r *DummyReader) Read(p []byte) (int, error) { 83 return 0, errors.New(r.msg) 84 }