Documentation ¶
Overview ¶
Package lookslike is used to validate JSON-like nested map data-structure against a set of expectations. Its key features are allowing custom, function defined validators for values, and allowing the composition of multiple validation specs.
See the example below for more details. Most key functions include detailed examples of their use within this documentation.
Example ¶
// Let's say we want to validate this map data := map[string]interface{}{"foo": "bar", "baz": "bot", "count": 1} // We can validate the data by creating a lookslike.Validator // validator.Validators are functions created by compiling the special lookslike.map[string]interface{} // type. This is a map[string]interface{} that can be compiled // into a series of checks. // // We can validate the data by defining a validator for this data. //Lookslike has powerful matching features for maps and slices especially. // You can see an example validator below: validator := MustCompile(map[string]interface{}{ "foo": isdef.IsStringContaining("a"), "baz": "bot", }) // When being used in test-suites, you should use testslike.Test to execute the validator // This produces easy to read test output, and outputs one failed assertion per failed matcher // See the docs for testslike for more info. // testslike.Test(t, validator, data) // If you need more control than testslike.Test provides, you can use the results directly results := validator(data) // The Results.Valid property indicates if the validator passed fmt.Printf("Results.Valid: %t\n", results.Valid) // Results.Errors() returns one error per failed match fmt.Printf("There were %d errors\n", len(results.Errors())) // Results.Fields is a map of paths defined in the input map[string]interface{} to the result of their validation // This is useful if you need more control fmt.Printf("Over %d fields\n", len(results.Fields)) // You may be thinking that the validation above should have failed since there was an // extra key, 'count', defined that was encountered. By default lookslike does not // consider extra data to be an error. To change that behavior, wrap the validator // in lookslike.Strict() strictResults := Strict(validator)(data) fmt.Printf("Strict Results.Valid: %t\n", strictResults.Valid) // You can Check an exact field for an error fmt.Printf("For the count field specifically .Valid is: %t\n", strictResults.Fields["count"][0].Valid) // And get error objects for each error for _, err := range strictResults.Errors() { fmt.Println(err) } // And even get a new Results object with only invalid fields included strictResults.DetailedErrors()
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Compose ¶
Compose combines multiple SchemaValidators into a single one.
Example ¶
// Composition is useful when you need to share common validation logic between validators. // Let's imagine that we want to validate maps describing pets. pets := []map[string]interface{}{ {"Name": "rover", "barks": "often", "fur_length": "long"}, {"Name": "lucky", "barks": "rarely", "fur_length": "short"}, {"Name": "pounce", "meows": "often", "fur_length": "short"}, {"Name": "peanut", "meows": "rarely", "fur_length": "long"}, } // We can see that all pets have the "fur_length" property, but that only cats meow, and dogs bark. // We can concisely encode this in lookslike using lookslike.Compose. // We can also see that both "meows" and "barks" contain the same enums of values. // We'll start by creating a composed IsDef using the IsAny composition, which creates a new IsDef that is // a logical 'or' of its IsDef arguments isFrequency := isdef.IsAny(isdef.IsEqual("often"), isdef.IsEqual("rarely")) petValidator := MustCompile(map[string]interface{}{ "Name": isdef.IsNonEmptyString, "fur_length": isdef.IsAny(isdef.IsEqual("long"), isdef.IsEqual("short")), }) dogValidator := Compose( petValidator, MustCompile(map[string]interface{}{"barks": isFrequency}), ) catValidator := Compose( petValidator, MustCompile(map[string]interface{}{"meows": isFrequency}), ) for _, pet := range pets { var petType string if dogValidator(pet).Valid { petType = "dog" } else if catValidator(pet).Valid { petType = "cat" } fmt.Printf("%s is a %s\n", pet["Name"], petType) }
Output: rover is a dog lucky is a dog pounce is a cat peanut is a cat
func MustCompile ¶
MustCompile compiles the given validation, panic-ing if that map is invalid.
Types ¶
type CompiledSchema ¶
type CompiledSchema []flatValidator
CompiledSchema represents a compiled definition for driving a validator.Validator.
func (CompiledSchema) Check ¶
func (cs CompiledSchema) Check(actual interface{}) *llresult.Results
Check executes the the checks within the CompiledSchema
Click to show internal directories.
Click to hide internal directories.