go-lookslike: github.com/elastic/go-lookslike Index | Examples | Files | Directories

package lookslike

import "github.com/elastic/go-lookslike"

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.

Code:

// 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()

Index

Examples

Package Files

compiled_schema.go core.go doc.go walk.go

func Compose Uses

func Compose(validators ...validator.Validator) validator.Validator

Compose combines multiple SchemaValidators into a single one.

Code:

// 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 Uses

func MustCompile(in interface{}) validator.Validator

MustCompile compiles the given validation, panic-ing if that map is invalid.

func Strict Uses

func Strict(laxValidator validator.Validator) validator.Validator

Strict is used when you want any unspecified keys that are encountered to be considered errors.

type CompiledSchema Uses

type CompiledSchema []flatValidator

CompiledSchema represents a compiled definition for driving a validator.Validator.

func (CompiledSchema) Check Uses

func (cs CompiledSchema) Check(actual interface{}) *llresult.Results

Check executes the the checks within the CompiledSchema

Directories

PathSynopsis
internal/llreflect
isdef
llpath
llresult
testslike
validator

Package lookslike imports 8 packages (graph) and is imported by 14 packages. Updated 2019-09-05. Refresh now. Tools for package owners.