use strict;
use Test::More qw/no_plan/;
use Test::Exception;
+use Test::Differences;
use FindBin qw/$Bin/;
use SQL::Translator;
+use SQL::Translator::Utils qw/ddl_parser_instance/;
+
### Set $ENV{SQLTTEST_RT_DEBUG} = 1 for more output
my $plan = [
{
engine => 'XML',
+ req => 'XML::LibXML 1.69',
+ no_grammar => 1,
+ },
+ {
+ engine => 'YAML',
+ no_grammar => 1,
},
+
{
engine => 'SQLite',
producer_args => {},
parser_args => {},
},
{
- engine => 'Oracle',
+ engine => 'SQLServer',
producer_args => {},
parser_args => {},
},
+
{
- engine => 'SQLServer',
+ engine => 'Oracle',
producer_args => {},
parser_args => {},
+ todo_cmp => "auto-increment triggers aren't detected",
},
{
engine => 'Sybase',
producer_args => {},
parser_args => {},
+ todo => 'Needs volunteers',
},
{
engine => 'DB2',
producer_args => {},
parser_args => {},
+ todo => 'Needs volunteers',
},
# There is no Access producer
# This data file has the right mix of table/view/procedure/trigger
# definitions, and lists enough quirks to trip up most combos
-# I am not sure if augmenting it will break other tests - experiment
-my $base_file = "$Bin/data/xml/schema.xml";
+my $base_file = "$Bin/data/roundtrip_autogen.yaml";
+open (my $base_fh, '<', $base_file) or die "$base_file: $!";
my $base_t = SQL::Translator->new;
-$base_t->$_ (1) for qw/add_drop_table no_comments/;
+$base_t->$_ (1) for qw/add_drop_table no_comments quote_identifiers/;
my $base_schema = $base_t->translate (
- parser => 'XML',
- file => $base_file,
+ parser => 'YAML',
+ data => do { local $/; <$base_fh>; },
) or die $base_t->error;
+#assume there is at least one table
+my $string_re = {
+ XML => qr/<tables>\s*<table/,
+ YAML => qr/\A---\n.+tables\:/s,
+ SQL => qr/^\s*CREATE TABLE/m,
+};
+
for my $args (@$plan) {
+ SKIP: {
+ $args->{name} ||= $args->{engine};
+
+ my @req = ref $args->{req} ? @{$args->{req}} : $args->{req}||();
+ my @missing;
+ for (@req) {
+ eval "use $_ ()";
+ push @missing, $_ if ($@);
+ }
+ if (@missing) {
+ skip sprintf ('Need %s for %s roundtrip test',
+ join (', ', @missing),
+ $args->{name},
+ );
+ }
- $args->{name} ||= $args->{engine};
+ use_ok("SQL::Translator::Producer::$args->{engine}");
+ use_ok("SQL::Translator::Parser::$args->{engine}");
- lives_ok (
- sub { check_roundtrip ($args, $base_schema) },
- "Round trip for $args->{name} did not throw an exception",
- );
+ ok(ddl_parser_instance($args->{engine}), 'Got proper parser instance')
+ unless $args->{no_grammar};
+
+ TODO: {
+ local $TODO = $args->{todo} if $args->{todo};
+
+ no warnings 'once';
+ # silence PR::D from spewing on STDERR
+ local $::RD_ERRORS = 0 if $args->{todo};
+ local $::RD_WARN = 0 if $args->{todo};
+ local $::RD_HINT = 0 if $args->{todo};
+
+ lives_ok (
+ sub { check_roundtrip ($args, $base_schema, $args->{todo_cmp}) },
+ "Round trip for $args->{name} did not throw an exception",
+ );
+ }
+ }
}
sub check_roundtrip {
- my ($args, $base_schema) = @_;
+ my ($args, $base_schema, $todo_cmp) = @_;
my $base_t = $base_schema->translator;
# create some output from the submitted schema
like (
$base_out,
- $args->{engine} eq 'XML' #assume there is at least one table
- ? qr/<tables>\s*<table/m
- : qr/^\s*CREATE TABLE/m
- ,
+ $string_re->{$args->{engine}} || $string_re->{SQL},
"Received some meaningful output from the first $args->{name} production",
) or do {
diag ( _gen_diag ($base_t->error) );
# parse the sql back
my $parser_t = SQL::Translator->new;
- $parser_t->$_ (1) for qw/add_drop_table no_comments/;
+ $parser_t->$_ (1) for qw/add_drop_table no_comments quote_identifiers/;
my $mid_schema = $parser_t->translate (
data => $base_out,
parser => $args->{engine},
isa_ok ($mid_schema, 'SQL::Translator::Schema', "First $args->{name} parser pass produced a schema:")
or do {
diag (_gen_diag ( $parser_t->error, $base_out ) );
+ my $i;
+ note join ("\n" . ( '=' x 76) . "\n",
+ 'Unparseable DDL:',
+ (join ("\n", map { ++$i . ":\t$_" } split /\n/, $base_out) ),
+ ''
+ );
return;
};
_get_table_info ($mid_schema->get_tables),
_get_table_info ($base_schema->get_tables),
"Schema tables generally match afer $args->{name} parser trip",
- ) or return;
+ ) or (diag(explain _get_table_info($mid_schema->get_tables)), return);
# and produce sql once again
like (
$rt_out,
- $args->{engine} eq 'XML' #assume there is at least one table
- ? qr/<tables>\s*<table/m
- : qr/^\s*CREATE TABLE/m
- ,
+ $string_re->{$args->{engine}} || $string_re->{SQL},
"Received some meaningful output from the second $args->{name} production",
) or do {
diag ( _gen_diag ( $parser_t->error ) );
return;
};
+ local $TODO = $todo_cmp;
# the two sql strings should be identical
my $msg = "$args->{name} SQL roundtrip successful - SQL statements match";
$ENV{SQLTTEST_RT_DEBUG}
- ? is_deeply (
- [ split /\n/, $rt_out ],
- [ split /\n/, $base_out ],
- $msg,
- )
+ ? eq_or_diff ($rt_out, $base_out, $msg)
: ok ($rt_out eq $base_out, $msg)
;
}