2023-06-03 07:12:31 +02:00
package components
import (
"fmt"
"regexp"
"strings"
"github.com/samber/lo"
)
type TextMatcher struct {
* Matcher [ string ]
}
func ( self * TextMatcher ) Contains ( target string ) * TextMatcher {
self . appendRule ( matcherRule [ string ] {
name : fmt . Sprintf ( "contains '%s'" , target ) ,
testFn : func ( value string ) ( bool , string ) {
// everything contains the empty string so we unconditionally return true here
if target == "" {
return true , ""
}
return strings . Contains ( value , target ) , fmt . Sprintf ( "Expected '%s' to be found in '%s'" , target , value )
} ,
} )
return self
}
func ( self * TextMatcher ) DoesNotContain ( target string ) * TextMatcher {
self . appendRule ( matcherRule [ string ] {
name : fmt . Sprintf ( "does not contain '%s'" , target ) ,
testFn : func ( value string ) ( bool , string ) {
return ! strings . Contains ( value , target ) , fmt . Sprintf ( "Expected '%s' to NOT be found in '%s'" , target , value )
} ,
} )
return self
}
2023-08-15 16:31:50 +02:00
func ( self * TextMatcher ) DoesNotContainAnyOf ( targets [ ] string ) * TextMatcher {
self . appendRule ( matcherRule [ string ] {
name : fmt . Sprintf ( "does not contain any of '%s'" , targets ) ,
testFn : func ( value string ) ( bool , string ) {
return lo . NoneBy ( targets , func ( target string ) bool { return strings . Contains ( value , target ) } ) ,
fmt . Sprintf ( "Expected none of '%s' to be found in '%s'" , targets , value )
} ,
} )
return self
}
2023-06-03 07:12:31 +02:00
func ( self * TextMatcher ) MatchesRegexp ( target string ) * TextMatcher {
self . appendRule ( matcherRule [ string ] {
name : fmt . Sprintf ( "matches regular expression '%s'" , target ) ,
testFn : func ( value string ) ( bool , string ) {
matched , err := regexp . MatchString ( target , value )
if err != nil {
return false , fmt . Sprintf ( "Unexpected error parsing regular expression '%s': %s" , target , err . Error ( ) )
}
return matched , fmt . Sprintf ( "Expected '%s' to match regular expression /%s/" , value , target )
} ,
} )
return self
}
func ( self * TextMatcher ) Equals ( target string ) * TextMatcher {
self . appendRule ( matcherRule [ string ] {
name : fmt . Sprintf ( "equals '%s'" , target ) ,
testFn : func ( value string ) ( bool , string ) {
return target == value , fmt . Sprintf ( "Expected '%s' to equal '%s'" , value , target )
} ,
} )
return self
}
const IS_SELECTED_RULE_NAME = "is selected"
// special rule that is only to be used in the TopLines and Lines methods, as a way of
// asserting that a given line is selected.
func ( self * TextMatcher ) IsSelected ( ) * TextMatcher {
self . appendRule ( matcherRule [ string ] {
name : IS_SELECTED_RULE_NAME ,
testFn : func ( value string ) ( bool , string ) {
panic ( "Special IsSelected matcher is not supposed to have its testFn method called. This rule should only be used within the .Lines() and .TopLines() method on a ViewAsserter." )
} ,
} )
return self
}
// if the matcher has an `IsSelected` rule, it returns true, along with the matcher after that rule has been removed
func ( self * TextMatcher ) checkIsSelected ( ) ( bool , * TextMatcher ) {
// copying into a new matcher in case we want to re-use the original later
newMatcher := & TextMatcher { }
* newMatcher = * self
check := lo . ContainsBy ( newMatcher . rules , func ( rule matcherRule [ string ] ) bool { return rule . name == IS_SELECTED_RULE_NAME } )
newMatcher . rules = lo . Filter ( newMatcher . rules , func ( rule matcherRule [ string ] , _ int ) bool { return rule . name != IS_SELECTED_RULE_NAME } )
return check , newMatcher
}
// this matcher has no rules meaning it always passes the test. Use this
// when you don't care what value you're dealing with.
func AnyString ( ) * TextMatcher {
return & TextMatcher { Matcher : & Matcher [ string ] { } }
}
func Contains ( target string ) * TextMatcher {
return AnyString ( ) . Contains ( target )
}
func DoesNotContain ( target string ) * TextMatcher {
return AnyString ( ) . DoesNotContain ( target )
}
2023-08-15 16:31:50 +02:00
func DoesNotContainAnyOf ( targets ... string ) * TextMatcher {
return AnyString ( ) . DoesNotContainAnyOf ( targets )
}
2023-06-03 07:12:31 +02:00
func MatchesRegexp ( target string ) * TextMatcher {
return AnyString ( ) . MatchesRegexp ( target )
}
func Equals ( target string ) * TextMatcher {
return AnyString ( ) . Equals ( target )
}