Top | ![]() |
![]() |
![]() |
![]() |
WblSchema * | wbl_schema_new () |
void | wbl_schema_load_from_data () |
void | wbl_schema_load_from_file () |
void | wbl_schema_load_from_stream () |
void | wbl_schema_load_from_stream_async () |
void | wbl_schema_load_from_stream_finish () |
WblSchemaNode * | wbl_schema_get_root () |
void | wbl_schema_apply () |
GPtrArray * | wbl_schema_generate_instances () |
WblSchemaNode * | wbl_schema_node_ref () |
void | wbl_schema_node_unref () |
JsonObject * | wbl_schema_node_get_root () |
const gchar * | wbl_schema_node_get_title () |
const gchar * | wbl_schema_node_get_description () |
JsonNode * | wbl_schema_node_get_default () |
WblGeneratedInstance * | wbl_generated_instance_new_from_string () |
WblGeneratedInstance * | wbl_generated_instance_copy () |
void | wbl_generated_instance_free () |
const gchar * | wbl_generated_instance_get_json () |
gboolean | wbl_generated_instance_is_valid () |
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_c = $(json_schemas:.schema.json=.schema.c) CLEANFILES += $(json_schemas_c) %.schema.c: %.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 |
my_test_suite_SOURCES = my-test-suite.c my-format.schema.c |
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.c" … // 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
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
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
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
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 { void (*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