matchers: always check the type of new matcher assignments.

* lib/specl/matchers.lua (matchers): Store the actual matcher
functions in a `contents` subtable so that `__newindex` doesn't
ignore reassignments to an existing entry!
(matchers:__index): Automatically reference the contents
subtable.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
matchers: support custom adaptors.

Declare adaptor functions as regular Object fields so they can
be added to and overridden during object cloning.  This requires
dynamic run-time adaptor lookup during expectations:
* specs/matchers_spec.yaml: Specify behaviour of the custom
adaptor API.
* lib/specl/matchers.lua (matchers): In addition to type-
checking assignments to the matchers table, also inject a
new `name` field in the assigned Matcher object.
 (Matcher:_init): First element of a new Matcher object
instantiation is always the matcher predicate. Save that into
the `matchp` field of the newly instantiated Matcher object.
Adjust all callers.
(Matcher["match?"], Matcher["all_of?"], Matcher["any_of?"]):
Instead of assigning these dynamically from _init during
instantiation...
(Matcher:match, Matcher["all_of?"], Matcher["any_of?"]):
...assign immediately in the prototype Matcher.  Strip the
trailing question mark from the match method, as that is now
used to signify an adaptor method.
(matchers): Automatically assign the name field so that methods
can fetch it easily with `self.name`.
(expect): Adjust to new calling conventions above.
Also, instead of hard-coding the adaptor scoring functions in
the returned functable, look them up dynamically in the Matcher
object fields in the __newindex metamethod by appending a "?"
to the adaptor name.
* docs/specl.md (Custom Adaptors): New documentation section.
* NEWS: Update.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
specs: improve long form summary sentences.

* specs/matchers_spec.yaml: Adjust descriptions slightly so that
long form summaries read better. "matchers be matcher displays
expected and actual output for failures" becomes "matcher be
displays expected and actual output for failures".

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
docs: fix a typo in specl.md.

* docs/specl.md: Replace 'succed' with 'succeed'.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
std: add string support to totable function.

* lib/specl/std.lua (totable): When passed a string, return a
table of each character in the string.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
util: check for type table before using # operator.

* lib/specl/util.lua (type_check): Don't apply # operator until
after we've checked that the operand is a table.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
util: simplify type_error implementation.

* lib/specl/util.lua (type_error): convert single types to a
typelist, then use util.concat unconditionally.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
matchers: fix comment typo.

* lib/specl/matchers.lua (reformat): Replace 'previded' with
'provided'.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
matchers: differentiate between primitive tables and objects.

* specs/matchers_spec (contain): Specify display of object
type name in failure reports.
* lib/specl/util.lua (xtype): New function that always returns
"object" for std.objects.
(M): Export xtype as util.type.
* lib/specl/matchers.lua (contain): Simplify with util.type.
(contain:format_actual, contain:format_alternatives): Likewise.
(contain:format_expect): Display object name for std.objects.
* NEWS: Update.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
matchers: use aliases for util functions.

* lib/specl/matchers.lua: Alias util.prettytostring and
util.table to prettytostring and table.
(objcmp, matchers.contain, matchers.contain:format_actual):
Simplify with aliases.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
std: implement std.table.empty and std.table.size.

* lib/specl/std.lua (empty, size): Copied from upstream stdlib.
(std.table): Export them.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
matchers: new contain.a_permutation_of adaptor.

* specs/matchers_spec.yaml: Specify expected behaviour of a new
adaptor.
* lib/specl/matchers.lua (Object, prettytostring, totable):
Alias directly from specl.std, to save reexporting functions
through specl.util all the time.
(clone, empty, size): Alias these too.
(concat): Use " and " as the final element separator when
concatenating a_permutation_of arguments.
(matchers.container.format_alternatives): Format strings
correctly when called by a_permutation_of.
(matchers.container:a_permutation_of?): New adaptor.
* docs/specl.md (Unordered matching with a_permutation_of):
Document it.
* TODO.yaml: Some new TODO items.
* NEWS: Update.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
specl: preload sources, and prefer preloaded from env.require.

On my machine this gets me about a 5% speedup in a large set
of specfiles, but I have an SSD which makes opening sources
every time they are loaded seem fast - on an io-bound machine
this should show an even greater speedup.
* local.mk (bin/specl): When generating this file, preload the
library sources with verbatim function initialisers.
* lib/specl.lua (env.require): Prefer preloaded modules, rather
than a full blown manual file slurp and loadstring().
And, excepting "spec_helper" and temporary lua_xxxxxx files, add
the result of loadstring to package.preload to speed up subsequent
loads.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
refactor: don't reexport specl.std functions from specl.util.

* lib/spec/util.lua (M.champ, M.escape_pattern, M.merge)
(M.Object, M.prettytostring, M.process_files, M.slurp)
(M.tostring, M.totable): Remove.
* lib/specl/matchers.lua, lib/specl/shell.lua,
specs/spec_helper.lua: Adjust. Require specl/std.lua into a
local table, and access functions directly.
* specs/custom_formatters_spec.yaml (context with an accumulator):
Set local tostring directly from specl/std.lua.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
refactor: use LuaMacro to support 'from table import <fieldlist>'.

* lib/larch/from.lua: New file. Implements 'from' syntax as a
LuaMacro macro.
* configure.ac (LUAM): Search for a working luam program.
* local.mk (LUAM_ENV): Add location of from.lua to LUA_PATH.
(LUAM_OPTS): Load from macro, and then dump macro-expanded
source.
(bin/specl): Expand macros in preloaded sources.
* lib/specl/formatter/progress.lua,
lib/specl/formatter/report.lua, lib/specl/formatter/tap.lua,
lib/specl/matchers.lua, lib/specl/shell.lua,
lib/specl/util.lua: Use 'from' to simplify alias creation.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
loader: only trigger expect macro expansion with arguments.

* lib/specl/loader.lua (expect): Use a getter function for the
body of this macro, that only triggers expansion if the 'expect'
token is followed by a parenthesized argument.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>
refactor: remove '_expect' references.

* lib/specl/loader.lua (expect): Instead of expanding literal
expect to an '_expect' reference, pass-through the 'expect'
token even when a function is recognized.
* lib/specl.lua (run_examples, M): Remove '_expect' references.

Signed-off-by: Gary V. Vaughan <gary@gnu.org>