diff --git a/CHANGES.md b/CHANGES.md index d9fa3d9..28db9b5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # **ANGoLS** Changes +## 0.9.1 - 7th February 2026 + +* fixed `EqualSliceOfInteger[]()` return type; +* added unit-tests for equal and select; + + ## 0.9.0 - 3rd January 2026 * 0.9.0 diff --git a/NEWS.md b/NEWS.md index e69de29..0c4fbf1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -0,0 +1,16 @@ +# ANGoLS - NEWS + + +| Date | News Item | +| ------------------- | ------------------------------------------------------------------------------- | +| 3rd January 2026 | Release of [**ANGoLS** 0.9.0](https://github.com/synesissoftware/ANGoLS/releases/tag/0.9.0) | +| 15th September 2025 | Release of [**ANGoLS** 0.8.0-alpha1](https://github.com/synesissoftware/ANGoLS/releases/tag/0.8.0-alpha1) | +| 27th August 2025 | Release of [**ANGoLS** 0.7.0](https://github.com/synesissoftware/ANGoLS/releases/tag/0.7.0) | +| 20th August 2025 | Release of [**ANGoLS** 0.6.0](https://github.com/synesissoftware/ANGoLS/releases/tag/0.6.0) | +| 30th March 2019 | Release of [**ANGoLS** 0.5.0](https://github.com/synesissoftware/ANGoLS/releases/tag/0.5.0) | +| 11th March 2019 | Release of [**ANGoLS** 0.4.0](https://github.com/synesissoftware/ANGoLS/releases/tag/0.4.0) | +| 1st March 2019 | initial commit | + + + + diff --git a/README.md b/README.md index 947116e..b738319 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,15 @@ - [Installation](#installation) - [Components](#components) - [Slices](#slices) + - [`Collect` Functions](#collect-functions) + - [`EqualSlice` Functions](#equalslice-functions) + - [`GenerateSlice` Functions](#generateslice-functions) + - [`SelectSlice` Functions](#selectslice-functions) - [Strings](#strings) + - [Conversion Functions](#conversion-functions) + - [`Index` Functions](#index-functions) + - [`Split` Functions](#split-functions) + - [`Chomp` Functions](#chomp-functions) - [Examples](#examples) - [Project Information](#project-information) - [Where to get help](#where-to-get-help) @@ -81,54 +89,89 @@ import ( ### Slices +#### `Collect` Functions + +Modelled after **Ruby**'s `Enumerable#collect()`, these functions provide for transforming a slice of a given type with given values into a same-sized slice of a given type with transformed values. + ```Go // in "github.com/synesissoftware/ANGoLS/slices" -func CollectSlice(input_slice any, fn func(input_item any) (any, error)) (any, error) +// This function maps an input slice of arbitrary type to an output slice of +// type []any. +func CollectSlice(input_slice any, fn func(input_item any) (any, error)) ([]any, error) +// This function maps an input slice of []int to an output slice of []int. func CollectSliceOfInt(input_slice []int, fn func(input_item int) int) (result_slice []int) +// This function maps an input slice of []N to an output slice of []N, where +// N is any integer type. func CollectSliceOfInteger[N int8 | int16 | int32 | int64 | int | uint8 | uint16 | uint32 | uint64 | uint | uintptr](input_slice []N, fn func(input_item N) N) (result_slice []N) +// This function maps an input slice of []float64 to an output slice of +// []float64. func CollectSliceOfFloat64(input_slice []float64, fn func(input_item float64) float64) (result_slice []float64) +// This function maps an input slice of []string to an output slice of +// []string. func CollectSliceOfString(input_slice []string, fn func(input_item string) string) (result_slice []string) +// This function maps an input slice of []T to an output slice of []string. func CollectSliceIntoStringSlice[T any](input_slice []T, fn func(input_item *T) (string, error)) ([]string, error) ``` +#### `EqualSlice` Functions + +Functions for evaluating equality between slices, in terms of both length and contents (values and ordering). + ```Go // in "github.com/synesissoftware/ANGoLS/slices" +// Indicates whether two []int slices have the same size, contents, and +// order. func EqualSliceOfInt(lhs, rhs []int) bool +// Indicates whether two []uint slices have the same size, contents, and +// order. func EqualSliceOfUInt(lhs, rhs []uint) bool func EqualSliceOfInteger[N int8 | int16 | int32 | int64 | int | uint8 | uint16 | uint32 | uint64 | uint | uintptr](lhs, rhs []int) bool +// Indicates whether two []float64 slices have the same size, contents, and +// order. func EqualSliceOfFloat64(lhs, rhs []float64) bool +// Indicates whether two []string slices have the same size, contents, and +// order. func EqualSliceOfString(lhs, rhs []string) bool func EqualSlice(lhs, rhs any) bool ``` +#### `GenerateSlice` Functions + +Functions for generating slices of a given size and type from a generator function. + ```Go // in "github.com/synesissoftware/ANGoLS/slices" -// GenerateSliceOfInt() creates a slice of a given size and populates its -// values with the given generator (which may be nil) +// Creates a slice of a given size and populates its values with the given +// generator (which may be nil). func GenerateSliceOfInt(size int, generator func(index int) (result int, err error)) (result []int, err error) -// GenerateSliceOfUInt() creates a slice of a given size and populates its -// values with the given generator (which may be nil) +// Creates a slice of a given size and populates its values with the given +// generator (which may be nil). func GenerateSliceOfUInt(size int, generator func(index int) (result uint, err error)) (result []uint, err error) -// GenerateSliceOfString() creates a slice of a given size and populates its -// values with the given generator (which may be nil) +// Creates a slice of a given size and populates its values with the given +// generator (which may be nil). func GenerateSliceOfString(size int, generator func(index int) (result string, err error)) (result []string, err error) ``` +#### `SelectSlice` Functions + +Modelled after **Ruby**'s `Enumerable#select()`, these functions provide for selecting elements of a given slice of a given type into a new slice of the given type. + + ```Go // in "github.com/synesissoftware/ANGoLS/slices" @@ -144,6 +187,8 @@ func SelectSliceOfString(input_slice []string, selector func(index int, input_it ### Strings +#### Conversion Functions + ```Go // in "github.com/synesissoftware/ANGoLS/strings" @@ -164,7 +209,11 @@ func ASCIIToLower(s string) string // are known to contain only ASCII and a faster conversion than is provided // by the standard `ToUpper()` is desired. func ASCIIToUpper(s string) string +``` +#### `Index` Functions + +```Go // Finds the index of the given substring in the given string, starting from // the position after the given index. -1 is returned if the find is not // successful. @@ -231,11 +280,13 @@ func IndexFuncAfter(s string, f func(rune) bool, ix int) int func IndexNotAnyAfter(s string, chars string, ix int) int ``` +#### `Split` Functions + ```Go // in "github.com/synesissoftware/ANGoLS/strings" -// SplitAfterByte slices a string into all substings after each instance of -// the byte sep and returns a slice of those substrings. +// Slices a string into all substings after each instance of the byte sep +// and returns a slice of those substrings. // // If s does not contain sep, SplitAfterByte returns a slice of length 1 // whose only element is s. @@ -243,8 +294,8 @@ func IndexNotAnyAfter(s string, chars string, ix int) int // It is equivalent to [SplitAfterByteN] with a count of -1. func SplitAfterByte(s string, sep byte) []string -// SplitAfterByteN slices s into substrings after each instance of the byte -// sep and returns a slice of those substrings. +// Slices s into substrings after each instance of the byte sep and returns +// a slice of those substrings. // // ix determines the number of substrings to return: // - n > 0: at most n substrings; the last substring being the unsplit @@ -253,8 +304,8 @@ func SplitAfterByte(s string, sep byte) []string // - n < 0: all substrings. func SplitAfterByteN(s string, sep byte, ix int) []string -// SplitAfterRune slices a string into all substings after each instance of -// the rune sep and returns a slice of those substrings. +// Slices a string into all substings after each instance of the rune sep +// and returns a slice of those substrings. // // If s does not contain sep, SplitAfterRune returns a slice of length 1 // whose only element is s. @@ -262,8 +313,8 @@ func SplitAfterByteN(s string, sep byte, ix int) []string // It is equivalent to [SplitAfterRuneN] with a count of -1. func SplitAfterRune(s string, sep rune) []string -// SplitAfterRuneN slices s into substrings after each instance of the rune -// sep and returns a slice of those substrings. +// Slices s into substrings after each instance of the rune sep and returns +// a slice of those substrings. // // ix determines the number of substrings to return: // - n > 0: at most n substrings; the last substring being the unsplit @@ -272,8 +323,8 @@ func SplitAfterRune(s string, sep rune) []string // - n < 0: all substrings. func SplitAfterRuneN(s string, sep rune, ix int) []string -// SplitAfterAny slices a string into all substings after each instance of -// any of the runes in chars and returns a slice of those substrings. +// Slices a string into all substings after each instance of any of the +// runes in chars and returns a slice of those substrings. // // If s does not contain any of the runes in chars and chars is not empty, // SplitAfterAny returns a slice of length 1 whose only element is s. @@ -281,8 +332,8 @@ func SplitAfterRuneN(s string, sep rune, ix int) []string // It is equivalent to [SplitAfterAnyN] with a count of -1. func SplitAfterAny(s, chars string) []string -// SplitAfterAnyN slices s into substrings after each instance of any of the -// runes in chars and returns a slice of those substrings. +// Slices s into substrings after each instance of any of the runes in chars +// and returns a slice of those substrings. // // ix determines the number of substrings to return: // - n > 0: at most n substrings; the last substring being the unsplit @@ -291,9 +342,8 @@ func SplitAfterAny(s, chars string) []string // - n < 0: all substrings. func SplitAfterAnyN(s, chars string, ix int) []string -// SplitAfterAnyBytes slices a string into all substings after each -// instance of any of the bytes in seps and returns a slice of those -// substrings. +// Slices a string into all substings after each instance of any of the +// bytes in seps and returns a slice of those substrings. // // If s does not contain any of the bytes in seps and seps is not empty, // SplitAfterAnyBytes returns a slice of length 1 whose only element is s. @@ -301,9 +351,8 @@ func SplitAfterAnyN(s, chars string, ix int) []string // It is equivalent to [SplitAfterAnyBytesN] with a count of -1. func SplitAfterAnyBytes(s string, seps []byte) []string -// SplitAfterAnyBytesN slices a string into all substings after each -// instance of any of the bytes in seps and returns a slice of those -// substrings. +// Slices a string into all substings after each instance of any of the +// bytes in seps and returns a slice of those substrings. // // ix determines the number of substrings to return: // - n > 0: at most n substrings; the last substring being the unsplit @@ -312,9 +361,8 @@ func SplitAfterAnyBytes(s string, seps []byte) []string // - n < 0: all substrings. func SplitAfterAnyBytesN(s string, seps []byte, ix int) []string -// SplitAfterAnyRunes slices a string into all substings after each -// instance of any of the runes in seps and returns a slice of those -// substrings. +// Slices a string into all substings after each instance of any of the +// runes in seps and returns a slice of those substrings. // // If s does not contain any of the runes in seps and seps is not empty, // SplitAfterAnyRunes returns a slice of length 1 whose only element is s. @@ -322,9 +370,8 @@ func SplitAfterAnyBytesN(s string, seps []byte, ix int) []string // It is equivalent to [SplitAfterAnyN] with a count of -1. func SplitAfterAnyRunes(s string, seps []rune) []string -// SplitAfterAnyRunesN slices a string into all substings after each -// instance of any of the runes in seps and returns a slice of those -// substrings. +// Slices a string into all substings after each instance of any of the +// runes in seps and returns a slice of those substrings. // // ix determines the number of substrings to return: // - n > 0: at most n substrings; the last substring being the unsplit @@ -334,17 +381,19 @@ func SplitAfterAnyRunes(s string, seps []rune) []string func SplitAfterAnyRunesN(s string, seps []rune, ix int) []string ``` +#### `Chomp` Functions + ```Go // in "github.com/synesissoftware/ANGoLS/strings" -// StringChomp() takes a single string and returns a chomped version of it, -// where chomping removes a single trailing '\n' character, a single -// trailing '\r' character, or a single trailing sequence of "\r\n" +// Takes a single string and returns a chomped version of it, where chomping +// removes a single trailing '\n' character, a single trailing '\r' +// character, or a single trailing sequence of "\r\n". func StringChomp(s string) string -// StringChompAll() takes a single string and returns a fully/repeatedly -// chomped version of, where full/repeated chomping removes all trailing -// '\r' and/or '\n' characters +// Takes a single string and returns a fully/repeatedly chomped version of, +// where full/repeated chomping removes all trailing '\r' and/or '\n' +// characters. func StringChompAll(s string) string ``` diff --git a/TODO.md b/TODO.md index a3b89ab..4485a1d 100644 --- a/TODO.md +++ b/TODO.md @@ -4,17 +4,30 @@ recls for Go ## Table of contents -- [Section-1](#section-1) -- [Section-2](#section-2) +- [0.9.x Items](#09x-items) +- [0.10+ Items](#010-items) +- [0.11+ Items](#011-items) -## Section-1 +## 0.9.x Items -T.B.C. +* simplify `CollectSlice()`; +* add unit-testing for `slices` functions; +* enhance code coverage in unit-tests; -## Section-2 +## 0.10+ Items -T.B.C. +* change semantics of `CollectSlice()`, `EqualSlice()` to not take `any`, but (at least) `[]any`; +* correct all `slices` functions to proper naming, including `Uint` rather than `UInt`; +* `GenerateSliceOfInteger[T]()`; +* `SelectSlice[T]()`; +* expand coverage of specific types for `EqualSlice[T]()`; + + +## 0.11+ Items + +* simplify names, e.g. `CollectSlice()` => `Collect()`, and so forth; +* \ diff --git a/slices/collect_slice.go b/slices/collect_slice.go index 2fbf6ce..1d824ad 100644 --- a/slices/collect_slice.go +++ b/slices/collect_slice.go @@ -1,10 +1,10 @@ -// Copyright 2019-2025 Matthew Wilson and Synesis Information Systems. All +// Copyright 2019-2026 Matthew Wilson and Synesis Information Systems. All // rights reserved. Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. /* * Created: 1st March 2019 - * Updated: 27th November 2025 + * Updated: 7th February 2026 */ package slices @@ -67,7 +67,8 @@ func CollectSliceOfInt(input_slice []int, fn func(input_item int) int) (result_s return } -// CollectSliceOfInteger +// This function maps an input slice of []N to an output slice of []N, where +// N is any integer type. func CollectSliceOfInteger[N int8 | int16 | int32 | int64 | int | uint8 | uint16 | uint32 | uint64 | uint | uintptr](input_slice []N, fn func(input_item N) N) (result_slice []N) { result_slice = make([]N, len(input_slice)) diff --git a/slices/collect_test.go b/slices/collect_test.go index ae7086d..1f1f613 100644 --- a/slices/collect_test.go +++ b/slices/collect_test.go @@ -1,10 +1,9 @@ package slices_test import ( - "fmt" - "github.com/synesissoftware/ANGoLS/slices" + "fmt" "strconv" "strings" "testing" diff --git a/slices/equal_slice.go b/slices/equal_slice.go index 128e685..bcb67fb 100644 --- a/slices/equal_slice.go +++ b/slices/equal_slice.go @@ -16,6 +16,8 @@ import ( // ///////////////////////////////////////////////////////////////////////// // EqualSlice*() +// Indicates whether two []int slices have the same size, contents, and +// order. func EqualSliceOfInt(lhs, rhs []int) bool { len_l := len(lhs) @@ -38,6 +40,8 @@ func EqualSliceOfInt(lhs, rhs []int) bool { } } +// Indicates whether two []uint slices have the same size, contents, and +// order. func EqualSliceOfUInt(lhs, rhs []uint) bool { len_l := len(lhs) @@ -60,7 +64,7 @@ func EqualSliceOfUInt(lhs, rhs []uint) bool { } } -func EqualSliceOfInteger[N int8 | int16 | int32 | int64 | int | uint8 | uint16 | uint32 | uint64 | uint | uintptr](lhs, rhs []int) bool { +func EqualSliceOfInteger[N int8 | int16 | int32 | int64 | int | uint8 | uint16 | uint32 | uint64 | uint | uintptr](lhs, rhs []N) bool { len_l := len(lhs) len_r := len(rhs) @@ -82,6 +86,8 @@ func EqualSliceOfInteger[N int8 | int16 | int32 | int64 | int | uint8 | uint16 | } } +// Indicates whether two []float64 slices have the same size, contents, and +// order. func EqualSliceOfFloat64(lhs, rhs []float64) bool { len_l := len(lhs) @@ -104,6 +110,8 @@ func EqualSliceOfFloat64(lhs, rhs []float64) bool { } } +// Indicates whether two []string slices have the same size, contents, and +// order. func EqualSliceOfString(lhs, rhs []string) bool { len_l := len(lhs) diff --git a/slices/equal_test.go b/slices/equal_test.go new file mode 100644 index 0000000..1ed1913 --- /dev/null +++ b/slices/equal_test.go @@ -0,0 +1,197 @@ +package slices_test + +import ( + "github.com/synesissoftware/ANGoLS/slices" + + "github.com/stretchr/testify/assert" + + "testing" +) + +func Test_EqualSliceOfInt(t *testing.T) { + + { + assert.True(t, slices.EqualSliceOfInt([]int{}, []int{})) + assert.True(t, slices.EqualSliceOfInt([]int{1}, []int{1})) + assert.False(t, slices.EqualSliceOfInt([]int{1}, []int{2})) + + assert.True(t, slices.EqualSliceOfInt([]int{1, 2, 3, 4}, []int{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInt([]int{1, 2, 3, 4}, []int{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInt([]int{1, 2, 3, 4, 5}[:4], []int{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]int{}, []int{})) + assert.True(t, slices.EqualSliceOfInteger([]int{1}, []int{1})) + assert.False(t, slices.EqualSliceOfInteger([]int{1}, []int{2})) + + assert.True(t, slices.EqualSliceOfInteger([]int{1, 2, 3, 4}, []int{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]int{1, 2, 3, 4}, []int{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]int{1, 2, 3, 4, 5}[:4], []int{1, 2, 3, 4, 6}[:4])) + } +} + +func Test_EqualSliceOfUint(t *testing.T) { + + { + assert.True(t, slices.EqualSliceOfUInt([]uint{}, []uint{})) + assert.True(t, slices.EqualSliceOfUInt([]uint{1}, []uint{1})) + assert.False(t, slices.EqualSliceOfUInt([]uint{1}, []uint{2})) + + assert.True(t, slices.EqualSliceOfUInt([]uint{1, 2, 3, 4}, []uint{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfUInt([]uint{1, 2, 3, 4}, []uint{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfUInt([]uint{1, 2, 3, 4, 5}[:4], []uint{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]uint{}, []uint{})) + assert.True(t, slices.EqualSliceOfInteger([]uint{1}, []uint{1})) + assert.False(t, slices.EqualSliceOfInteger([]uint{1}, []uint{2})) + + assert.True(t, slices.EqualSliceOfInteger([]uint{1, 2, 3, 4}, []uint{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]uint{1, 2, 3, 4}, []uint{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]uint{1, 2, 3, 4, 5}[:4], []uint{1, 2, 3, 4, 6}[:4])) + } +} + +func Test_EqualSliceOfInteger(t *testing.T) { + + { + assert.True(t, slices.EqualSliceOfInteger([]int{}, []int{})) + assert.True(t, slices.EqualSliceOfInteger([]int{1}, []int{1})) + assert.False(t, slices.EqualSliceOfInteger([]int{1}, []int{2})) + + assert.True(t, slices.EqualSliceOfInteger([]int{1, 2, 3, 4}, []int{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]int{1, 2, 3, 4}, []int{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]int{1, 2, 3, 4, 5}[:4], []int{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]uint{}, []uint{})) + assert.True(t, slices.EqualSliceOfInteger([]uint{1}, []uint{1})) + assert.False(t, slices.EqualSliceOfInteger([]uint{1}, []uint{2})) + + assert.True(t, slices.EqualSliceOfInteger([]uint{1, 2, 3, 4}, []uint{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]uint{1, 2, 3, 4}, []uint{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]uint{1, 2, 3, 4, 5}[:4], []uint{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]int8{}, []int8{})) + assert.True(t, slices.EqualSliceOfInteger([]int8{1}, []int8{1})) + assert.False(t, slices.EqualSliceOfInteger([]int8{1}, []int8{2})) + + assert.True(t, slices.EqualSliceOfInteger([]int8{1, 2, 3, 4}, []int8{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]int8{1, 2, 3, 4}, []int8{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]int8{1, 2, 3, 4, 5}[:4], []int8{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]uint8{}, []uint8{})) + assert.True(t, slices.EqualSliceOfInteger([]uint8{1}, []uint8{1})) + assert.False(t, slices.EqualSliceOfInteger([]uint8{1}, []uint8{2})) + + assert.True(t, slices.EqualSliceOfInteger([]uint8{1, 2, 3, 4}, []uint8{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]uint8{1, 2, 3, 4}, []uint8{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]uint8{1, 2, 3, 4, 5}[:4], []uint8{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]int16{}, []int16{})) + assert.True(t, slices.EqualSliceOfInteger([]int16{1}, []int16{1})) + assert.False(t, slices.EqualSliceOfInteger([]int16{1}, []int16{2})) + + assert.True(t, slices.EqualSliceOfInteger([]int16{1, 2, 3, 4}, []int16{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]int16{1, 2, 3, 4}, []int16{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]int16{1, 2, 3, 4, 5}[:4], []int16{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]uint16{}, []uint16{})) + assert.True(t, slices.EqualSliceOfInteger([]uint16{1}, []uint16{1})) + assert.False(t, slices.EqualSliceOfInteger([]uint16{1}, []uint16{2})) + + assert.True(t, slices.EqualSliceOfInteger([]uint16{1, 2, 3, 4}, []uint16{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]uint16{1, 2, 3, 4}, []uint16{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]uint16{1, 2, 3, 4, 5}[:4], []uint16{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]int32{}, []int32{})) + assert.True(t, slices.EqualSliceOfInteger([]int32{1}, []int32{1})) + assert.False(t, slices.EqualSliceOfInteger([]int32{1}, []int32{2})) + + assert.True(t, slices.EqualSliceOfInteger([]int32{1, 2, 3, 4}, []int32{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]int32{1, 2, 3, 4}, []int32{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]int32{1, 2, 3, 4, 5}[:4], []int32{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]uint32{}, []uint32{})) + assert.True(t, slices.EqualSliceOfInteger([]uint32{1}, []uint32{1})) + assert.False(t, slices.EqualSliceOfInteger([]uint32{1}, []uint32{2})) + + assert.True(t, slices.EqualSliceOfInteger([]uint32{1, 2, 3, 4}, []uint32{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]uint32{1, 2, 3, 4}, []uint32{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]uint32{1, 2, 3, 4, 5}[:4], []uint32{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]int64{}, []int64{})) + assert.True(t, slices.EqualSliceOfInteger([]int64{1}, []int64{1})) + assert.False(t, slices.EqualSliceOfInteger([]int64{1}, []int64{2})) + + assert.True(t, slices.EqualSliceOfInteger([]int64{1, 2, 3, 4}, []int64{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]int64{1, 2, 3, 4}, []int64{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]int64{1, 2, 3, 4, 5}[:4], []int64{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]uint64{}, []uint64{})) + assert.True(t, slices.EqualSliceOfInteger([]uint64{1}, []uint64{1})) + assert.False(t, slices.EqualSliceOfInteger([]uint64{1}, []uint64{2})) + + assert.True(t, slices.EqualSliceOfInteger([]uint64{1, 2, 3, 4}, []uint64{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]uint64{1, 2, 3, 4}, []uint64{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]uint64{1, 2, 3, 4, 5}[:4], []uint64{1, 2, 3, 4, 6}[:4])) + } + + { + assert.True(t, slices.EqualSliceOfInteger([]uintptr{}, []uintptr{})) + assert.True(t, slices.EqualSliceOfInteger([]uintptr{1}, []uintptr{1})) + assert.False(t, slices.EqualSliceOfInteger([]uintptr{1}, []uintptr{2})) + + assert.True(t, slices.EqualSliceOfInteger([]uintptr{1, 2, 3, 4}, []uintptr{1, 2, 3, 4})) + assert.False(t, slices.EqualSliceOfInteger([]uintptr{1, 2, 3, 4}, []uintptr{1, 2, 4, 3})) + + assert.True(t, slices.EqualSliceOfInteger([]uintptr{1, 2, 3, 4, 5}[:4], []uintptr{1, 2, 3, 4, 6}[:4])) + } +} + +func Test_EqualSliceOfString(t *testing.T) { + + { + assert.True(t, slices.EqualSliceOfString([]string{}, []string{})) + assert.True(t, slices.EqualSliceOfString([]string{"1"}, []string{"1"})) + assert.False(t, slices.EqualSliceOfString([]string{"1"}, []string{"2"})) + + assert.True(t, slices.EqualSliceOfString([]string{"1", "2", "3", "4"}, []string{"1", "2", "3", "4"})) + assert.False(t, slices.EqualSliceOfString([]string{"1", "2", "3", "4"}, []string{"1", "2", "4", "3"})) + + assert.True(t, slices.EqualSliceOfString([]string{"1", "2", "3", "4", "5"}[:4], []string{"1", "2", "3", "4", "6"}[:4])) + } +} diff --git a/slices/select_test.go b/slices/select_test.go new file mode 100644 index 0000000..da561c6 --- /dev/null +++ b/slices/select_test.go @@ -0,0 +1,276 @@ +package slices_test + +import ( + "github.com/synesissoftware/ANGoLS/slices" + + "github.com/stretchr/testify/assert" + + "testing" +) + +func Test_SelectSliceOfInt(t *testing.T) { + + { + input := []int{} + + { + r, _ := slices.SelectSliceOfInt( + input, + func(_, _ int) (bool, error) { return true, nil }, + ) + + assert.Equal(t, []int{}, r) + } + { + r, _ := slices.SelectSliceOfInt( + input, + func(_, _ int) (bool, error) { return false, nil }, + ) + + assert.Equal(t, []int{}, r) + } + } + + { + input := []int{1} + + { + r, _ := slices.SelectSliceOfInt( + input, + func(_, _ int) (bool, error) { return true, nil }, + ) + + assert.Equal(t, []int{1}, r) + } + { + r, _ := slices.SelectSliceOfInt( + input, + func(_, _ int) (bool, error) { return false, nil }, + ) + + assert.Equal(t, []int{}, r) + } + } + + { + input := []int{1, 2, 3, 4, 5, 6} + + { + r, _ := slices.SelectSliceOfInt( + input, + func(_, input_item int) (bool, error) { return 0 != (input_item % 2), nil }, + ) + + assert.Equal(t, []int{1, 3, 5}, r) + } + { + r, _ := slices.SelectSliceOfInt( + input, + func(_, input_item int) (bool, error) { return 0 == (input_item % 2), nil }, + ) + + assert.Equal(t, []int{2, 4, 6}, r) + } + } +} + +func Test_SelectSliceOfUInt(t *testing.T) { + + { + input := []uint{} + + { + r, _ := slices.SelectSliceOfUInt( + input, + func(_ int, _ uint) (bool, error) { return true, nil }, + ) + + assert.Equal(t, []uint{}, r) + } + { + r, _ := slices.SelectSliceOfUInt( + input, + func(_ int, _ uint) (bool, error) { return false, nil }, + ) + + assert.Equal(t, []uint{}, r) + } + } + + { + input := []uint{1} + + { + r, _ := slices.SelectSliceOfUInt( + input, + func(_ int, _ uint) (bool, error) { return true, nil }, + ) + + assert.Equal(t, []uint{1}, r) + } + { + r, _ := slices.SelectSliceOfUInt( + input, + func(_ int, _ uint) (bool, error) { return false, nil }, + ) + + assert.Equal(t, []uint{}, r) + } + } + + { + input := []uint{1, 2, 3, 4, 5, 6} + + { + r, _ := slices.SelectSliceOfUInt( + input, + func(_ int, input_item uint) (bool, error) { return 0 != (input_item % 2), nil }, + ) + + assert.Equal(t, []uint{1, 3, 5}, r) + } + { + r, _ := slices.SelectSliceOfUInt( + input, + func(_ int, input_item uint) (bool, error) { return 0 == (input_item % 2), nil }, + ) + + assert.Equal(t, []uint{2, 4, 6}, r) + } + } +} + +func Test_SelectSliceOfInteger(t *testing.T) { + + // int + { + { + input := []int{} + + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, _ int) (bool, error) { return true, nil }, + ) + + assert.Equal(t, []int{}, r) + } + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, _ int) (bool, error) { return false, nil }, + ) + + assert.Equal(t, []int{}, r) + } + } + + { + input := []int{1} + + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, _ int) (bool, error) { return true, nil }, + ) + + assert.Equal(t, []int{1}, r) + } + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, _ int) (bool, error) { return false, nil }, + ) + + assert.Equal(t, []int{}, r) + } + } + + { + input := []int{1, 2, 3, 4, 5, 6} + + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, input_item int) (bool, error) { return 0 != (input_item % 2), nil }, + ) + + assert.Equal(t, []int{1, 3, 5}, r) + } + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, input_item int) (bool, error) { return 0 == (input_item % 2), nil }, + ) + + assert.Equal(t, []int{2, 4, 6}, r) + } + } + } + + // int + { + { + input := []int{} + + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, _ int) (bool, error) { return true, nil }, + ) + + assert.Equal(t, []int{}, r) + } + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, _ int) (bool, error) { return false, nil }, + ) + + assert.Equal(t, []int{}, r) + } + } + + { + input := []int{1} + + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, _ int) (bool, error) { return true, nil }, + ) + + assert.Equal(t, []int{1}, r) + } + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, _ int) (bool, error) { return false, nil }, + ) + + assert.Equal(t, []int{}, r) + } + } + + { + input := []int{1, 2, 3, 4, 5, 6} + + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, input_item int) (bool, error) { return 0 != (input_item % 2), nil }, + ) + + assert.Equal(t, []int{1, 3, 5}, r) + } + { + r, _ := slices.SelectSliceOfUInteger( + input, + func(_, input_item int) (bool, error) { return 0 == (input_item % 2), nil }, + ) + + assert.Equal(t, []int{2, 4, 6}, r) + } + } + } +} diff --git a/strings/ascii_test.go b/strings/ascii_test.go index ed5491d..bf119cd 100644 --- a/strings/ascii_test.go +++ b/strings/ascii_test.go @@ -6,6 +6,7 @@ package strings_test import ( strings "github.com/synesissoftware/ANGoLS/strings" + stegol "github.com/synesissoftware/STEGoL" stdstrings "strings" diff --git a/strings/chomps.go b/strings/chomps.go index 61f1ff8..e578dc1 100644 --- a/strings/chomps.go +++ b/strings/chomps.go @@ -1,10 +1,10 @@ -// Copyright 2019-2025 Matthew Wilson and Synesis Information Systems. All +// Copyright 2019-2026 Matthew Wilson and Synesis Information Systems. All // rights reserved. Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. /* * Created: 30th March 2019 - * Updated: 27th November 2025 + * Updated: 7th February 2026 */ package strings diff --git a/strings/chomps_test.go b/strings/chomps_test.go index e8f7b70..830af84 100644 --- a/strings/chomps_test.go +++ b/strings/chomps_test.go @@ -2,6 +2,7 @@ package strings_test import ( strings "github.com/synesissoftware/ANGoLS/strings" + stegol "github.com/synesissoftware/STEGoL" "testing" diff --git a/strings/find_test.go b/strings/find_test.go index f9fd146..224aa9d 100644 --- a/strings/find_test.go +++ b/strings/find_test.go @@ -1,9 +1,10 @@ package strings_test import ( - "github.com/stretchr/testify/require" strings "github.com/synesissoftware/ANGoLS/strings" + "github.com/stretchr/testify/require" + "testing" ) diff --git a/version.go b/version.go index de574b7..fa1b750 100644 --- a/version.go +++ b/version.go @@ -4,7 +4,7 @@ /* * Created: 1st March 2019 - * Updated: 3rd January 2025 + * Updated: 6th February 2026 */ package angols @@ -14,7 +14,7 @@ import "github.com/synesissoftware/ver2go" const ( VersionMajor uint16 = 0 VersionMinor uint16 = 9 - VersionPatch uint16 = 0 + VersionPatch uint16 = 1 VersionAB uint16 = 0xFFFF Version uint64 = (uint64(VersionMajor) << 48) + (uint64(VersionMinor) << 32) + (uint64(VersionPatch) << 16) + (uint64(VersionAB) << 0) ) diff --git a/version_test.go b/version_test.go index bfad339..8944a74 100644 --- a/version_test.go +++ b/version_test.go @@ -1,16 +1,17 @@ package angols_test import ( - "github.com/stretchr/testify/require" angols "github.com/synesissoftware/ANGoLS" + "github.com/stretchr/testify/require" + "testing" ) const ( Expected_VersionMajor uint16 = 0 Expected_VersionMinor uint16 = 9 - Expected_VersionPatch uint16 = 0 + Expected_VersionPatch uint16 = 1 Expected_VersionAB uint16 = 0xFFFF ) @@ -22,9 +23,9 @@ func Test_Version_Elements(t *testing.T) { } func Test_Version(t *testing.T) { - require.Equal(t, uint64(0x0000_0009_0000_FFFF), angols.Version) + require.Equal(t, uint64(0x0000_0009_0001_FFFF), angols.Version) } func Test_Version_String(t *testing.T) { - require.Equal(t, "0.9.0", angols.VersionString()) + require.Equal(t, "0.9.1", angols.VersionString()) }