From 0c88071297203032a610fd40bd83ab1944852a04 Mon Sep 17 00:00:00 2001 From: gabrielseibel1 Date: Tue, 25 Jun 2024 15:02:10 -0300 Subject: [PATCH] Add All* funcs to check --- check/check.go | 53 +++++++++------ check/check_test.go | 162 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 20 deletions(-) diff --git a/check/check.go b/check/check.go index d130fa5..a9be09a 100644 --- a/check/check.go +++ b/check/check.go @@ -1,66 +1,81 @@ // Package check has functions to check if some condition is valid for slices and maps // TODO indexed -// TODO all package check +// All checks that the provided slice has every element satifying the checker function +func All[T any](s []T, f func(T) bool) bool { + return len(s) != 0 && !hasAny[T](false)(s, f) +} + // Some checks that the provided slice has any element that satisfies the checker function func Some[T any](s []T, f func(T) bool) bool { - return check[T](true)(s, f) + return len(s) != 0 && hasAny[T](true)(s, f) } // None checks that the provided slice has no element that satisfies the checker function func None[T any](s []T, f func(T) bool) bool { - return check[T](false)(s, f) + return !hasAny[T](true)(s, f) +} + +// All checks that the provided map has every key satifying the checker function +func AllKeys[T comparable, U any](m map[T]U, f func(T) bool) bool { + return len(m) != 0 && !hasAnyKey[T, U](false)(m, f) } // SomeKey checks that the provided map has any key that satisfies the checker function func SomeKey[T comparable, U any](m map[T]U, f func(T) bool) bool { - return checkKey[T, U](true)(m, f) + return hasAnyKey[T, U](true)(m, f) } // NoKey checks that the provided map has no key that satisfies the checker function func NoKey[T comparable, U any](m map[T]U, f func(T) bool) bool { - return checkKey[T, U](false)(m, f) + return !hasAnyKey[T, U](true)(m, f) +} + +// All checks that the provided map has every value satifying the checker function +func AllValues[T comparable, U any](m map[T]U, f func(U) bool) bool { + return len(m) != 0 && !hasAnyVal[T, U](false)(m, f) } // SomeValue checks that the provided map has any value that satisfies the checker function func SomeValue[T comparable, U any](m map[T]U, f func(U) bool) bool { - return checkVal[T, U](true)(m, f) + return hasAnyVal[T, U](true)(m, f) } // NoValue checks that the provided map has no value that satisfies the checker function func NoValue[T comparable, U any](m map[T]U, f func(U) bool) bool { - return checkVal[T, U](false)(m, f) + return !hasAnyVal[T, U](true)(m, f) } -func check[T any](b bool) func(s []T, f func(T) bool) bool { +func hasAny[T any](b bool) func(s []T, f func(T) bool) bool { return func(s []T, f func(T) bool) bool { for _, v := range s { - if f(v) { - return b + if f(v) == b { + return true } } - return !b + return false } } -func checkVal[T comparable, U any](b bool) func(m map[T]U, f func(U) bool) bool { + +func hasAnyVal[T comparable, U any](b bool) func(m map[T]U, f func(U) bool) bool { return func(m map[T]U, f func(U) bool) bool { for _, v := range m { - if f(v) { - return b + if f(v) == b { + return true } } - return !b + return false } } -func checkKey[T comparable, U any](b bool) func(m map[T]U, f func(T) bool) bool { +func hasAnyKey[T comparable, U any](b bool) func(m map[T]U, f func(T) bool) bool { return func(m map[T]U, f func(T) bool) bool { for k := range m { - if f(k) { - return b + if f(k) == b { + return true } } - return !b + return false } } diff --git a/check/check_test.go b/check/check_test.go index 9dc9693..15995e4 100644 --- a/check/check_test.go +++ b/check/check_test.go @@ -1,11 +1,65 @@ package check_test import ( + "testing" + "github.com/gabrielseibel1/fungo/check" "github.com/gabrielseibel1/fungo/util" - "testing" ) +func TestAll(t *testing.T) { + type args[T any] struct { + s []T + f func(T) bool + } + type testCase[T any] struct { + name string + args args[T] + want bool + } + tests := []testCase[util.Data]{ + { + name: "empty/nil", + args: args[util.Data]{ + s: nil, + f: util.PassAll[util.Data], + }, + want: false, + }, + { + name: "none", + args: args[util.Data]{ + s: []util.Data{util.Data1, util.Data2}, + f: util.PassNo[util.Data], + }, + want: false, + }, + { + name: "some", + args: args[util.Data]{ + s: []util.Data{util.Data1, util.Data2}, + f: util.Is(util.Data1), + }, + want: false, + }, + { + name: "all", + args: args[util.Data]{ + s: []util.Data{util.Data1, util.Data1, util.Data2}, + f: func(d util.Data) bool { return util.Is(util.Data1)(d) || util.Is(util.Data2)(d) }, + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := check.All(tt.args.s, tt.args.f); got != tt.want { + t.Errorf("All = %v, want %v", got, tt.want) + } + }) + } +} + func TestSome(t *testing.T) { type args[T any] struct { s []T @@ -186,6 +240,59 @@ func TestNoValue(t *testing.T) { } } +func TestAllKeys(t *testing.T) { + type args[T comparable, U any] struct { + m map[T]U + f func(T) bool + } + type testCase[T comparable, U any] struct { + name string + args args[T, U] + want bool + } + tests := []testCase[string, int]{ + { + name: "empty", + args: args[string, int]{ + m: nil, + f: util.PassAll[string], + }, + want: false, + }, + { + name: "some", + args: args[string, int]{ + m: map[string]int{"1": 1, "b": 2}, + f: util.IsInt, + }, + want: false, + }, + { + name: "none", + args: args[string, int]{ + m: map[string]int{"a": 1, "b": 2}, + f: util.IsInt, + }, + want: false, + }, + { + name: "all", + args: args[string, int]{ + m: map[string]int{"1": 1, "2": 2}, + f: util.IsInt, + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := check.AllKeys(tt.args.m, tt.args.f); got != tt.want { + t.Errorf("AllKeys() = %v, want %v", got, tt.want) + } + }) + } +} + func TestSomeKey(t *testing.T) { type args[T comparable, U any] struct { m map[T]U @@ -275,3 +382,56 @@ func TestSomeValue(t *testing.T) { }) } } + +func TestAllValues(t *testing.T) { + type args[T comparable, U any] struct { + m map[T]U + f func(U) bool + } + type testCase[T comparable, U any] struct { + name string + args args[T, U] + want bool + } + tests := []testCase[int, string]{ + { + name: "empty", + args: args[int, string]{ + m: nil, + f: util.PassAll[string], + }, + want: false, + }, + { + name: "some", + args: args[int, string]{ + m: map[int]string{1: "1", 2: "b"}, + f: util.IsInt, + }, + want: false, + }, + { + name: "none", + args: args[int, string]{ + m: map[int]string{1: "a", 2: "b"}, + f: util.IsInt, + }, + want: false, + }, + { + name: "all", + args: args[int, string]{ + m: map[int]string{1: "1", 2: "2"}, + f: util.IsInt, + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := check.AllValues(tt.args.m, tt.args.f); got != tt.want { + t.Errorf("AllValues() = %v, want %v", got, tt.want) + } + }) + } +}