Merge pull request #359 from apelisse/predicates-package

unstructpath: Move predicates to their own package
This commit is contained in:
k8s-ci-robot 2018-03-19 09:54:01 -07:00 committed by GitHub
commit 73cf61c131
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 158 additions and 122 deletions

View File

@ -14,21 +14,21 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath
package predicates
// MapP is a "map predicate". It's a type that decides if a
// Map is a "map predicate". It's a type that decides if a
// map matches or not.
type MapP interface {
type Map interface {
Match(map[string]interface{}) bool
}
// MapNot inverses the value of the predicate.
func MapNot(predicate MapP) MapP {
func MapNot(predicate Map) Map {
return mapNot{mp: predicate}
}
type mapNot struct {
mp MapP
mp Map
}
func (p mapNot) Match(m map[string]interface{}) bool {
@ -37,12 +37,12 @@ func (p mapNot) Match(m map[string]interface{}) bool {
// MapAnd returns true if all the sub-predicates are true. If there are
// no sub-predicates, always returns true.
func MapAnd(predicates ...MapP) MapP {
func MapAnd(predicates ...Map) Map {
return mapAnd{mps: predicates}
}
type mapAnd struct {
mps []MapP
mps []Map
}
func (p mapAnd) Match(m map[string]interface{}) bool {
@ -56,8 +56,8 @@ func (p mapAnd) Match(m map[string]interface{}) bool {
// MapOr returns true if any sub-predicate is true. If there are no
// sub-predicates, always returns false.
func MapOr(predicates ...MapP) MapP {
mps := []MapP{}
func MapOr(predicates ...Map) Map {
mps := []Map{}
// Implements "De Morgan's law"
for _, mp := range predicates {
@ -68,12 +68,12 @@ func MapOr(predicates ...MapP) MapP {
// MapNumFields matches if the number of fields matches the number
// predicate.
func MapNumFields(predicate NumberP) MapP {
func MapNumFields(predicate Number) Map {
return mapNumFields{ip: predicate}
}
type mapNumFields struct {
ip NumberP
ip Number
}
func (p mapNumFields) Match(m map[string]interface{}) bool {

View File

@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath_test
package predicates_test
import (
"testing"
. "k8s.io/kubectl/pkg/framework/unstructpath"
. "k8s.io/kubectl/pkg/framework/predicates"
)
type MapTrue struct{}

View File

@ -14,21 +14,21 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath
package predicates
// NumberP is a "number predicate". It's a type that decides if a
// Number is a "number predicate". It's a type that decides if a
// number matches or not.
type NumberP interface {
type Number interface {
Match(float64) bool
}
// NumberNot inverts the result of the sub-predicate.
func NumberNot(predicate NumberP) NumberP {
func NumberNot(predicate Number) Number {
return numberNot{ip: predicate}
}
type numberNot struct {
ip NumberP
ip Number
}
func (p numberNot) Match(i float64) bool {
@ -37,12 +37,12 @@ func (p numberNot) Match(i float64) bool {
// NumberAnd returns true if all the sub-predicates are true. If there are
// no sub-predicates, always returns true.
func NumberAnd(predicates ...NumberP) NumberP {
func NumberAnd(predicates ...Number) Number {
return numberAnd{ips: predicates}
}
type numberAnd struct {
ips []NumberP
ips []Number
}
func (p numberAnd) Match(i float64) bool {
@ -56,8 +56,8 @@ func (p numberAnd) Match(i float64) bool {
// NumberOr returns true if any sub-predicate is true. If there are no
// sub-predicates, always returns false.
func NumberOr(predicates ...NumberP) NumberP {
ips := []NumberP{}
func NumberOr(predicates ...Number) Number {
ips := []Number{}
// Implements "De Morgan's law"
for _, ip := range predicates {
@ -67,7 +67,7 @@ func NumberOr(predicates ...NumberP) NumberP {
}
// NumberEqual returns true if the value is exactly i.
func NumberEqual(i float64) NumberP {
func NumberEqual(i float64) Number {
return numberEqual{i: i}
}
@ -80,7 +80,7 @@ func (p numberEqual) Match(i float64) bool {
}
// NumberGreaterThan returns true if the value is strictly greater than i.
func NumberGreaterThan(i float64) NumberP {
func NumberGreaterThan(i float64) Number {
return numberGreaterThan{i: i}
}
@ -94,17 +94,17 @@ func (p numberGreaterThan) Match(i float64) bool {
// NumberEqualOrGreaterThan returns true if the value is equal or greater
// than i.
func NumberEqualOrGreaterThan(i float64) NumberP {
func NumberEqualOrGreaterThan(i float64) Number {
return NumberOr(NumberEqual(i), NumberGreaterThan(i))
}
// NumberLessThan returns true if the value is strictly less than i.
func NumberLessThan(i float64) NumberP {
func NumberLessThan(i float64) Number {
// It's not equal, and it's not greater than i.
return NumberAnd(NumberNot(NumberEqual(i)), NumberNot(NumberGreaterThan(i)))
}
// NumberEqualOrLessThan returns true if the value is equal or less than i.
func NumberEqualOrLessThan(i float64) NumberP {
func NumberEqualOrLessThan(i float64) Number {
return NumberOr(NumberEqual(i), NumberLessThan(i))
}

View File

@ -14,20 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath_test
package predicates_test
import (
"fmt"
"testing"
. "k8s.io/kubectl/pkg/framework/unstructpath"
. "k8s.io/kubectl/pkg/framework/predicates"
)
// This example shows you how you can create a IntP, and how it's use to
// compare with the actual value.
//
// XXX: This could definitely be improved to add a better example.
func ExampleNumberP() {
func ExampleNumber() {
fmt.Println(NumberEqual(5).Match(5))
// Output: true
}

View File

@ -14,21 +14,21 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath
package predicates
// SliceP is a "slice predicate". It's a type that decides if a
// Slice is a "slice predicate". It's a type that decides if a
// slice matches or not.
type SliceP interface {
type Slice interface {
Match([]interface{}) bool
}
// SliceNot inverses the value of the predicate.
func SliceNot(predicate SliceP) SliceP {
func SliceNot(predicate Slice) Slice {
return sliceNot{vp: predicate}
}
type sliceNot struct {
vp SliceP
vp Slice
}
func (p sliceNot) Match(slice []interface{}) bool {
@ -37,12 +37,12 @@ func (p sliceNot) Match(slice []interface{}) bool {
// SliceAnd returns true if all the sub-predicates are true. If there are
// no sub-predicates, always returns true.
func SliceAnd(predicates ...SliceP) SliceP {
func SliceAnd(predicates ...Slice) Slice {
return sliceAnd{sps: predicates}
}
type sliceAnd struct {
sps []SliceP
sps []Slice
}
func (p sliceAnd) Match(slice []interface{}) bool {
@ -56,8 +56,8 @@ func (p sliceAnd) Match(slice []interface{}) bool {
// SliceOr returns true if any sub-predicate is true. If there are no
// sub-predicates, always returns false.
func SliceOr(predicates ...SliceP) SliceP {
sps := []SliceP{}
func SliceOr(predicates ...Slice) Slice {
sps := []Slice{}
// Implements "De Morgan's law"
for _, sp := range predicates {
@ -68,12 +68,12 @@ func SliceOr(predicates ...SliceP) SliceP {
// SliceLength matches if the length of the list matches the given
// integer predicate.
func SliceLength(ip NumberP) SliceP {
func SliceLength(ip Number) Slice {
return sliceLength{ip: ip}
}
type sliceLength struct {
ip NumberP
ip Number
}
func (p sliceLength) Match(slice []interface{}) bool {

View File

@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath_test
package predicates_test
import (
"testing"
. "k8s.io/kubectl/pkg/framework/unstructpath"
. "k8s.io/kubectl/pkg/framework/predicates"
)
type SliceTrue struct{}

View File

@ -14,26 +14,26 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath
package predicates
import (
"regexp"
"strings"
)
// StringP is a "string predicate". It's a type that decides if a
// String is a "string predicate". It's a type that decides if a
// string matches or not.
type StringP interface {
type String interface {
Match(string) bool
}
// StringNot will inverse the result of the predicate.
func StringNot(predicate StringP) StringP {
func StringNot(predicate String) String {
return stringNot{sp: predicate}
}
type stringNot struct {
sp StringP
sp String
}
func (p stringNot) Match(str string) bool {
@ -42,12 +42,12 @@ func (p stringNot) Match(str string) bool {
// StringAnd returns true if all the sub-predicates are true. If there are
// no sub-predicates, always returns true.
func StringAnd(predicates ...StringP) StringP {
func StringAnd(predicates ...String) String {
return stringAnd{sps: predicates}
}
type stringAnd struct {
sps []StringP
sps []String
}
func (p stringAnd) Match(str string) bool {
@ -61,8 +61,8 @@ func (p stringAnd) Match(str string) bool {
// StringOr returns true if any sub-predicate is true. If there are no
// sub-predicates, always returns false.
func StringOr(predicates ...StringP) StringP {
sps := []StringP{}
func StringOr(predicates ...String) String {
sps := []String{}
// Implements "De Morgan's law"
for _, sp := range predicates {
@ -72,7 +72,7 @@ func StringOr(predicates ...StringP) StringP {
}
// StringEqual returns a predicate that matches only the exact string.
func StringEqual(str string) StringP {
func StringEqual(str string) String {
return stringEqual{str: str}
}
@ -86,12 +86,12 @@ func (p stringEqual) Match(str string) bool {
// StringLength matches if the length of the string matches the given
// integer predicate.
func StringLength(predicate NumberP) StringP {
func StringLength(predicate Number) String {
return stringLength{ip: predicate}
}
type stringLength struct {
ip NumberP
ip Number
}
func (p stringLength) Match(str string) bool {
@ -99,7 +99,7 @@ func (p stringLength) Match(str string) bool {
}
// StringHasPrefix matches if the string starts with the given prefix.
func StringHasPrefix(prefix string) StringP {
func StringHasPrefix(prefix string) String {
return stringHasPrefix{prefix: prefix}
}
@ -112,7 +112,7 @@ func (p stringHasPrefix) Match(str string) bool {
}
// StringHasSuffix matches if the string ends with the given suffix.
func StringHasSuffix(suffix string) StringP {
func StringHasSuffix(suffix string) String {
return stringHasSuffix{suffix: suffix}
}
@ -125,7 +125,7 @@ func (p stringHasSuffix) Match(str string) bool {
}
// StringRegexp matches if the string matches with the given regexp.
func StringRegexp(regex *regexp.Regexp) StringP {
func StringRegexp(regex *regexp.Regexp) String {
return stringRegexp{regex: regex}
}

View File

@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath_test
package predicates_test
import (
"regexp"
"testing"
. "k8s.io/kubectl/pkg/framework/unstructpath"
. "k8s.io/kubectl/pkg/framework/predicates"
)
func TestStringEqual(t *testing.T) {

View File

@ -14,20 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath
package predicates
import (
"reflect"
)
// ValueP is a "value predicate". It's a type that decides if a
// Value is a "value predicate". It's a type that decides if a
// value matches or not.
type ValueP interface {
type Value interface {
Match(interface{}) bool
}
// ValueDeepEqual compares the Value data with DeepEqual.
func ValueDeepEqual(v interface{}) ValueP {
func ValueDeepEqual(v interface{}) Value {
return valueEqual{v: v}
}
@ -40,12 +40,12 @@ func (p valueEqual) Match(v interface{}) bool {
}
// ValueNot inverses the value of the predicate.
func ValueNot(predicate ValueP) ValueP {
func ValueNot(predicate Value) Value {
return valueNot{vp: predicate}
}
type valueNot struct {
vp ValueP
vp Value
}
func (p valueNot) Match(v interface{}) bool {
@ -54,12 +54,12 @@ func (p valueNot) Match(v interface{}) bool {
// ValueAnd returns true if all the sub-predicates are true. If there are
// no sub-predicates, always returns true.
func ValueAnd(predicates ...ValueP) ValueP {
func ValueAnd(predicates ...Value) Value {
return valueAnd{vps: predicates}
}
type valueAnd struct {
vps []ValueP
vps []Value
}
func (p valueAnd) Match(value interface{}) bool {
@ -73,8 +73,8 @@ func (p valueAnd) Match(value interface{}) bool {
// ValueOr returns true if any sub-predicate is true. If there are no
// sub-predicates, always returns false.
func ValueOr(predicates ...ValueP) ValueP {
vps := []ValueP{}
func ValueOr(predicates ...Value) Value {
vps := []Value{}
// Implements "De Morgan's law"
for _, vp := range predicates {

View File

@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package unstructpath_test
package predicates_test
import (
"testing"
. "k8s.io/kubectl/pkg/framework/unstructpath"
. "k8s.io/kubectl/pkg/framework/predicates"
)
type ValueTrue struct{}

View File

@ -18,6 +18,8 @@ package unstructpath
import (
"github.com/ghodss/yaml"
p "k8s.io/kubectl/pkg/framework/predicates"
)
// This example is inspired from http://goessner.net/articles/JsonPath/#e3.
@ -77,13 +79,13 @@ func Example() {
All().Map().Field("book").Slice().Last().SelectFrom(u)
// The first two books. Returns a list of 2 interface{}.
All().Map().Field("book").Slice().AtP(NumberLessThan(2)).SelectFrom(u)
All().Map().Field("book").Slice().AtP(p.NumberLessThan(2)).SelectFrom(u)
// Filter all books with isbn number. Returns a list of interface{}.
All().Map().Field("book").Filter(Map().Field("isbn")).SelectFrom(u)
// Filter all books cheaper than 10. Returns a list of interface{}.
All().Map().Field("book").Children().Filter(Map().Field("price").Number().Filter(NumberLessThan(10))).SelectFrom(u)
All().Map().Field("book").Children().Filter(Map().Field("price").Number().Filter(p.NumberLessThan(10))).SelectFrom(u)
// All elements in structure. Returns a list of interface{}.
All().SelectFrom(u)

View File

@ -16,7 +16,11 @@ limitations under the License.
package unstructpath
import "sort"
import (
"sort"
p "k8s.io/kubectl/pkg/framework/predicates"
)
// This is a Map-to-Value filter.
type mapFilter interface {
@ -33,7 +37,7 @@ func filterMap(ms MapS, mf mapFilter) ValueS {
}
type mapFieldPFilter struct {
sp StringP
sp p.String
}
func (f mapFieldPFilter) SelectFrom(maps ...map[string]interface{}) []interface{} {

View File

@ -16,6 +16,10 @@ limitations under the License.
package unstructpath
import (
p "k8s.io/kubectl/pkg/framework/predicates"
)
// MapS is a "map selector". It selects values as maps (if
// possible) and filters those maps based on the "filtered"
// predicates.
@ -23,7 +27,7 @@ type MapS interface {
// MapS can be used as a Value predicate. If the selector can't
// select any map from the value, then the predicate is
// false.
ValueP
p.Value
// SelectFrom finds maps from values using this selector. The
// list can be bigger or smaller than the initial lists,
@ -38,7 +42,7 @@ type MapS interface {
// string predicate. This selector can return more values than
// it gets (for one map, it can returns multiple sub-values, one
// for each field that matches the predicate).
FieldP(...StringP) ValueS
FieldP(...p.String) ValueS
// All returns a selector that selects all direct and indrect
// children of the given values.
@ -49,7 +53,7 @@ type MapS interface {
// Filter will create a new MapS that filters only the values
// who match the predicate.
Filter(...MapP) MapS
Filter(...p.Map) MapS
}
// Map creates a selector that takes values and filters them into maps
@ -60,7 +64,7 @@ func Map() MapS {
type mapS struct {
vs ValueS
mp MapP
mp p.Map
}
func (s *mapS) SelectFrom(values ...interface{}) []map[string]interface{} {
@ -84,11 +88,11 @@ func (s *mapS) SelectFrom(values ...interface{}) []map[string]interface{} {
}
func (s *mapS) Field(str string) ValueS {
return s.FieldP(StringEqual(str))
return s.FieldP(p.StringEqual(str))
}
func (s *mapS) FieldP(predicates ...StringP) ValueS {
return filterMap(s, mapFieldPFilter{sp: StringAnd(predicates...)})
func (s *mapS) FieldP(predicates ...p.String) ValueS {
return filterMap(s, mapFieldPFilter{sp: p.StringAnd(predicates...)})
}
func (s *mapS) Children() ValueS {
@ -100,8 +104,8 @@ func (s *mapS) All() ValueS {
return filterMap(s, mapAllFilter{})
}
func (s *mapS) Filter(predicates ...MapP) MapS {
return &mapS{vs: s.vs, mp: MapAnd(append(predicates, s.mp)...)}
func (s *mapS) Filter(predicates ...p.Map) MapS {
return &mapS{vs: s.vs, mp: p.MapAnd(append(predicates, s.mp)...)}
}
func (s *mapS) Match(value interface{}) bool {

View File

@ -16,6 +16,10 @@ limitations under the License.
package unstructpath
import (
p "k8s.io/kubectl/pkg/framework/predicates"
)
// NumberS is a "number selector". It selects values as numbers (if
// possible) and filters those numbers based on the "filtered"
// predicates.
@ -23,7 +27,7 @@ type NumberS interface {
// NumberS can be used as a Value predicate. If the selector can't
// select any number from the value, then the predicate is
// false.
ValueP
p.Value
// SelectFrom finds numbers from values using this selector. The
// list can be bigger or smaller than the initial lists,
@ -32,7 +36,7 @@ type NumberS interface {
// Filter will create a new NumberS that filters only the values
// who match the predicate.
Filter(...NumberP) NumberS
Filter(...p.Number) NumberS
}
// Number returns a NumberS that selects numbers from given values.
@ -42,7 +46,7 @@ func Number() NumberS {
type numberS struct {
vs ValueS
ip NumberP
ip p.Number
}
func (s *numberS) SelectFrom(values ...interface{}) []float64 {
@ -63,13 +67,13 @@ func (s *numberS) SelectFrom(values ...interface{}) []float64 {
return numbers
}
func (s *numberS) Filter(predicates ...NumberP) NumberS {
func (s *numberS) Filter(predicates ...p.Number) NumberS {
if s.ip != nil {
predicates = append(predicates, s.ip)
}
return &numberS{
vs: s.vs,
ip: NumberAnd(predicates...),
ip: p.NumberAnd(predicates...),
}
}

View File

@ -20,6 +20,7 @@ import (
"reflect"
"testing"
p "k8s.io/kubectl/pkg/framework/predicates"
. "k8s.io/kubectl/pkg/framework/unstructpath"
)
@ -37,7 +38,7 @@ func TestNumberSSelectFrom(t *testing.T) {
func TestNumberSFilter(t *testing.T) {
s := Number().
Filter(NumberGreaterThan(2), NumberEqualOrLessThan(4)).
Filter(p.NumberGreaterThan(2), p.NumberEqualOrLessThan(4)).
SelectFrom(
1.,
2.,
@ -51,19 +52,19 @@ func TestNumberSFilter(t *testing.T) {
}
func TestNumberSPredicate(t *testing.T) {
if !Number().Filter(NumberGreaterThan(10)).Match(12.) {
if !Number().Filter(p.NumberGreaterThan(10)).Match(12.) {
t.Fatal("SelectFromor matching element should match")
}
if Number().Filter(NumberGreaterThan(10)).Match(4.) {
if Number().Filter(p.NumberGreaterThan(10)).Match(4.) {
t.Fatal("SelectFromor not matching element should not match")
}
}
func TestNumberSFromValueS(t *testing.T) {
if !Children().Number().Filter(NumberGreaterThan(10)).Match([]interface{}{1., 2., 5., 12.}) {
if !Children().Number().Filter(p.NumberGreaterThan(10)).Match([]interface{}{1., 2., 5., 12.}) {
t.Fatal("SelectFromor should find element that match")
}
if Children().Number().Filter(NumberGreaterThan(10)).Match([]interface{}{1., 2., 5.}) {
if Children().Number().Filter(p.NumberGreaterThan(10)).Match([]interface{}{1., 2., 5.}) {
t.Fatal("SelectFromor shouldn't find element that match")
}
}

View File

@ -16,6 +16,10 @@ limitations under the License.
package unstructpath
import (
p "k8s.io/kubectl/pkg/framework/predicates"
)
func filterSlice(ss SliceS, sf sliceFilter) ValueS {
return &valueS{
vf: &valueSliceFilter{
@ -31,7 +35,7 @@ type sliceFilter interface {
}
type sliceAtPFilter struct {
ip NumberP
ip p.Number
}
func (f sliceAtPFilter) SelectFrom(slices ...[]interface{}) []interface{} {

View File

@ -16,6 +16,10 @@ limitations under the License.
package unstructpath
import (
p "k8s.io/kubectl/pkg/framework/predicates"
)
// SliceS is a "slice selector". It selects values as slices (if
// possible) and filters those slices based on the "filtered"
// predicates.
@ -23,7 +27,7 @@ type SliceS interface {
// SliceS can be used as a Value predicate. If the selector
// can't select any slice from the value, then the predicate is
// false.
ValueP
p.Value
// SelectFrom finds slices from values using this selector. The
// list can be bigger or smaller than the initial lists,
@ -37,7 +41,7 @@ type SliceS interface {
// AtP returns a selector that selects all the item whose index
// matches the number predicate. More predicates can be given,
// they are "and"-ed by this method.
AtP(ips ...NumberP) ValueS
AtP(ips ...p.Number) ValueS
// Last returns a selector that selects the last value of the
// list. If the list is empty, then nothing will be selected.
Last() ValueS
@ -51,7 +55,7 @@ type SliceS interface {
// Filter will create a new SliceS that filters only the values
// who match the predicate.
Filter(...SliceP) SliceS
Filter(...p.Slice) SliceS
}
// Slice creates a selector that takes values and filters them into
@ -62,7 +66,7 @@ func Slice() SliceS {
type sliceS struct {
vs ValueS
sp SliceP
sp p.Slice
}
func (s *sliceS) SelectFrom(values ...interface{}) [][]interface{} {
@ -86,11 +90,11 @@ func (s *sliceS) SelectFrom(values ...interface{}) [][]interface{} {
}
func (s *sliceS) At(index int) ValueS {
return s.AtP(NumberEqual(float64(index)))
return s.AtP(p.NumberEqual(float64(index)))
}
func (s *sliceS) AtP(predicates ...NumberP) ValueS {
return filterSlice(s, sliceAtPFilter{ip: NumberAnd(predicates...)})
func (s *sliceS) AtP(predicates ...p.Number) ValueS {
return filterSlice(s, sliceAtPFilter{ip: p.NumberAnd(predicates...)})
}
func (s *sliceS) Last() ValueS {
@ -106,8 +110,8 @@ func (s *sliceS) All() ValueS {
return filterSlice(s, sliceAllFilter{})
}
func (s *sliceS) Filter(sps ...SliceP) SliceS {
return &sliceS{vs: s.vs, sp: SliceAnd(append(sps, s.sp)...)}
func (s *sliceS) Filter(sps ...p.Slice) SliceS {
return &sliceS{vs: s.vs, sp: p.SliceAnd(append(sps, s.sp)...)}
}
func (s *sliceS) Match(value interface{}) bool {

View File

@ -16,6 +16,10 @@ limitations under the License.
package unstructpath
import (
p "k8s.io/kubectl/pkg/framework/predicates"
)
// StringS is a "string selector". It selects values as strings (if
// possible) and filters those strings based on the "filtered"
// predicates.
@ -23,7 +27,7 @@ type StringS interface {
// StringS can be used as a Value predicate. If the selector can't
// select any string from the value, then the predicate is
// false.
ValueP
p.Value
// SelectFrom finds strings from values using this selector. The
// list can be bigger or smaller than the initial lists,
@ -32,12 +36,12 @@ type StringS interface {
// Filter will create a new StringS that filters only the values
// who match the predicate.
Filter(...StringP) StringS
Filter(...p.String) StringS
}
type stringS struct {
vs ValueS
sp StringP
sp p.String
}
// String returns a StringS that selects strings from values.
@ -63,13 +67,13 @@ func (s *stringS) SelectFrom(values ...interface{}) []string {
return strings
}
func (s *stringS) Filter(predicates ...StringP) StringS {
func (s *stringS) Filter(predicates ...p.String) StringS {
if s.sp != nil {
predicates = append(predicates, s.sp)
}
return &stringS{
vs: s.vs,
sp: StringAnd(predicates...),
sp: p.StringAnd(predicates...),
}
}

View File

@ -20,6 +20,7 @@ import (
"reflect"
"testing"
p "k8s.io/kubectl/pkg/framework/predicates"
. "k8s.io/kubectl/pkg/framework/unstructpath"
)
@ -37,7 +38,7 @@ func TestStringSSelectFrom(t *testing.T) {
func TestStringSFilter(t *testing.T) {
s := String().
Filter(StringLength(NumberEqual(4))).
Filter(p.StringLength(p.NumberEqual(4))).
SelectFrom(
"one",
"two",
@ -51,19 +52,19 @@ func TestStringSFilter(t *testing.T) {
}
func TestStringSPredicate(t *testing.T) {
if !String().Filter(StringLength(NumberEqual(4))).Match("four") {
if !String().Filter(p.StringLength(p.NumberEqual(4))).Match("four") {
t.Fatal("SelectFromor matching element should match")
}
if String().Filter(StringLength(NumberEqual(10))).Match("four") {
if String().Filter(p.StringLength(p.NumberEqual(10))).Match("four") {
t.Fatal("SelectFromor not matching element should not match")
}
}
func TestStringSFromValueS(t *testing.T) {
if !Children().String().Filter(StringLength(NumberEqual(4))).Match([]interface{}{"four", "five"}) {
if !Children().String().Filter(p.StringLength(p.NumberEqual(4))).Match([]interface{}{"four", "five"}) {
t.Fatal("SelectFromor should find element that match")
}
if Children().String().Filter(StringLength(NumberEqual(4))).Match([]interface{}{"one", "two", "three"}) {
if Children().String().Filter(p.StringLength(p.NumberEqual(4))).Match([]interface{}{"one", "two", "three"}) {
t.Fatal("SelectFromor shouldn't find element that match")
}
}

View File

@ -16,6 +16,10 @@ limitations under the License.
package unstructpath
import (
p "k8s.io/kubectl/pkg/framework/predicates"
)
// A valueFilter allows us to chain ValueS to ValueS. None of this is
// public. It's implementing the "SelectFrom" part of a ValueS.
type valueFilter interface {
@ -24,7 +28,7 @@ type valueFilter interface {
// valueFilterP filters using a predicate.
type valueFilterP struct {
vp ValueP
vp p.Value
}
func (f *valueFilterP) SelectFrom(values ...interface{}) []interface{} {

View File

@ -16,13 +16,17 @@ limitations under the License.
package unstructpath
import (
p "k8s.io/kubectl/pkg/framework/predicates"
)
// ValueS is a "value selector". It filters values based on the
// "filtered" predicates.
type ValueS interface {
// ValueS can be used as a Value predicate. If the selector can't
// select any value from the value, then the predicate is
// false.
ValueP
p.Value
// SelectFrom finds values from values using this selector. The
// list can be bigger or smaller than the initial lists,
@ -49,7 +53,7 @@ type ValueS interface {
// Filter will create a new StringS that filters only the values
// who match the predicate.
Filter(...ValueP) ValueS
Filter(...p.Value) ValueS
}
// Children selects all the children of the values.
@ -63,8 +67,8 @@ func All() ValueS {
}
// Filter will only return the values that match the predicate.
func Filter(predicates ...ValueP) ValueS {
return &valueS{vf: &valueFilterP{vp: ValueAnd(predicates...)}}
func Filter(predicates ...p.Value) ValueS {
return &valueS{vf: &valueFilterP{vp: p.ValueAnd(predicates...)}}
}
// ValueS is a "Value SelectFromor". It selects a list of values, maps,
@ -111,6 +115,6 @@ func (s *valueS) All() ValueS {
return &valueS{vs: s, vf: valueAllFilter{}}
}
func (s *valueS) Filter(predicates ...ValueP) ValueS {
return &valueS{vs: s, vf: &valueFilterP{vp: ValueAnd(predicates...)}}
func (s *valueS) Filter(predicates ...p.Value) ValueS {
return &valueS{vs: s, vf: &valueFilterP{vp: p.ValueAnd(predicates...)}}
}