NAME
Test::Neo4j::Types - Tools for testing Neo4j type modules
VERSION
version 0.05
OVERVIEW
This module distribution is experimental. Should the experiment be deemed successful, it will eventually be merged with the existing Neo4j-Types distribution.
You probably shouldn't be using this module at this time, because the requirements it checks for are evolving and might shift under your feet at any moment. For further information, see johannessen/neo4j-types Version 2 (milestone).
SYNOPSIS
# For a node data structure that happens to match
# the given parameters exactly:
neo4j_node_ok 'Local::Node', sub {
my ($class, $params) = @_;
return bless { %$params }, $class;
};
# For a node class that happens to already have
# a new() constructor exactly like that:
neo4j_node_ok 'Local::Node', \&Local::Node::new;
# For a relationship data structure that needs
# adapting from the given parameters:
neo4j_relationship_ok 'Local::Reln', sub {
my ($class, $params) = @_;
return bless {
%$params,
start => $params->{start_id},
end => $params->{end_id},
}, $class;
};
# For the typical path data structure:
neo4j_path_ok 'Local::Path', sub {
my ($class, $params) = @_;
return bless [ $params->{elements}->@* ], $class;
};
# For spatial / temporal data structures:
neo4j_point_ok 'Local::Point', sub {...};
neo4j_datetime_ok 'Local::Temporal::Instant', sub {...};
neo4j_duration_ok 'Local::Temporal::Duration', sub {...};
DESCRIPTION
Offers a simple way to test your Neo4j::Types implementation for correctness. These test tools not only verify that the required methods are provided, they also try to verify that the methods actually work as expected. While the checks provided by this module certainly don't cover all requirements, they do cover many of them.
It is anticipated that the checks these tools perform will be expanded in future. If this worries you, you should consider only using these tools for author tests. That said, if your code is on CPAN and declares this module as a dependency, the author of this module will take every effort to avoid problems caused by such changes.
FUNCTIONS
Test::Neo4j::Types offers the following functions. All functions are exported by default.
neo4j_datetime_ok
sub datetime_new ($class, $params) {
return bless { ... }, $class;
}
neo4j_datetime_ok $datetime_class, \&datetime_new;
neo4j_datetime_ok $datetime_class, \&datetime_new, $subtest_name;
Verifies that $datetime_class
is a package that implements the interface specified for temporal instants by Neo4j::Types.
\&datetime_new
must be a reference to a subroutine that can construct a new temporal instant of the type $datetime_class
based on the parameters provided in the hash ref $params
. The parameters have names exactly matching the methods in Neo4j::Types::DateTime, but epoch and type are not provided:
$params = {
days => 6560, # 1987-12-18
nanoseconds => 0,
seconds => 72000, # 20:00 UTC
tz_name => 'America/Los_Angeles',
tz_offset => -28800, # UTC-08
};
neo4j_duration_ok
sub duration_new ($class, $params) {
return bless { ... }, $class;
}
neo4j_duration_ok $duration_class, \&duration_new;
neo4j_duration_ok $duration_class, \&duration_new, $subtest_name;
Verifies that $duration_class
is a package that implements the interface specified for temporal durations by Neo4j::Types.
\&duration_new
must be a reference to a subroutine that can construct a new temporal instant of the type $duration_class
based on the parameters provided in the hash ref $params
. The parameters have names exactly matching the methods in Neo4j::Types::Duration:
$params = {
months => 18, # 1.5 years
days => 42, # 12 weeks
seconds => 172800, # 48 hours
nanoseconds => 0,
};
neo4j_node_ok
sub node_new ($class, $params) {
return bless { ... }, $class;
}
neo4j_node_ok $node_class, \&node_new;
neo4j_node_ok $node_class, \&node_new, $subtest_name;
Verifies that $node_class
is a package that implements the interface specified for nodes by Neo4j::Types.
\&node_new
must be a reference to a subroutine that can construct a new node of the type $node_class
based on the parameters provided in the hash ref $params
. The parameters have names exactly matching the methods in Neo4j::Types::Node:
$params = {
element_id => '4:a9bd8c39-9afb-4474-9890-c074b2002cf5:47',
id => 47,
labels => ['Label'],
properties => { key => 'value' },
};
neo4j_path_ok
sub path_new ($class, $params) {
return bless { ... }, $class;
}
neo4j_path_ok $path_class, \&path_new;
neo4j_path_ok $path_class, \&path_new, $subtest_name;
Verifies that $path_class
is a package that implements the interface specified for paths by Neo4j::Types.
\&path_new
must be a reference to a subroutine that can construct a new path of the type $path_class
based on the parameter provided in the hash ref $params
. The parameter is an array of references that alternate between nodes and relationships, matching the method "elements" in Neo4j::Types::Path:
$elements = [
$node_0,
$relationship_0,
$node_1,
$relationship_1,
$node_2,
];
Inside path_new
, these references will purport to perform the Neo4j::Types::Node and Neo4j::Types::Relationship roles, but shall be treated as opaque. Calling any methods other than ->DOES()
on these references may fail.
neo4j_point_ok
sub point_new ($class, $params) {
return bless { ... }, $class;
}
neo4j_point_ok $point_class, \&point_new;
neo4j_point_ok $point_class, \&point_new, $subtest_name;
Verifies that $point_class
is a package that implements the interface specified for spatial points by Neo4j::Types.
\&point_new
must be a reference to a subroutine that can construct a new node of the type $point_class
based on the parameters provided in the hash ref $params
. The parameters have names exactly matching the methods in Neo4j::Types::Point:
$params = {
srid => 4326,
coordinates => [ $x, $y, $z ],
};
neo4j_relationship_ok
sub rel_new ($class, $params) {
return bless { ... }, $class;
}
neo4j_relationship_ok $rel_class, \&rel_new;
neo4j_relationship_ok $rel_class, \&rel_new, $subtest_name;
Verifies that $rel_class
is a package that implements the interface specified for relationships by Neo4j::Types.
\&rel_new
must be a reference to a subroutine that can construct a new relationship of the type $rel_class
based on the parameters provided in the hash ref $params
. The parameters have names exactly matching the methods in Neo4j::Types::Relationship:
$params = {
element_id => '5:a9bd8c39-9afb-4474-9890-c074b2002cf5:23',
id => 23,
start_element_id => '4:a9bd8c39-9afb-4474-9890-c074b2002cf5:81',
start_id => 81,
end_element_id => '4:a9bd8c39-9afb-4474-9890-c074b2002cf5:82',
end_id => 82,
properties => { key => 'value' },
type => 'TYPE',
};
BUGS AND LIMITATIONS
The diagnostics are not particularly great. All of these tools are implemented as simple subtests. You can run prove -v
and obtain details about any failing checks, but you'll probably have to compare the TAP output with this modules's source code to make sense of them. Unfortunately, the tool source code is more optimised for compactness that for readability, which of course means me asking people to "just read the code" is quite shameless. However, because the number of users this module is anticipated to have is very low (maybe two or so), this limitation is unlikely to be addressed.
The individual test names inside the subtests could be (and probably should be) improved though. Ideally, the names of failed tests would make sense even without reading the source.
As a consequence of the subtests, it appears to be difficult to verify that these tools correctly identify non-conforming implementations, which is of course the primary job of these tools. So the testing of the tools themselves is incomplete.
Optional / "should" requirements may need to be checked, with warnings or at least diag
messages issued if not met. These warnings need to be individually selectable. One (naive but perhaps adequate) way to implement this might be a global @Test::Neo4j::Types::no_warnings
variable, which users could then localise and configure as required.
If these tools are ever developed further than this, switching to Test2::Manual::Tooling should be considered.
SEE ALSO
Neo4j::Types::ImplementorNotes
AUTHOR
Arne Johannessen <ajnn@cpan.org>
If you contact me by email, please make sure you include the word "Perl" in your subject header to help beat the spam filters.
COPYRIGHT AND LICENSE
This software is Copyright (c) 2023 by Arne Johannessen.
This is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0 or (at your option) the same terms as the Perl 5 programming language system itself.