feat: add StopOnFailureFilter for meta.Collection

This commit is contained in:
z7zmey 2018-12-10 11:51:56 +02:00
parent d155c563ef
commit dbdedc20de
2 changed files with 212 additions and 24 deletions

View File

@ -64,18 +64,41 @@ func (mc *Collection) Cut(f Filter) *Collection {
type Filter func(d *Data) bool type Filter func(d *Data) bool
// TokenNameFilter generates filter function that returns true // TokenNameFilter generates filter function that returns true
// if data.TokenName exactly same as given // if data.TokenName has in the arguments list
func TokenNameFilter(tn TokenName) Filter { func TokenNameFilter(tokenNames ...TokenName) Filter {
return func(d *Data) bool { return func(d *Data) bool {
return d.TokenName == tn for _, tn := range tokenNames {
if d.TokenName == tn {
return true
}
}
return false
} }
} }
// TypeFilter generates filter function that returns true // TypeFilter generates filter function that returns true
// if data.Type exactly same as given // if data.Type has in the arguments list
func TypeFilter(t Type) Filter { func TypeFilter(types ...Type) Filter {
return func(d *Data) bool { return func(d *Data) bool {
return d.Type == t for _, t := range types {
if d.Type == t {
return true
}
}
return false
}
}
// ValueFilter generates filter function that returns true
// if data.Value has in the arguments list
func ValueFilter(values ...string) Filter {
return func(d *Data) bool {
for _, v := range values {
if d.Value == v {
return true
}
}
return false
} }
} }
@ -113,3 +136,20 @@ func NotFilter(f Filter) Filter {
return !f(d) return !f(d)
} }
} }
// StopOnFailureFilter always returns false after first failure
func StopOnFailureFilter(f Filter) Filter {
stopFlag := false
return func(d *Data) bool {
if stopFlag == true {
return false
}
if !f(d) {
stopFlag = true
return false
}
return true
}
}

View File

