Top | ![]() |
![]() |
![]() |
![]() |
GBoxed ├── WblGeneratedInstance ├── WblSchemaInfo ├── WblSchemaNode ╰── WblValidateMessage GObject ╰── WblSchema
WblSchema represents a single JSON schema, at the top level. This is a tree
of WblSchemaNodes, with one guaranteed to exist at the top level
(retrievable using wbl_schema_get_root()
) and others lower down representing
sub-schemas.
When loading a schema, it is validated for well-formedness and adherence to the JSON meta-schema (which defines the format used for schemas). Invalid schemas will fail to load.
Two main operations may be performed on a loaded schema: application of the schema to a JSON instance, and generation of instances from the schema. Applying a schema to an instance validates that instance against the schema, returning success or a validation error. Generating instances from a schema produces zero or more JSON instances which test various boundary conditions of the schema. They are designed to be used in testing parser implementations for that schema.
The most common usage of Walbottle is to integrate it into the unit tests for
a parser in the software under test (SUT). This is typically done with the
json-schema-generate
utility which comes with Walbottle.
To do so is straightforward if the SUT is using autotools. Add the following
to the configure.ac
file in the SUT:
1 2 3 4 5 6 7 |
AC_PATH_PROG([JSON_SCHEMA_VALIDATE],[json-schema-validate]) AC_PATH_PROG([JSON_SCHEMA_GENERATE],[json-schema-generate]) AS_IF([test "$JSON_SCHEMA_VALIDATE" = ""], [AC_MSG_ERROR([json-schema-validate not found])]) AS_IF([test "$JSON_SCHEMA_GENERATE" = ""], [AC_MSG_ERROR([json-schema-generate not found])]) |
Then add the following in the Makefile.am
for the SUT’s parser unit tests
and adjust json_schemas
to point to the schemas for the format (or formats)
accepted by the SUT’s parser:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
json_schemas = \ my-format.schema.json \ my-other-format.schema.json \ $(NULL) EXTRA_DIST += $(json_schemas) check-json-schema: $(json_schemas) $(AM_V_GEN)$(JSON_SCHEMA_VALIDATE) $^ check-local: check-json-schema .PHONY: check-json-schema json_schemas_h = $(json_schemas:.schema.json=.schema.h) BUILT_SOURCES += $(json_schemas_h) CLEANFILES += $(json_schemas_h) %.schema.h: %.schema.json $(AM_V_GEN)$(JSON_SCHEMA_GENERATE) \ --c-variable-name=$(subst -,_,$(notdir $*))_json_instances \ --format c $^ > $@ |
If using the GLib test framework, a typical way of then using the generated
test vectors in a test suite is to include the generated C file and add a
unit test for each vector. In Makefile.am:
1 2 |
my_test_suite_SOURCES = my-test-suite.c nodist_my_test_suite_SOURCES = $(json_schemas_h) |
And in the test suite code itself (my-test-suite.c
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include "my-format.schema.h" … // Test the parser with each generated test vector from the JSON schema. static void test_parser_generated (gconstpointer user_data) { guint i; GObject *parsed = NULL; GError *error = NULL; i = GPOINTER_TO_UINT (user_data); parsed = try_parsing_string (my_format_json_instances[i].json, my_format_json_instances[i].size, &error); if (my_format_json_instances[i].is_valid) { // Assert @parsed is valid. g_assert_no_error (error); g_assert (G_IS_OBJECT (parser)); } else { // Assert parsing failed. g_assert_error (error, SOME_ERROR_DOMAIN, SOME_ERROR_CODE); g_assert (parsed == NULL); } g_clear_error (&error); g_clear_object (&parsed); } … int main (int argc, char *argv[]) { guint i; … for (i = 0; i < G_N_ELEMENTS (my_format_json_instances); i++) { gchar *test_name = NULL; test_name = g_strdup_printf ("/parser/generated/%u", i); g_test_add_data_func (test_name, GUINT_TO_POINTER (i), test_parser_generated); g_free (test_name); } … } |
WblSchema *
wbl_schema_new (void
);
Creates a new WblSchema with default properties.
Since: 0.1.0
void wbl_schema_load_from_data (WblSchema *self
,const gchar *data
,gssize length
,GError **error
);
Load and parse a JSON schema from the given serialised JSON data
.
See wbl_schema_load_from_stream_async()
for more details.
Since: 0.1.0
void wbl_schema_load_from_file (WblSchema *self
,const gchar *filename
,GError **error
);
Load and parse a JSON schema from the given local file containing serialised
JSON data. To load a non-local file, or to use a URI, use
wbl_schema_load_from_stream_async()
.
See wbl_schema_load_from_stream_async()
for more details.
Since: 0.1.0
void wbl_schema_load_from_stream (WblSchema *self
,GInputStream *stream
,GCancellable *cancellable
,GError **error
);
Load and parse a JSON schema from an input stream providing serialised JSON
data. This is the synchronous version of wbl_schema_load_from_stream_async()
,
which is preferred for production code.
See wbl_schema_load_from_stream_async()
for more details.
self |
||
stream |
stream of serialised JSON data to load |
|
cancellable |
a GCancellable, or |
[nullable] |
error |
Since: 0.1.0
void wbl_schema_load_from_stream_async (WblSchema *self
,GInputStream *stream
,GCancellable *cancellable
,GAsyncReadyCallback callback
,gpointer user_data
);
Load and parse a JSON schema from an input stream providing serialised JSON
data. The loading and parsing is done asynchronously and, once complete,
callback
is invoked in the main context which was thread default at the time
of calling this method.
Call wbl_schema_load_from_stream_finish()
from callback
to retrieve
information about any parsing errors.
If a schema is loaded successfully, it is guaranteed to be valid.
Any previously loaded schemas will be unloaded when starting to load a new one, even if the new load operation fails (e.g. due to the new schema being invalid).
This is the preferred method for loading a schema due to the potential blocking involved in the I/O.
self |
||
stream |
stream of serialised JSON data to load |
|
cancellable |
a GCancellable, or |
[nullable] |
callback |
callback to invoke when parsing is
complete, or |
[scope async][nullable] |
user_data |
user data to pass to |
[closure callback] |
Since: 0.1.0
void wbl_schema_load_from_stream_finish (WblSchema *self
,GAsyncResult *result
,GError **error
);
Finish an asynchronous schema loading operation started with
wbl_schema_load_from_stream_async()
.
Since: 0.1.0
void wbl_schema_load_from_json (WblSchema *self
,JsonNode *root
,GCancellable *cancellable
,GError **error
);
Load and parse a JSON schema from a pre-parsed JSON tree. To load from a
non-pre-parsed JSON document, use wbl_schema_load_from_stream_async()
.
See wbl_schema_load_from_stream_async()
for more details.
self |
||
root |
root node of the parsed JSON data to load |
|
cancellable |
a GCancellable, or |
[nullable] |
error |
Since: UNRELEASED
WblSchemaNode *
wbl_schema_get_root (WblSchema *self
);
Get the root schema from the parsed schema document. If no document has been
parsed using wbl_schema_load_from_stream_async()
yet, or if the parsed
document was invalid, NULL
is returned.
The returned object is valid as long as the WblSchema is alive and has not started parsing another document.
Since: 0.1.0
GPtrArray *
wbl_schema_get_validation_messages (WblSchema *self
);
Get an array of messages from the validation process of the schema document.
These may be informational messages as well as errors. If no document has
been parsed using wbl_schema_load_from_stream_async()
yet, or if there were
no messages from the validation process, NULL
is returned.
The returned messages are valid as long as the WblSchema is alive and has not started parsing another document.
a
non-empty array of messages, or NULL
.
[transfer none][nullable][element-type WblValidateMessage]
Since: UNRELEASED
void wbl_schema_apply (WblSchema *self
,JsonNode *instance
,GError **error
);
Apply a JSON Schema to a JSON instance, validating whether the instance conforms to the schema. The instance may be any kind of JSON node, and does not necessarily have to be a JSON object.
Since: 0.1.0
GPtrArray * wbl_schema_generate_instances (WblSchema *self
,WblGenerateInstanceFlags flags
);
Generate JSON instances for the given JSON Schema. These instances are designed to be used as test vectors for code which parses and handles JSON following this schema. By default, instances which are both valid and invalid are generated, with the invalid schemas designed to test boundary conditions of validity, and common parsing problems.
All generated instances are correctly formed JSON, and all will parse successfully. By design, however, some of the instances will not validate according to the given WblSchema.
newly allocated array of WblGeneratedInstances.
[transfer full][element-type WblGeneratedInstance]
Since: 0.1.0
GPtrArray *
wbl_schema_get_schema_info (WblSchema *self
);
Get an array of WblSchemaInfo structures, each giving debugging and timing information for a schema or subschema from this WblSchema. There will always be one WblSchemaInfo for the top-level schema and, depending on the structure of the schema, there may be other WblSchemaInfo instances for sub-schemas of the top-level schema.
This function is only useful after wbl_schema_generate_instances()
has been
called, as all its debugging and timing information pertains to generated
instances, and which parts of a JSON schema file are fast or slow.
The array of WblSchemaInfo structures is returned in an undefined order.
a newly allocated array of WblSchemaInfo structures of timing information.
[transfer full][element-type WblSchemaInfo]
Since: UNRELEASED
WblSchemaNode *
wbl_schema_node_ref (WblSchemaNode *self
);
Increment the reference count of the schema node.
Since: 0.1.0
void
wbl_schema_node_unref (WblSchemaNode *self
);
Decrement the reference count of the schema node.
Since: 0.1.0
JsonObject *
wbl_schema_node_get_root (WblSchemaNode *self
);
Get the JSON object forming the root node of this schema or subschema.
Since: 0.1.0
const gchar *
wbl_schema_node_get_title (WblSchemaNode *self
);
Get the title metadata of this schema or subschema, if set. This should briefly state the purpose of the instance produced by this schema.
Since: 0.1.0
const gchar *
wbl_schema_node_get_description (WblSchemaNode *self
);
Get the description metadata of this schema or subschema, if set. This should explain in depth the purpose of the instance produced by this schema.
Since: 0.1.0
JsonNode *
wbl_schema_node_get_default (WblSchemaNode *self
);
Get the default value for instances of this schema or subschema, if set. This may not validate against the schema.
Since: 0.1.0
WblGeneratedInstance * wbl_generated_instance_new_from_string (const gchar *json
,gboolean valid
);
Create a new WblGeneratedInstance from the given serialised JSON instance and associated metadata.
json |
serialised JSON to use for the instance |
|
valid |
whether the instance is expected to validate against the schema |
Since: 0.1.0
WblGeneratedInstance *
wbl_generated_instance_copy (WblGeneratedInstance *self
);
Copy a WblGeneratedInstance into a newly allocated region of memory. This is a deep copy.
Since: 0.1.0
void
wbl_generated_instance_free (WblGeneratedInstance *self
);
Free an allocated WblGeneratedInstance.
Since: 0.1.0
const gchar *
wbl_generated_instance_get_json (WblGeneratedInstance *self
);
Get the string form of the generated JSON instance.
Since: 0.1.0
gboolean
wbl_generated_instance_is_valid (WblGeneratedInstance *self
);
Get whether the generated JSON instance is valid with respect to the schema.
Since: 0.2.0
WblValidateMessage *
wbl_validate_message_copy (WblValidateMessage *self
);
Copy a WblValidateMessage into a newly allocated region of memory. This is a deep copy.
Since: UNRELEASED
void
wbl_validate_message_free (WblValidateMessage *self
);
Free an allocated WblValidateMessage.
Since: UNRELEASED
gchar *
wbl_validate_message_build_specification_link
(WblValidateMessage *self
);
Build a URI linking to the JSON Schema specification section relevant to the
validate message. If there is no relevant section, NULL
is returned.
Since: UNRELEASED
const gchar *
wbl_validate_message_get_path (WblValidateMessage *self
);
Get a JSONPath output path expression for the JSON node relevant to the validate message. If the node cannot be identified, a generic string (‘(unknown node)’) is returned.
See: http://goessner.net/articles/JsonPath/
Since: UNRELEASED
WblValidateMessageLevel
wbl_validate_message_get_level (WblValidateMessage *self
);
Get the level of the WblValidateMessage.
Since: UNRELEASED
gchar *
wbl_validate_message_build_json (WblValidateMessage *self
);
Build a string representation of the JSON node relevant to the validate message.
Since: UNRELEASED
const gchar *
wbl_validate_message_get_message (WblValidateMessage *self
);
Get the formatted message of the WblValidateMessage.
Since: UNRELEASED
GPtrArray *
wbl_validate_message_get_sub_messages (WblValidateMessage *self
);
Get the sub-messages of the message, if any exist. If there are no
sub-messages, NULL
is returned.
Since: UNRELEASED
WblSchemaInfo *
wbl_schema_info_copy (WblSchemaInfo *self
);
Copy a WblSchemaInfo into a newly allocated region of memory. This is a deep copy.
Since: UNRELEASED
void
wbl_schema_info_free (WblSchemaInfo *self
);
Free an allocated WblSchemaInfo.
Since: UNRELEASED
gint64
wbl_schema_info_get_generation_time (WblSchemaInfo *self
);
Get the time it took to generate all instances of the schema, in monotonic microseconds.
Since: UNRELEASED
guint
wbl_schema_info_get_n_times_generated (WblSchemaInfo *self
);
Get the number of times the instances of this schema were requested. They are only ever actually generated at most once, and further requests are answered from the cache.
Since: UNRELEASED
guint
wbl_schema_info_get_id (WblSchemaInfo *self
);
Get an opaque, unique identifier for this schema.
Since: UNRELEASED
guint
wbl_schema_info_get_n_instances_generated
(WblSchemaInfo *self
);
Get the number of instances generated from this schema.
Since: UNRELEASED
gchar *
wbl_schema_info_build_json (WblSchemaInfo *self
);
Build the JSON string for this schema, in a human-readable format.
Since: UNRELEASED
typedef struct _WblSchema WblSchema;
All the fields in the WblSchema structure are private and should never be accessed directly.
Since: 0.1.0
typedef struct { GPtrArray/*<owned WblValidateMessage>*/ *(*validate_schema) (WblSchema *self, WblSchemaNode *root, GError **error); void (*apply_schema) (WblSchema *self, WblSchemaNode *root, JsonNode *instance, GError **error); GHashTable/*<owned JsonNode>*/ *(*generate_instance_nodes) (WblSchema *self, WblSchemaNode *root); } WblSchemaClass;
Most of the fields in the WblSchemaClass structure are private and should never be accessed directly.
Walk over a parsed schema and validate that it is a valid
schema. The default implementation checks against JSON Schema, but overriding
implementations could check extension keywords. If |
||
Apply a parsed schema to a JSON instance, validating the
instance against the schema. The default implementation applies standard
JSON Schema keywords, but overriding implementations could implement extension
keywords. If |
||
Generate a set of JSON instances which are valid
and invalid for this JSON Schema. The default implementation generates for
all standard JSON Schema keywords, but overriding implementations could
generate for extension keywords. If |
Since: 0.1.0
typedef struct _WblSchemaNode WblSchemaNode;
A reference counted structure which represents a single schema or subschema.
All the fields in the WblSchemaNode structure are private and should never be accessed directly.
Since: 0.1.0
Flags affecting the generation of JSON instances for schemas using
wbl_schema_generate_instances()
.
Since: 0.1.0
typedef struct _WblGeneratedInstance WblGeneratedInstance;
An allocated structure which represents a generated JSON instance which may be valid for a given JSON Schema. Associated metadata is stored with the instance, such as whether it is expected to be valid.
All the fields in the WblGeneratedInstance structure are private and should never be accessed directly.
Since: 0.1.0
Severity levels of messages from the validation process for a JSON Schema.
Since: UNRELEASED
typedef struct _WblValidateMessage WblValidateMessage;
An allocated structure which represents a message from the validation process for a JSON Schema. This may be an error message (for an invalid schema), or an informational or warning message. Associated metadata, such as the relevant part of the JSON Schema standard, and the location in the schema input which caused the message, are included.
All the fields in the WblValidateMessage structure are private and should never be accessed directly.
Since: UNRELEASED
#define WBL_SCHEMA_CORE "json-schema-core"
Canonical name for the JSON Schema Core standard.
Since: UNRELEASED
#define WBL_SCHEMA_VALIDATION "json-schema-validation"
Canonical name for the JSON Schema Validation standard.
Since: UNRELEASED
typedef struct _WblSchemaInfo WblSchemaInfo;
An allocated structure which stores debugging and timing information about a particular schema or sub-schema, which might be useful in optimising the schema file design.
All the fields in the WblSchemaInfo structure are private and should never be accessed directly.
Since: UNRELEASED