# vim: set ft=perl ts=8 sts=2 sw=2 tw=100 et :
use strictures 2;
use 5.020;
use stable 0.031 'postderef';
use experimental 'signatures';
no autovivification warn => qw(fetch store exists delete);
use if "$]" >= 5.022, experimental => 're_strict';
no if "$]" >= 5.031009, feature => 'indirect';
no if "$]" >= 5.033001, feature => 'multidimensional';
no if "$]" >= 5.033006, feature => 'bareword_filehandles';
no if "$]" >= 5.041009, feature => 'smartmatch';
no feature 'switch';
use open ':std', ':encoding(UTF-8)'; # force stdin, stdout, stderr into utf8

use Test::Needs;
use List::Util 1.50 'head';
use lib 't/lib';
use Helper;
use Acceptance;

BEGIN {
  my @variables = qw(AUTHOR_TESTING AUTOMATED_TESTING EXTENDED_TESTING);

  plan skip_all => 'These tests may fail if the test suite continues to evolve! They should only be run with '
      .join(', ', map $_.'=1', head(-1, @variables)).' or '.$variables[-1].'=1'
    if not grep $ENV{$_}, @variables;
}

if ($ENV{EXTENDED_TESTING}) {
  test_needs {
    'Email::Address::XS' => '1.04',
    'Data::Validate::Domain' => 0.13,
    'Data::Validate::URI' => 0,
  };
}

if ($ENV{AUTHOR_TESTING}) {
  eval { require Email::Address::XS; Email::Address::XS->VERSION(1.04); 1 } or fail $@;
  eval { require Data::Validate::Domain; Data::Validate::Domain->VERSION(0.13); 1 } or fail $@;
  eval { require Data::Validate::URI; 1 } or fail $@;
}

my $version = 'draft4';

$ENV{NO_SHORT_CIRCUIT} = 1;

acceptance_tests(
  acceptance => {
    specification => $version,
    test_subdir => 'optional/format',
  },
  evaluator => {
    specification_version => $version,
    # validate_formats behaviour should default to true for this draft
    collect_annotations => 0,
  },
  output_file => $version.'-acceptance-format.txt',
  test => {
    $ENV{NO_TODO} ? () : (todo_tests => [
      { file => [
          # these all depend on optional prereqs
          !$ENV{AUTHOR_TESTING} && !eval { require Email::Address::XS; Email::Address::XS->VERSION(1.04); 1 } ? 'email.json' : (),
          !$ENV{AUTHOR_TESTING} && !eval { require Data::Validate::Domain; Data::Validate::Domain->VERSION(0.13); 1 } ? 'hostname.json' : (),
          !$ENV{AUTHOR_TESTING} && !eval { require Data::Validate::URI; 1 } ? 'uri.json' : (),
        ] },
      # various edge cases that are difficult to accomodate
      { file => 'hostname.json', group_description => 'validation of host names', test_description => 'trailing dot' },
      { file => 'hostname.json', group_description => 'validation of A-label (punycode) host names' },
      { file => 'uri.json', test_description => [
          'lone percent sign is invalid',
          'non-numeric port is invalid',
          'leading zero in an embedded IPv4 address is invalid',
        ] },
      { file => 'email.json', test_description => [
          'a trailing line feed is not valid',
          'a trailing carriage return is not valid',
          'a trailing space is not valid',
          'a leading space is not valid',
          'a domain label starting with a hyphen is not valid',
          'a domain label ending with a hyphen is not valid',
          'a domain ending with a dot is not valid',
          'empty brackets after the @ are not valid',
          'an IPv4-address-literal with three octets is not valid',
          'an IPv4-address-literal with five octets is not valid',
          'bracketed content that is not an address is not valid',
          'a parenthesis in an unquoted local part is not valid',
          'a parenthesis in the domain is not valid',
        ] },
    ]),
  },
);

END {
diag <<DIAG

###############################

Attention CPANTesters: you do not need to file a ticket when this test fails. I will receive the test reports and act on it soon. thank you!

###############################
DIAG
  if not is_passing;
}

done_testing;
__END__
see t/results/draft4-acceptance-format.txt for test results
