Documentation
¶
Overview ¶
Package sham generates pseudorandom data from a supplied schema written in the Sham language.
Index ¶
- Variables
- func Generate(schema []byte) (interface{}, error)
- type Array
- type FormattedString
- type Generator
- type GeneratorFunc
- type KV
- type Literal
- type Node
- type Object
- type OrderedMap
- type Parser
- type QuoteType
- type Range
- type Regex
- type Scanner
- type Schema
- type TerminalGenerator
- type Token
- type TokenType
Constants ¶
This section is empty.
Variables ¶
var TerminalGenerators = map[string]Generator{ "name": GeneratorFunc(stringAdaptor(gen.Name)), "firstName": GeneratorFunc(stringAdaptor(gen.FirstName)), "lastName": GeneratorFunc(stringAdaptor(gen.LastName)), "phoneNumber": GeneratorFunc(stringAdaptor(gen.PhoneNumber)), "timestamp": GeneratorFunc(timeAdaptor(gen.Timestamp)), }
TerminalGenerators is the standard collection of terminal generators provided by Sham.
Functions ¶
func Generate ¶
Generate parses a Sham schema, and on success, performs a single generation of data using the default terminal generators. This function is intended to be a simple wrapper for the Sham data generation process. If multiple generations are required, or custom terminal generators are needed, then a parser should be instantiated with NewParser. After successfully parsing, the resulting Schema object can be used to generate data multiple times without parsing the schema.
Types ¶
type Array ¶
Array represents a list of values that can be generated. An array has two potential parts: an inner node and a range. The inner node defines the structure of the array elements, and the range defines how many elements should be present. The range is optional. If omitted, one element will be generated.
func (Array) Generate ¶
func (a Array) Generate() interface{}
Generate creates a slice of generated values where each value is defined by the inner node field. If the range is omitted, then exactly one element will populate the array. Otherwise, a random number of elements will be generated based on the inclusive range of integers.
type FormattedString ¶
FormattedString represents a string literal with values that can be interpolated into the string. In the Sham language, formatted strings are enclosed in backticks, and the interpolated values are enclosed by curly braces. Interpolated values must be valid, registered terminal generators.
func (FormattedString) Generate ¶
func (f FormattedString) Generate() interface{}
Generate produces a string literal value by replacing interpolated values with the values generated by the corresponding terminal generator.
type Generator ¶
type Generator interface {
Generate() interface{}
}
Generator represents the core functionality behind Sham's data generation. Any type that implements this interface can be used to generate data. Implementors can be either data structures containing more data, or simpler functions that directly generate a sinlge piece of data. These latter objects are referred to as terminal generators since they are generally found as leaves in the AST.
type GeneratorFunc ¶
type GeneratorFunc func() interface{}
GeneratorFunc is a simple function type that implements the Generator interface. This type can be used to provide single functions as Generators.
func (GeneratorFunc) Generate ¶
func (f GeneratorFunc) Generate() interface{}
type Literal ¶
type Literal struct {
Value interface{}
}
Literal represents a literal value. No data generation is involved here, but rather values are returned as-is.
type Node ¶
type Node interface { Generator }
Node represents a single element in the abstract syntax tree. A valid Sham AST must be able to generate data. As such, every node in tree must be implement the Generator interface. There are two main type of nodes: structural and terminal. Terminal nodes are leaves that generate values. Structural nodes generate the data structures that hold these values.
type Object ¶
type Object struct {
Values []KV
}
Object represents a key-value data structure. In order to maintain the key order in the schema, the pairs are stored in a slice and converted to an ordered map during the generation process. If a key is provided multiple times, the last value will be used during generation.
func (*Object) AppendPair ¶
AppendPair adds a key-value pair to an Object.
type OrderedMap ¶
func NewOrderedMap ¶
func NewOrderedMap() *OrderedMap
func (*OrderedMap) MarshalJSON ¶
func (m *OrderedMap) MarshalJSON() ([]byte, error)
func (*OrderedMap) MarshalXML ¶
func (m *OrderedMap) MarshalXML(e *xml.Encoder, start xml.StartElement) error
func (*OrderedMap) Set ¶
func (m *OrderedMap) Set(k string, v interface{})
type Parser ¶
type Parser struct { TerminalGenerators map[string]Generator // contains filtered or unexported fields }
Parser maintains the internal state of the language parser. This struct takes a slice of tokens as input and produces an AST if and only if the token stream represents a valid Sham schema. Part of the internal state is the terminalGenerator map. This map of terminal generators must be set prior to the initiating the parsing method. If a terminal generator is referenced in the schema, but not defined in the terminal generator map, then the parsing process will be halted with an error.
To ensure the parser begins with the proper state, one of the constructor functions should be used.
func NewDefaultParser ¶
NewDefaultParser creates a new Parser instance using the default terminal generators map.
func (*Parser) Parse ¶
Parse generates a new AST from the schema provided to the parser. The parser combines multiple steps to generate this structure. The schema is first tokenized. If an invalid token is presented (either an unknown character or an unterminated sequence), then a scanning error will be returned. Upon success, the slice of tokens will be parsed. If the tokens are representative of a valid Sham schema, then an AST will be returned. Otherwise and error will be returned.
func (*Parser) RegisterGenerators ¶
RegisterGenerators merges a terminal generator map into the parser's internal terminal generator map. If a generator is already registered, then the existing generator will be overwritten with the new. To avoid parsing errors, all terminal generators should be registered prior to parsing.
type Range ¶
Range is an inclusive range of integers. Ranges have two uses within the a Sham schema. If provided as the first argument in an array, the range will be used to determine the number of elements to populate the array. If provided in the position of a terminal generator, then a random integer will be generated for the value.
type Regex ¶
type Regex struct { Pattern string // contains filtered or unexported fields }
Regex holds a compiled regex. While any valid regular expression can be provided, only a subset will actually generate data. Every node in a parsed regex leads to a possible choice. During data generation, a random path through the parsed expression is taken. Therefore, a complciated expression has the potential to lead to wildly different performance on repeated generations.
TODO: fully document nodes that can generate data
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner maintains of the state of the tokenization process. This scanner maintains an internal buffer to minimize allocations as the Scanner reads through the source.
func NewScanner ¶
NewScanner initializes a Scanner with the provided schema.
func (*Scanner) Scan ¶
Scan consumes characters in the source until a full token is determined. An error will never occur while scanning. Instead, TokInvalid will be returned if a token cannot be created.
Whitespace is not important in the Sham language. If whitespace is encountered outside of string literals or regular expressions, then it will be aggregated into a single TokWS token.
type Schema ¶
type Schema struct {
Root Node
}
Schema represents a Sham schema and holds the root of the AST. The root of the AST must either be a single terminal node, or a structural node.
func (Schema) Generate ¶
func (s Schema) Generate() interface{}
Generate triggers the Sham data generation process. The generation process begins with the root and walks the tree, generating data structures and data as it goes. Data generation cannot cause errors. Any possible errors will have been caught during the tokenization and parsing processes. This method can be called more than once to generate more data using the same schema.
type TerminalGenerator ¶
type TerminalGenerator struct { Name string // contains filtered or unexported fields }
TerminalGenerator represents a function that can generate data.
func (TerminalGenerator) Generate ¶
func (t TerminalGenerator) Generate() interface{}
Generate runs the terminal generator's generation function. The generator is expected to be a non nil interface. If nil was registered for this terminal generator, then this method will panic.