@ -261,11 +261,11 @@ func TestCollectionCutByTokenName(t *testing.T) {
actualCollection := meta.Collection{whiteSpace, OpenParenthesisComment, OpenParenthesisToken, CloseParenthesisToken} actualCollection := meta.Collection{whiteSpace, OpenParenthesisComment, OpenParenthesisToken, CloseParenthesisToken}
expectedCollection := meta.Collection{whiteSpace, CloseParenthesisToken} expectedCollection := meta.Collection{whiteSpace, CloseParenthesisToken}
expectedCuttedCollection := &meta.Collection{OpenParenthesisComment, OpenParenthesisToken} expectedCutCollection := &meta.Collection{OpenParenthesisComment, OpenParenthesisToken}
// action // action
actualCuttedCollection := actualCollection.Cut( actualCutCollection := actualCollection.Cut(
meta.TokenNameFilter(meta.OpenParenthesisToken), meta.TokenNameFilter(meta.OpenParenthesisToken),
) )
@ -281,13 +281,13 @@ func TestCollectionCutByTokenName(t *testing.T) {
} }
} }
if !reflect.DeepEqual(expectedCuttedCollection, actualCuttedCollection) { if !reflect.DeepEqual(expectedCutCollection, actualCutCollection) {
diff := pretty.Compare(expectedCuttedCollection, actualCuttedCollection) diff := pretty.Compare(expectedCutCollection, actualCutCollection)
if diff != "" { if diff != "" {
t.Errorf("\nexpected and actual cutted collections are not equal\ndiff: (-expected +actual)\n%s", diff) t.Errorf("\nexpected and actual Cut collections are not equal\ndiff: (-expected +actual)\n%s", diff)
} else { } else {
t.Errorf("\nexpected and actual cutted collections are not equal\n") t.Errorf("\nexpected and actual Cut collections are not equal\n")
} }
} }
} }
@ -319,11 +319,11 @@ func TestCollectionCutByTokenTypes(t *testing.T) {
actualCollection := meta.Collection{whiteSpace, OpenParenthesisComment, OpenParenthesisToken, CloseParenthesisToken} actualCollection := meta.Collection{whiteSpace, OpenParenthesisComment, OpenParenthesisToken, CloseParenthesisToken}
expectedCollection := meta.Collection{OpenParenthesisToken, CloseParenthesisToken} expectedCollection := meta.Collection{OpenParenthesisToken, CloseParenthesisToken}
expectedCuttedCollection := &meta.Collection{whiteSpace, OpenParenthesisComment} expectedCutCollection := &meta.Collection{whiteSpace, OpenParenthesisComment}
// action // action
actualCuttedCollection := actualCollection.Cut(meta.OrFilter( actualCutCollection := actualCollection.Cut(meta.OrFilter(
meta.TypeFilter(meta.CommentType), meta.TypeFilter(meta.CommentType),
meta.TypeFilter(meta.WhiteSpaceType)), meta.TypeFilter(meta.WhiteSpaceType)),
) )
@ -340,13 +340,13 @@ func TestCollectionCutByTokenTypes(t *testing.T) {
} }
} }
if !reflect.DeepEqual(expectedCuttedCollection, actualCuttedCollection) { if !reflect.DeepEqual(expectedCutCollection, actualCutCollection) {
diff := pretty.Compare(expectedCuttedCollection, actualCuttedCollection) diff := pretty.Compare(expectedCutCollection, actualCutCollection)
if diff != "" { if diff != "" {
t.Errorf("\nexpected and actual cutted collections are not equal\ndiff: (-expected +actual)\n%s", diff) t.Errorf("\nexpected and actual Cut collections are not equal\ndiff: (-expected +actual)\n%s", diff)
} else { } else {
t.Errorf("\nexpected and actual cutted collections are not equal\n") t.Errorf("\nexpected and actual Cut collections are not equal\n")
} }
} }
} }
@ -387,13 +387,13 @@ func TestCollectionCutByTokenNameButNotType(t *testing.T) {
OpenParenthesisToken, OpenParenthesisToken,
CloseParenthesisToken, CloseParenthesisToken,
} }
expectedCuttedCollection := &meta.Collection{ expectedCutCollection := &meta.Collection{
OpenParenthesisComment, OpenParenthesisComment,
} }
// action // action
actualCuttedCollection := actualCollection.Cut(meta.AndFilter( actualCutCollection := actualCollection.Cut(meta.AndFilter(
meta.TokenNameFilter(meta.OpenParenthesisToken), meta.TokenNameFilter(meta.OpenParenthesisToken),
meta.NotFilter(meta.TypeFilter(meta.TokenType))), meta.NotFilter(meta.TypeFilter(meta.TokenType))),
) )
@ -410,13 +410,161 @@ func TestCollectionCutByTokenNameButNotType(t *testing.T) {
} }
} }
if !reflect.DeepEqual(expectedCuttedCollection, actualCuttedCollection) { if !reflect.DeepEqual(expectedCutCollection, actualCutCollection) {
diff := pretty.Compare(expectedCuttedCollection, actualCuttedCollection) diff := pretty.Compare(expectedCutCollection, actualCutCollection)
if diff != "" { if diff != "" {
t.Errorf("\nexpected and actual cutted collections are not equal\ndiff: (-expected +actual)\n%s", diff) t.Errorf("\nexpected and actual Cut collections are not equal\ndiff: (-expected +actual)\n%s", diff)
} else { } else {
t.Errorf("\nexpected and actual cutted collections are not equal\n") t.Errorf("\nexpected and actual Cut collections are not equal\n")
}
}
}
func TestCollectionCutByValue(t *testing.T) {
// prepare
whiteSpace := &meta.Data{
Type: meta.WhiteSpaceType,
Value: "\n",
}
OpenParenthesisComment := &meta.Data{
Type: meta.CommentType,
Value: "// some comment",
TokenName: meta.OpenParenthesisToken,
}
OpenParenthesisToken := &meta.Data{
Type: meta.TokenType,
Value: "(",
TokenName: meta.OpenParenthesisToken,
}
CloseParenthesisToken := &meta.Data{
Type: meta.TokenType,
Value: ")",
TokenName: meta.CloseParenthesisToken,
}
actualCollection := meta.Collection{
whiteSpace,
OpenParenthesisComment,
OpenParenthesisToken,
CloseParenthesisToken,
}
expectedCollection := meta.Collection{
whiteSpace,
OpenParenthesisComment,
}
expectedCutCollection := &meta.Collection{
OpenParenthesisToken,
CloseParenthesisToken,
}
// action
actualCutCollection := actualCollection.Cut(meta.ValueFilter("(", ")"))
// check
if !reflect.DeepEqual(expectedCollection, actualCollection) {
diff := pretty.Compare(expectedCollection, actualCollection)
if diff != "" {
t.Errorf("\nexpected and actual collections are not equal\ndiff: (-expected +actual)\n%s", diff)
} else {
t.Errorf("\nexpected and actual collections are not equal\n")
}
}
if !reflect.DeepEqual(expectedCutCollection, actualCutCollection) {
diff := pretty.Compare(expectedCutCollection, actualCutCollection)
if diff != "" {
t.Errorf("\nexpected and actual Cut collections are not equal\ndiff: (-expected +actual)\n%s", diff)
} else {
t.Errorf("\nexpected and actual Cut collections are not equal\n")
}
}
}
func TestCollectionCutUntilFirstToken(t *testing.T) {
// prepare
whiteSpace := &meta.Data{
Type: meta.WhiteSpaceType,
Value: "\n",
TokenName: meta.NodeStart,
}
OpenParenthesisComment := &meta.Data{
Type: meta.CommentType,
Value: "// some comment",
TokenName: meta.NodeStart,
}
OpenParenthesisToken := &meta.Data{
Type: meta.TokenType,
Value: "(",
TokenName: meta.OpenParenthesisToken,
}
CloseParenthesisComment := &meta.Data{
Type: meta.WhiteSpaceType,
Value: "// some comment",
TokenName: meta.OpenParenthesisToken,
}
CloseParenthesisToken := &meta.Data{
Type: meta.TokenType,
Value: ")",
TokenName: meta.CloseParenthesisToken,
}
actualCollection := meta.Collection{
whiteSpace,
OpenParenthesisComment,
OpenParenthesisToken,
CloseParenthesisComment,
CloseParenthesisToken,
}
expectedCutCollection := &meta.Collection{
whiteSpace,
OpenParenthesisComment,
}
expectedCollection := meta.Collection{
OpenParenthesisToken,
CloseParenthesisComment, // must not be cut
CloseParenthesisToken,
}
// action
actualCutCollection := actualCollection.Cut(
meta.StopOnFailureFilter(
meta.NotFilter(
meta.TypeFilter(meta.TokenType),
),
),
)
// check
if !reflect.DeepEqual(expectedCollection, actualCollection) {
diff := pretty.Compare(expectedCollection, actualCollection)
if diff != "" {
t.Errorf("\nexpected and actual collections are not equal\ndiff: (-expected +actual)\n%s", diff)
} else {
t.Errorf("\nexpected and actual collections are not equal\n")
}
}
if !reflect.DeepEqual(expectedCutCollection, actualCutCollection) {
diff := pretty.Compare(expectedCutCollection, actualCutCollection)
if diff != "" {
t.Errorf("\nexpected and actual Cut collections are not equal\ndiff: (-expected +actual)\n%s", diff)
} else {
t.Errorf("\nexpected and actual Cut collections are not equal\n")
} }
} }
} }