From f02eb72f8846350e9d5d02e6930f76b5282a968f Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Mon, 7 Sep 2026 17:42:02 +0200 Subject: [PATCH 1/5] fix: parse Mo::Inline double-colon barewords Treat `::` as a bareword string when it appears before concatenation, allowing dense Mo::Inline-generated hash dereferences such as TestML::Base to compile on both execution backends. Generated with [Codex](https://openai.com/codex) Co-Authored-By: Codex --- docs/about/changelog.md | 2 ++ .../org/perlonjava/frontend/parser/ParsePrimary.java | 8 ++++++++ .../resources/unit/mo_inline_double_colon_bareword.t | 10 ++++++++++ 3 files changed, 20 insertions(+) create mode 100644 src/test/resources/unit/mo_inline_double_colon_bareword.t diff --git a/docs/about/changelog.md b/docs/about/changelog.md index f7d3298da..07913addd 100644 --- a/docs/about/changelog.md +++ b/docs/about/changelog.md @@ -6,6 +6,8 @@ priorities and future plans. ## Work in progress +- Fix parsing of dense Mo::Inline expressions that use `::` as a bareword. + - Preserve UTF-8 HTML octets through HTML::Parser and no-op entity decoding, restoring complete Thai text in HTML::Formatter output. - Preserve caller-owned array and hash lifetimes across generated coercion diff --git a/src/main/java/org/perlonjava/frontend/parser/ParsePrimary.java b/src/main/java/org/perlonjava/frontend/parser/ParsePrimary.java index 571bf6c15..e8be24cbd 100644 --- a/src/main/java/org/perlonjava/frontend/parser/ParsePrimary.java +++ b/src/main/java/org/perlonjava/frontend/parser/ParsePrimary.java @@ -374,6 +374,14 @@ static Node parseOperator(Parser parser, LexerToken token, String operator) { return new StringNode("::" + identifierName, parser.tokenIndex); } } + // In an expression such as `$pkg.::.':E'`, Perl treats `::` + // as a bareword string. This spelling is emitted by + // Mo::Inline and is especially common inside braced hash + // dereferences. It is not a package-qualified subroutine + // when the following token is the concatenation operator. + if (nextToken2.text.equals(".")) { + return new StringNode("::", parser.tokenIndex); + } throw new PerlCompilerException(parser.tokenIndex, "syntax error", parser.ctx.errorUtil); case "\\": diff --git a/src/test/resources/unit/mo_inline_double_colon_bareword.t b/src/test/resources/unit/mo_inline_double_colon_bareword.t new file mode 100644 index 000000000..a496de1dd --- /dev/null +++ b/src/test/resources/unit/mo_inline_double_colon_bareword.t @@ -0,0 +1,10 @@ +use strict; +use warnings; +no strict 'subs'; + +my $package = 'TestML::Base'; +my %values = ($package . ':::E' => 'loaded'); + +print "1..1\n"; +print "ok 1 - a double-colon bareword concatenates inside a braced hash lookup\n" + if $values{$package.::.':E'} eq 'loaded'; From a8b5f6ff776b10e9a3205cd2bfe351606b3caf66 Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Mon, 7 Sep 2026 18:49:23 +0200 Subject: [PATCH 2/5] wip: snapshot synced Perl core test updates Snapshot the user-supplied Perl core library and test-suite synchronization before continuing issue #1217 investigation. Generated with [Codex](https://openai.com/codex) Co-Authored-By: Codex --- src/main/perl/lib/CPAN/Meta.pm | 10 +- src/main/perl/lib/CPAN/Meta/Converter.pm | 19 +- src/main/perl/lib/CPAN/Meta/Feature.pm | 4 +- src/main/perl/lib/CPAN/Meta/History.pm | 4 +- .../perl/lib/CPAN/Meta/History/Meta_1_2.pod | 2 +- .../perl/lib/CPAN/Meta/History/Meta_1_3.pod | 2 +- .../perl/lib/CPAN/Meta/History/Meta_1_4.pod | 2 +- src/main/perl/lib/CPAN/Meta/Merge.pm | 4 +- src/main/perl/lib/CPAN/Meta/Prereqs.pm | 4 +- src/main/perl/lib/CPAN/Meta/Spec.pm | 4 +- src/main/perl/lib/CPAN/Meta/Validator.pm | 10 +- src/main/perl/lib/Parse/CPAN/Meta.pm | 4 +- src/main/perl/lib/Pod/perldelta.pod | 40 ++- src/main/perl/lib/Pod/perlexperiment.pod | 9 + src/main/perl/lib/Pod/perlop.pod | 2 +- src/main/perl/lib/Pod/perlreguts.pod | 236 +++++++++++++++++- src/main/perl/lib/Pod/perlsub.pod | 3 - src/main/perl/lib/Test/Builder.pm | 16 +- src/main/perl/lib/Test/Builder/Formatter.pm | 2 +- src/main/perl/lib/Test/Builder/Module.pm | 2 +- src/main/perl/lib/Test/Builder/Tester.pm | 2 +- .../perl/lib/Test/Builder/Tester/Color.pm | 2 +- src/main/perl/lib/Test/Builder/TodoDiag.pm | 2 +- src/main/perl/lib/Test/More.pm | 6 +- src/main/perl/lib/Test/Simple.pm | 2 +- src/main/perl/lib/Test/Tester.pm | 2 +- src/main/perl/lib/Test/Tester/Capture.pm | 2 +- .../perl/lib/Test/Tester/CaptureRunner.pm | 2 +- src/main/perl/lib/Test/Tester/Delegate.pm | 2 +- src/main/perl/lib/Test/use/ok.pm | 2 +- src/main/perl/lib/Test2.pm | 2 +- src/main/perl/lib/Test2/API.pm | 4 +- src/main/perl/lib/Test2/API/Breakage.pm | 2 +- src/main/perl/lib/Test2/API/Context.pm | 2 +- src/main/perl/lib/Test2/API/Instance.pm | 2 +- .../perl/lib/Test2/API/InterceptResult.pm | 2 +- .../lib/Test2/API/InterceptResult/Event.pm | 4 +- .../lib/Test2/API/InterceptResult/Facet.pm | 2 +- .../perl/lib/Test2/API/InterceptResult/Hub.pm | 2 +- .../lib/Test2/API/InterceptResult/Squasher.pm | 2 +- src/main/perl/lib/Test2/API/Stack.pm | 2 +- src/main/perl/lib/Test2/AsyncSubtest.pm | 2 +- .../lib/Test2/AsyncSubtest/Event/Attach.pm | 2 +- .../lib/Test2/AsyncSubtest/Event/Detach.pm | 2 +- .../perl/lib/Test2/AsyncSubtest/Formatter.pm | 2 +- src/main/perl/lib/Test2/AsyncSubtest/Hub.pm | 2 +- src/main/perl/lib/Test2/Bundle.pm | 2 +- src/main/perl/lib/Test2/Bundle/Extended.pm | 2 +- src/main/perl/lib/Test2/Bundle/More.pm | 2 +- src/main/perl/lib/Test2/Bundle/Simple.pm | 2 +- src/main/perl/lib/Test2/Compare.pm | 8 +- src/main/perl/lib/Test2/Compare/Array.pm | 12 +- src/main/perl/lib/Test2/Compare/Bag.pm | 15 +- src/main/perl/lib/Test2/Compare/Base.pm | 27 +- src/main/perl/lib/Test2/Compare/Bool.pm | 2 +- src/main/perl/lib/Test2/Compare/Custom.pm | 2 +- src/main/perl/lib/Test2/Compare/DeepRef.pm | 2 +- src/main/perl/lib/Test2/Compare/Delta.pm | 2 +- src/main/perl/lib/Test2/Compare/Event.pm | 2 +- src/main/perl/lib/Test2/Compare/EventMeta.pm | 2 +- src/main/perl/lib/Test2/Compare/Float.pm | 2 +- src/main/perl/lib/Test2/Compare/Hash.pm | 12 +- src/main/perl/lib/Test2/Compare/Isa.pm | 2 +- src/main/perl/lib/Test2/Compare/Meta.pm | 2 +- src/main/perl/lib/Test2/Compare/Negatable.pm | 2 +- src/main/perl/lib/Test2/Compare/Number.pm | 2 +- src/main/perl/lib/Test2/Compare/Object.pm | 2 +- .../perl/lib/Test2/Compare/OrderedSubset.pm | 2 +- src/main/perl/lib/Test2/Compare/Pattern.pm | 2 +- src/main/perl/lib/Test2/Compare/Ref.pm | 2 +- src/main/perl/lib/Test2/Compare/Regex.pm | 2 +- src/main/perl/lib/Test2/Compare/Scalar.pm | 2 +- src/main/perl/lib/Test2/Compare/Set.pm | 2 +- src/main/perl/lib/Test2/Compare/String.pm | 2 +- src/main/perl/lib/Test2/Compare/Undef.pm | 2 +- src/main/perl/lib/Test2/Compare/Wildcard.pm | 2 +- src/main/perl/lib/Test2/Env.pm | 2 +- src/main/perl/lib/Test2/Event.pm | 2 +- src/main/perl/lib/Test2/Event/Bail.pm | 2 +- src/main/perl/lib/Test2/Event/Diag.pm | 2 +- src/main/perl/lib/Test2/Event/Encoding.pm | 2 +- src/main/perl/lib/Test2/Event/Exception.pm | 2 +- src/main/perl/lib/Test2/Event/Fail.pm | 2 +- src/main/perl/lib/Test2/Event/Generic.pm | 2 +- src/main/perl/lib/Test2/Event/Note.pm | 2 +- src/main/perl/lib/Test2/Event/Ok.pm | 2 +- src/main/perl/lib/Test2/Event/Pass.pm | 2 +- src/main/perl/lib/Test2/Event/Plan.pm | 2 +- src/main/perl/lib/Test2/Event/Skip.pm | 2 +- src/main/perl/lib/Test2/Event/Subtest.pm | 2 +- src/main/perl/lib/Test2/Event/TAP/Version.pm | 2 +- src/main/perl/lib/Test2/Event/V2.pm | 2 +- src/main/perl/lib/Test2/Event/Waiting.pm | 2 +- src/main/perl/lib/Test2/EventFacet.pm | 2 +- src/main/perl/lib/Test2/EventFacet/About.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Amnesty.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Assert.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Control.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Error.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Hub.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Info.pm | 2 +- .../perl/lib/Test2/EventFacet/Info/Table.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Meta.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Parent.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Plan.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Render.pm | 2 +- src/main/perl/lib/Test2/EventFacet/Trace.pm | 2 +- src/main/perl/lib/Test2/Formatter.pm | 2 +- src/main/perl/lib/Test2/Formatter/TAP.pm | 2 +- src/main/perl/lib/Test2/Handle.pm | 8 +- src/main/perl/lib/Test2/Hub.pm | 2 +- src/main/perl/lib/Test2/Hub/Interceptor.pm | 2 +- .../lib/Test2/Hub/Interceptor/Terminator.pm | 2 +- src/main/perl/lib/Test2/Hub/Subtest.pm | 2 +- src/main/perl/lib/Test2/IPC.pm | 2 +- src/main/perl/lib/Test2/IPC/Driver.pm | 2 +- src/main/perl/lib/Test2/IPC/Driver/Files.pm | 2 +- src/main/perl/lib/Test2/Manual.pm | 2 +- src/main/perl/lib/Test2/Manual/Anatomy.pm | 2 +- src/main/perl/lib/Test2/Manual/Anatomy/API.pm | 2 +- .../perl/lib/Test2/Manual/Anatomy/Context.pm | 2 +- .../perl/lib/Test2/Manual/Anatomy/EndToEnd.pm | 2 +- .../perl/lib/Test2/Manual/Anatomy/Event.pm | 2 +- .../perl/lib/Test2/Manual/Anatomy/Hubs.pm | 2 +- src/main/perl/lib/Test2/Manual/Anatomy/IPC.pm | 2 +- .../lib/Test2/Manual/Anatomy/Utilities.pm | 2 +- src/main/perl/lib/Test2/Manual/Concurrency.pm | 2 +- .../perl/lib/Test2/Manual/Contributing.pm | 2 +- src/main/perl/lib/Test2/Manual/Testing.pm | 2 +- .../lib/Test2/Manual/Testing/Introduction.pm | 6 +- .../lib/Test2/Manual/Testing/Migrating.pm | 2 +- .../perl/lib/Test2/Manual/Testing/Planning.pm | 2 +- .../perl/lib/Test2/Manual/Testing/Todo.pm | 2 +- src/main/perl/lib/Test2/Manual/Tooling.pm | 2 +- .../lib/Test2/Manual/Tooling/FirstTool.pm | 2 +- .../lib/Test2/Manual/Tooling/Formatter.pm | 2 +- .../perl/lib/Test2/Manual/Tooling/Nesting.pm | 2 +- .../Test2/Manual/Tooling/Plugin/TestExit.pm | 2 +- .../Manual/Tooling/Plugin/TestingDone.pm | 2 +- .../Manual/Tooling/Plugin/ToolCompletes.pm | 2 +- .../Test2/Manual/Tooling/Plugin/ToolStarts.pm | 2 +- .../perl/lib/Test2/Manual/Tooling/Subtest.pm | 2 +- .../lib/Test2/Manual/Tooling/TestBuilder.pm | 2 +- .../perl/lib/Test2/Manual/Tooling/Testing.pm | 2 +- src/main/perl/lib/Test2/Mock.pm | 2 +- src/main/perl/lib/Test2/Plugin.pm | 2 +- src/main/perl/lib/Test2/Plugin/BailOnFail.pm | 17 +- src/main/perl/lib/Test2/Plugin/DieOnFail.pm | 15 +- src/main/perl/lib/Test2/Plugin/ExitSummary.pm | 2 +- src/main/perl/lib/Test2/Plugin/SRand.pm | 2 +- src/main/perl/lib/Test2/Plugin/Times.pm | 2 +- src/main/perl/lib/Test2/Plugin/UTF8.pm | 2 +- src/main/perl/lib/Test2/Require.pm | 2 +- .../perl/lib/Test2/Require/AuthorTesting.pm | 2 +- .../lib/Test2/Require/AutomatedTesting.pm | 2 +- src/main/perl/lib/Test2/Require/EnvVar.pm | 2 +- .../perl/lib/Test2/Require/ExtendedTesting.pm | 2 +- src/main/perl/lib/Test2/Require/Fork.pm | 2 +- src/main/perl/lib/Test2/Require/Module.pm | 2 +- .../Test2/Require/NonInteractiveTesting.pm | 2 +- src/main/perl/lib/Test2/Require/Perl.pm | 2 +- src/main/perl/lib/Test2/Require/RealFork.pm | 2 +- .../perl/lib/Test2/Require/ReleaseTesting.pm | 2 +- src/main/perl/lib/Test2/Require/Threads.pm | 2 +- src/main/perl/lib/Test2/Suite.pm | 2 +- src/main/perl/lib/Test2/Todo.pm | 2 +- src/main/perl/lib/Test2/Tools.pm | 2 +- src/main/perl/lib/Test2/Tools/AsyncSubtest.pm | 4 +- src/main/perl/lib/Test2/Tools/Basic.pm | 6 +- src/main/perl/lib/Test2/Tools/Class.pm | 2 +- .../perl/lib/Test2/Tools/ClassicCompare.pm | 2 +- src/main/perl/lib/Test2/Tools/Compare.pm | 25 +- src/main/perl/lib/Test2/Tools/Defer.pm | 2 +- src/main/perl/lib/Test2/Tools/Encoding.pm | 2 +- src/main/perl/lib/Test2/Tools/Event.pm | 2 +- src/main/perl/lib/Test2/Tools/Exception.pm | 2 +- src/main/perl/lib/Test2/Tools/Exports.pm | 2 +- src/main/perl/lib/Test2/Tools/GenTemp.pm | 2 +- src/main/perl/lib/Test2/Tools/Grab.pm | 2 +- src/main/perl/lib/Test2/Tools/Mock.pm | 2 +- src/main/perl/lib/Test2/Tools/Ref.pm | 2 +- src/main/perl/lib/Test2/Tools/Refcount.pm | 2 +- src/main/perl/lib/Test2/Tools/Spec.pm | 6 +- src/main/perl/lib/Test2/Tools/Subtest.pm | 2 +- src/main/perl/lib/Test2/Tools/Target.pm | 2 +- src/main/perl/lib/Test2/Tools/Tester.pm | 2 +- src/main/perl/lib/Test2/Tools/Tiny.pm | 6 +- src/main/perl/lib/Test2/Tools/Warnings.pm | 2 +- src/main/perl/lib/Test2/Util.pm | 2 +- src/main/perl/lib/Test2/Util/ExternalMeta.pm | 2 +- src/main/perl/lib/Test2/Util/Facets2Legacy.pm | 2 +- src/main/perl/lib/Test2/Util/Grabber.pm | 2 +- src/main/perl/lib/Test2/Util/Guard.pm | 2 +- src/main/perl/lib/Test2/Util/HashBase.pm | 2 +- src/main/perl/lib/Test2/Util/Importer.pm | 2 +- src/main/perl/lib/Test2/Util/Ref.pm | 2 +- src/main/perl/lib/Test2/Util/Sig.pm | 2 +- src/main/perl/lib/Test2/Util/Stash.pm | 2 +- src/main/perl/lib/Test2/Util/Sub.pm | 2 +- src/main/perl/lib/Test2/Util/Table.pm | 2 +- src/main/perl/lib/Test2/Util/Table/Cell.pm | 2 +- .../perl/lib/Test2/Util/Table/LineBreak.pm | 2 +- src/main/perl/lib/Test2/Util/Term.pm | 2 +- src/main/perl/lib/Test2/Util/Times.pm | 2 +- src/main/perl/lib/Test2/Util/Trace.pm | 2 +- src/main/perl/lib/Test2/V0.pm | 2 +- src/main/perl/lib/Test2/V1.pm | 32 +-- src/main/perl/lib/Test2/V1/Base.pm | 2 +- src/main/perl/lib/Test2/V1/Handle.pm | 2 +- src/main/perl/lib/Test2/Workflow.pm | 2 +- src/main/perl/lib/Test2/Workflow/BlockBase.pm | 2 +- src/main/perl/lib/Test2/Workflow/Build.pm | 2 +- src/main/perl/lib/Test2/Workflow/Runner.pm | 2 +- src/main/perl/lib/Test2/Workflow/Task.pm | 2 +- .../perl/lib/Test2/Workflow/Task/Action.pm | 2 +- .../perl/lib/Test2/Workflow/Task/Group.pm | 2 +- src/main/perl/lib/ok.pm | 2 +- 217 files changed, 667 insertions(+), 283 deletions(-) diff --git a/src/main/perl/lib/CPAN/Meta.pm b/src/main/perl/lib/CPAN/Meta.pm index e00c73233..fad6a06a0 100644 --- a/src/main/perl/lib/CPAN/Meta.pm +++ b/src/main/perl/lib/CPAN/Meta.pm @@ -3,7 +3,7 @@ use strict; use warnings; package CPAN::Meta; -our $VERSION = '2.150013'; +our $VERSION = '2.150015'; #pod =head1 SYNOPSIS #pod @@ -649,7 +649,7 @@ CPAN::Meta - the distribution metadata for a CPAN dist =head1 VERSION -version 2.150013 +version 2.150015 =head1 SYNOPSIS @@ -1038,7 +1038,7 @@ Adam Kennedy =head1 CONTRIBUTORS -=for stopwords Ansgar Burchardt Avar Arnfjord Bjarmason Benjamin Noggle Christopher J. Madsen Chuck Adams Cory G Watson Damyan Ivanov Dan Book Eric Wilhelm Graham Knop Gregor Hermann Karen Etheridge Kenichi Ishigaki Kent Fredric Ken Williams Lars Dieckow Leon Timmermans majensen Mark Fowler Matt S Trout Michael G. Schwern Mohammad Anwar mohawk2 moznion Niko Tyni Olaf Alders Olivier Mengué Philippe Bruhat (BooK) Randy Sims Ricardo Signes Tomohiro Hosaka +=for stopwords Ansgar Burchardt Avar Arnfjord Bjarmason Benjamin Noggle Christopher J. Madsen Chuck Adams Cory G Watson Damyan Ivanov Dan Book Eric Wilhelm Graham Knop Gregor Hermann James E Keenan Karen Etheridge Kenichi Ishigaki Kent Fredric Ken Williams Lars Dieckow Leon Timmermans majensen Mark Fowler Matt S Trout Michael G. Schwern Mohammad Anwar mohawk2 moznion Niko Tyni Olaf Alders Olivier Mengué Philippe Bruhat (BooK) Randy Sims Ricardo Signes Tomohiro Hosaka =over 4 @@ -1088,6 +1088,10 @@ Gregor Hermann =item * +James E Keenan + +=item * + Karen Etheridge =item * diff --git a/src/main/perl/lib/CPAN/Meta/Converter.pm b/src/main/perl/lib/CPAN/Meta/Converter.pm index 44830c668..18beae564 100644 --- a/src/main/perl/lib/CPAN/Meta/Converter.pm +++ b/src/main/perl/lib/CPAN/Meta/Converter.pm @@ -3,12 +3,11 @@ use strict; use warnings; package CPAN::Meta::Converter; -our $VERSION = '2.150013'; +our $VERSION = '2.150015'; #pod =head1 SYNOPSIS #pod -#pod my $struct = decode_json_file('META.json'); -#pod +#pod my $struct = Parse::CPAN::Meta->load_file('META.json'); #pod my $cmc = CPAN::Meta::Converter->new( $struct ); #pod #pod my $new_struct = $cmc->convert( version => "2" ); @@ -24,7 +23,7 @@ our $VERSION = '2.150013'; #pod =cut use CPAN::Meta::Validator; -use CPAN::Meta::Requirements; +use CPAN::Meta::Requirements 2.145; use Parse::CPAN::Meta 1.4400 (); # To help ExtUtils::MakeMaker bootstrap CPAN::Meta::Requirements on perls @@ -392,12 +391,7 @@ sub _clean_version { my $v = eval { version->new($element) }; # XXX check defined $v and not just $v because version objects leak memory # in boolean context -- dagolden, 2012-02-03 - if ( defined $v ) { - return _is_qv($v) ? $v->normal : $element; - } - else { - return 0; - } + return defined $v ? $v->stringify : 0; } sub _bad_version_hook { @@ -1513,12 +1507,11 @@ CPAN::Meta::Converter - Convert CPAN distribution metadata structures =head1 VERSION -version 2.150013 +version 2.150015 =head1 SYNOPSIS - my $struct = decode_json_file('META.json'); - + my $struct = Parse::CPAN::Meta->load_file('META.json'); my $cmc = CPAN::Meta::Converter->new( $struct ); my $new_struct = $cmc->convert( version => "2" ); diff --git a/src/main/perl/lib/CPAN/Meta/Feature.pm b/src/main/perl/lib/CPAN/Meta/Feature.pm index 82667d894..2ae0044f6 100644 --- a/src/main/perl/lib/CPAN/Meta/Feature.pm +++ b/src/main/perl/lib/CPAN/Meta/Feature.pm @@ -3,7 +3,7 @@ use strict; use warnings; package CPAN::Meta::Feature; -our $VERSION = '2.150013'; +our $VERSION = '2.150015'; use CPAN::Meta::Prereqs; @@ -77,7 +77,7 @@ CPAN::Meta::Feature - an optional feature provided by a CPAN distribution =head1 VERSION -version 2.150013 +version 2.150015 =head1 DESCRIPTION diff --git a/src/main/perl/lib/CPAN/Meta/History.pm b/src/main/perl/lib/CPAN/Meta/History.pm index eeae4af85..3ec3d9358 100644 --- a/src/main/perl/lib/CPAN/Meta/History.pm +++ b/src/main/perl/lib/CPAN/Meta/History.pm @@ -4,7 +4,7 @@ use strict; use warnings; package CPAN::Meta::History; -our $VERSION = '2.150013'; +our $VERSION = '2.150015'; 1; @@ -22,7 +22,7 @@ CPAN::Meta::History - history of CPAN Meta Spec changes =head1 VERSION -version 2.150013 +version 2.150015 =head1 DESCRIPTION diff --git a/src/main/perl/lib/CPAN/Meta/History/Meta_1_2.pod b/src/main/perl/lib/CPAN/Meta/History/Meta_1_2.pod index 1cb471fd2..6ded25901 100644 --- a/src/main/perl/lib/CPAN/Meta/History/Meta_1_2.pod +++ b/src/main/perl/lib/CPAN/Meta/History/Meta_1_2.pod @@ -653,7 +653,7 @@ Add proposal for C field. =item * -Add C field as a compliment to L +Add C field as a complement to L =item * diff --git a/src/main/perl/lib/CPAN/Meta/History/Meta_1_3.pod b/src/main/perl/lib/CPAN/Meta/History/Meta_1_3.pod index 9e889cd59..3e9e1283b 100644 --- a/src/main/perl/lib/CPAN/Meta/History/Meta_1_3.pod +++ b/src/main/perl/lib/CPAN/Meta/History/Meta_1_3.pod @@ -682,7 +682,7 @@ Add proposal for C field. =item * -Add C field as a compliment to L +Add C field as a complement to L =item * diff --git a/src/main/perl/lib/CPAN/Meta/History/Meta_1_4.pod b/src/main/perl/lib/CPAN/Meta/History/Meta_1_4.pod index 932f1ed94..f8b95a889 100644 --- a/src/main/perl/lib/CPAN/Meta/History/Meta_1_4.pod +++ b/src/main/perl/lib/CPAN/Meta/History/Meta_1_4.pod @@ -696,7 +696,7 @@ Add proposal for C field. =item * -Add C field as a compliment to L +Add C field as a complement to L =item * diff --git a/src/main/perl/lib/CPAN/Meta/Merge.pm b/src/main/perl/lib/CPAN/Meta/Merge.pm index dc012f31d..d6e48b3bf 100644 --- a/src/main/perl/lib/CPAN/Meta/Merge.pm +++ b/src/main/perl/lib/CPAN/Meta/Merge.pm @@ -4,7 +4,7 @@ use warnings; package CPAN::Meta::Merge; -our $VERSION = '2.150013'; +our $VERSION = '2.150015'; use Carp qw/croak/; use Scalar::Util qw/blessed/; @@ -252,7 +252,7 @@ CPAN::Meta::Merge - Merging CPAN Meta fragments =head1 VERSION -version 2.150013 +version 2.150015 =head1 SYNOPSIS diff --git a/src/main/perl/lib/CPAN/Meta/Prereqs.pm b/src/main/perl/lib/CPAN/Meta/Prereqs.pm index 894dc55a4..555af334d 100644 --- a/src/main/perl/lib/CPAN/Meta/Prereqs.pm +++ b/src/main/perl/lib/CPAN/Meta/Prereqs.pm @@ -3,7 +3,7 @@ use strict; use warnings; package CPAN::Meta::Prereqs; -our $VERSION = '2.150013'; +our $VERSION = '2.150015'; #pod =head1 DESCRIPTION #pod @@ -326,7 +326,7 @@ CPAN::Meta::Prereqs - a set of distribution prerequisites by phase and type =head1 VERSION -version 2.150013 +version 2.150015 =head1 DESCRIPTION diff --git a/src/main/perl/lib/CPAN/Meta/Spec.pm b/src/main/perl/lib/CPAN/Meta/Spec.pm index 2cd5d1d04..c5b28bc4a 100644 --- a/src/main/perl/lib/CPAN/Meta/Spec.pm +++ b/src/main/perl/lib/CPAN/Meta/Spec.pm @@ -8,7 +8,7 @@ use strict; use warnings; package CPAN::Meta::Spec; -our $VERSION = '2.150013'; +our $VERSION = '2.150015'; 1; @@ -29,7 +29,7 @@ CPAN::Meta::Spec - specification for CPAN distribution metadata =head1 VERSION -version 2.150013 +version 2.150015 =head1 SYNOPSIS diff --git a/src/main/perl/lib/CPAN/Meta/Validator.pm b/src/main/perl/lib/CPAN/Meta/Validator.pm index 257ee7edc..79a2ebef3 100644 --- a/src/main/perl/lib/CPAN/Meta/Validator.pm +++ b/src/main/perl/lib/CPAN/Meta/Validator.pm @@ -3,12 +3,11 @@ use strict; use warnings; package CPAN::Meta::Validator; -our $VERSION = '2.150013'; +our $VERSION = '2.150015'; #pod =head1 SYNOPSIS #pod -#pod my $struct = decode_json_file('META.json'); -#pod +#pod my $struct = Parse::CPAN::Meta->load_file('META.json'); #pod my $cmv = CPAN::Meta::Validator->new( $struct ); #pod #pod unless ( $cmv->is_valid ) { @@ -996,12 +995,11 @@ CPAN::Meta::Validator - validate CPAN distribution metadata structures =head1 VERSION -version 2.150013 +version 2.150015 =head1 SYNOPSIS - my $struct = decode_json_file('META.json'); - + my $struct = Parse::CPAN::Meta->load_file('META.json'); my $cmv = CPAN::Meta::Validator->new( $struct ); unless ( $cmv->is_valid ) { diff --git a/src/main/perl/lib/Parse/CPAN/Meta.pm b/src/main/perl/lib/Parse/CPAN/Meta.pm index b5d6914a4..cc33b3bad 100644 --- a/src/main/perl/lib/Parse/CPAN/Meta.pm +++ b/src/main/perl/lib/Parse/CPAN/Meta.pm @@ -4,7 +4,7 @@ use warnings; package Parse::CPAN::Meta; # ABSTRACT: Parse META.yml and META.json CPAN metadata files -our $VERSION = '2.150013'; +our $VERSION = '2.150015'; use Exporter; use Carp 'croak'; @@ -169,7 +169,7 @@ Parse::CPAN::Meta - Parse META.yml and META.json CPAN metadata files =head1 VERSION -version 2.150013 +version 2.150015 =head1 SYNOPSIS diff --git a/src/main/perl/lib/Pod/perldelta.pod b/src/main/perl/lib/Pod/perldelta.pod index b423fc9dd..134134774 100644 --- a/src/main/perl/lib/Pod/perldelta.pod +++ b/src/main/perl/lib/Pod/perldelta.pod @@ -32,15 +32,15 @@ here, but most should go in the L section. Four new operators have been added, which are similar to the regular equality operators except for their handling of C. Whereas the regular operators treat C as equal to the empty string or the number zero, these operators consider C to be a distinct value, equal to itself, but unequal to any defined value. if( $x equ $y ) { - # $x and $y are both undef, or - # $x and $y are both defined and equal - ... + # $x and $y are both undef, or + # $x and $y are both defined and equal + ... } This is approximately equal to the following, except that it is more efficient and avoids duplicate evaluation of operands or fetching of tied scalar values: if( (!defined $x and !defined $y) or - (defined $x and defined $y and $x eq $y) ) { + (defined $x and defined $y and $x eq $y) ) { ... } @@ -434,7 +434,37 @@ manager will later use a regex to expand these into links. =item * -XXX +Since 5.28.0, the numeric value of a string would sometimes not get reset +after the string was assigned to as part of a string concatenation. It +required the following circumstances to all be present for the bug to +manifest: + +=over + +=item * + +the string variable must be zero length and have just been used in numeric +context, e.g. C<$s = ""; $n = $s + 1;> + +=item * + +then the variable must be the target of a string concatenation and also +be used on the RHS, e.g.C<$s = "9$s";> + +=item * + +then if the string is used in numeric context again, the bug caused the +old numeric value of 0 to be returned, rather than numifying the new +string value and returning 9. + +=back + +[GH #24763] + +=item * + +Parsing an invalid signature that gives a slurpy parameter a default value no +longer crashes when parser debugging is enabled. [GH #24691] =item * diff --git a/src/main/perl/lib/Pod/perlexperiment.pod b/src/main/perl/lib/Pod/perlexperiment.pod index b9d9d38cf..b3185fa79 100644 --- a/src/main/perl/lib/Pod/perlexperiment.pod +++ b/src/main/perl/lib/Pod/perlexperiment.pod @@ -226,6 +226,15 @@ taken as a literal character. The ticket for this experiment is L<[perl #23945]|https://github.com/Perl/perl5/issues/24209>. +=item Value Magic in Magic v2 + +Introduced in Perl 5.45.3. + +See L for the mechanism. + +The ticket for this experiment is +L<[perl #24735]|https://github.com/Perl/perl5/issues/24735>. + =back =head2 Accepted features diff --git a/src/main/perl/lib/Pod/perlop.pod b/src/main/perl/lib/Pod/perlop.pod index cd6a5cb45..49f64e1d0 100644 --- a/src/main/perl/lib/Pod/perlop.pod +++ b/src/main/perl/lib/Pod/perlop.pod @@ -650,7 +650,7 @@ Each of these four operators has a variant whose name is one character longer, which has different behaviour to the base operator when either (or both) of its arguments is C. These operators, called the I, consider that C is equal to another C but not equal -to any defined value - even the number zero or the empty string. Furtheremore, +to any defined value - even the number zero or the empty string. Furthermore, these operators will not invoke warnings when invoked on undefined values, even when their base counterparts would. (Though other warnings are still possible, such as C<===> warning about non-numerical values). diff --git a/src/main/perl/lib/Pod/perlreguts.pod b/src/main/perl/lib/Pod/perlreguts.pod index c5521440d..3339838bb 100644 --- a/src/main/perl/lib/Pod/perlreguts.pod +++ b/src/main/perl/lib/Pod/perlreguts.pod @@ -1048,9 +1048,21 @@ regop. An even more aggressive form of this is that a branch sequence of the form C can be converted into a C regop. -All of this occurs in the routine C which uses a special -structure C to store the analysis that it has performed, and -does the "peep-hole" optimisations as it goes. +=head4 study_chunk() + +All of the optimisations described above occur in the routine +C, which is called from C after +C is done. It uses a special structure C to store the +analysis that it has performed, and does the "peep-hole" optimisations as +it goes, in-place. + +The basic structure of C is recursive. By default it will +linearly process all nodes until it reaches the node specified by the +C parameter, or an C node if earlier. But when it encounters a +sub-pattern such the 'A' in quantifiers like C<(A)+> or C<(A){1,5}>, it +will recurse into that sub-pattern, with C set to the end of that +sub-pattern. Similarly for a branch such as C, it will recurse for +each sub-pattern A,B and C. The code involved in C is extremely cryptic. Be careful. :-) @@ -1122,6 +1134,224 @@ the possible states are the regops themselves, plus a number of additional intermediate and failure states. A few of the states are implemented as subroutines but the bulk are inline code. +=head3 The super-linear cache + +"Insanity is doing the same thing over and over again and expecting +different results." + +Under some circumstances with quantifiers, it is possible for an NFA +engine to encounter a combinatorial explosion of backtracking. The +super-linear cache (SLC) is intended to avoid this happening under some +circumstances. + +Consider this simple example: + + ("a" x 20) =~ /^ ( (aa?) ){5,100} [bc] /x; + +(This example works just the same using C<*> rather than C<{5,100}>, but +the latter form is used here as it will shortly help illuminate an issue +with non-infinite ranges.) + +This pattern will eventually fail, since the string doesn't include a 'b' +or 'c' character (this example uses a character class to stop intuit +rejecting it immediately). But early on in execution the quantifier will +have iterated 10 times, each time consuming 'aa'. So at that point the +entire input string can be thought of as having been consumed in this +fashion: + + (aa)(aa)(aa)(aa)(aa)(aa)(aa)(aa)(aa)(aa) + +Then the character class fails and the pattern starts backtracking. The +last C is retried, this time consuming a single character, and an +11th iteration can proceed, resulting in: + + (aa)(aa)(aa)(aa)(aa)(aa)(aa)(aa)(aa)(a)(a) + +before again failing the character class. The backtracking continues until +every possible permutation of 'a' and 'aa' in each iteration is tried, +which may take a long time. + +Staying with this example, consider that after much iterating and +backtracking, the engine may have reached this state: + + (aa)(a)(a) + +where it has consumed four characters using three iterations. The rest of +the match at this point can be thought of as the equivalent of: + + ("a" x 16) =~ /^ ( (aa?) ){2,97} [bc] /x; + +Running this will eventually fail, and after backtracking to the +C<(aa)(a)(a)> state, it backtracks further and tries further permutations, +after which it will eventually reach this state: + + (a)(aa)(a) + +In a similar fashion to the previous state, the rest of the match at this +point is equivalent to: + + ("a" x 16) =~ /^ ( (aa?) ){2,97} [bc] /x; + +But hold on: we know that this particular sub-match failed earlier on; so +running the exact same match again must also fail. So, in principle, after +the first set of backtracking back to the C<(aa)(a)(a)> state, we could +record in a cache somewhere that the match failed for that particular +quantifier when starting from string position 4 and with between 2 and 97 +iterations left. Then the next time the same quantifier finds itself at +the same string position and with the same number of iterations left, it +knows that it can fail itself immediately and backtrack, rather than +pushing on and (eventually) failing again. + +This is the essence of the SLC. + +There are several caveats to to this in order to make a system which is +both practical and logically correct (i.e. without false cache failures). + +=over + +=item * + +The obvious objection at this point is that recording a whole bunch of +(quantifier-id, current string position, min iterations left, max +iterations left) tuples will be extremely expensive in memory. + +We can reduce this complexity by using the SLC only on quantifiers which +have a maximum of infinity (such as C<*>, C<+>, C<({5,}>), and make the +quantifiers only use the cache after the minimum number of iterations has +already been satisfied. Under these two conditions, the remaining number +of iterations will always have a min of 0 and a max of infinity, so we +don't need to record the min and max values any more. + +With this simplification, we just need to record a single bit of +information ("failed already") for every (quantifier-id, current string +position) tuple. We can achieve this by allocating a single bit array +whose size is equal to the string length multiplied by the number of +candidate quantifiers in the pattern. So for example when matching a 1 +Mbyte string against a pattern like C which has two +quantifiers, 2 million bits must be allocated. + +To avoid a potentially large malloc() for every match that has been marked +as suitable for a SLC, a countdown is initiated the first time a candidate +C node is reached; only after (string length) multiplied by +(number of participating C nodes) iterations is the cache actually +allocated and initialised. This crude heuristic is an indication that the +match has gone super-linear. + +=item * + +The SLC is only used for quantifiers on I sub-patterns, +i.e. those which are compiled to a C/C node pair. +Quantifiers with simpler sub-patterns are less likely to exhibit +exponential behaviour. + +=item * + +Non-regular pattern items such as backreferences (C<\g{1}>) and evals +(C<(??{...})/>) break the assumption that running the same rest-of-pattern +from the same position will give the same result each time. If these occur +in the rest-of-pattern, the cache is reset. This is currently done at +runtime. + +=item * + +Nested quantifiers can sometimes the break the assumption that running the +rest-of-pattern from the same string position will always give the same +result. To understand this issue, first consider a non-nested quantifier +pattern, such as + + / A (B)+ C /x + +where each capital letter represents an entire sub-pattern: for example, +'A' might represent C<(pq)?rs>. + +During execution, A will have consumed some characters, then a number of +iterations of the quantified sub-pattern B will have consumed some more +characters, then the rest-of-pattern (in this case C) will be attempted, +starting at string position p say. If C subsequently fails, then the +engine backtracks to the quantifier, which marks in the cache that running +the rest-of-pattern from position p will always fail. Subsequent attempts +might see A consuming a different number of characters and the quantifier +might iterate a different number of times, but if the quantifier is +ever about to run the rest-of-pattern again from position p, the cache can +be used to fail immediately, rather than running and failing C again. + +Now consider a nested pattern such as + + / A ((B)+){2,5} C /x + +Here, the inner quantifier doesn't know how many times the outer +quantifier has already iterated, nor that what's to the right of it can +now vary depending on that iteration count. The rest-of-pattern after an +inner quantifier run (from the viewpoint of that inner quantifier), rather +than always being just C as in the non-nested example above, is now +instead equivalent to + + / ... ((B)+){1,4} C /x # after the first outer iteration + / ... ((B)+){0,3} C /x # after the second outer iteration + / ... ((B)+){0,2} C /x # after the third outer iteration + etc + +This violates the assumption that the rest-of-pattern is always the same +sub-pattern and that what's to the right will always pass or fail in the +same way from the same string position. + +For it to be safe to use the cache in a nested quantifier, the rule is +that the outer quantifier's still-to-go minimum and maximum values must +both remain constant on the second, third, etc., iterations. Since such +values normally count down until they reach zero or remain at infinity, +a minimum can only be be 0 or 1, and a maximum must be 0, 1 or infinity. +This effectively means that any outer quantifier other than C +disqualifies nested quantifiers from participating in the cache. + +[DAPM 2026: I suspect that this restriction is too severe, and that an +outer quantifier like C<{1,5}> is safe. But I have neither been able to +prove this to my satisfaction, nor able to find a counter-example. But my +strong suspicion is that the outer must iterate at least twice (so is at +minimum C<{2,...}>) so that the first iteration can fail and mark the +cache, then the second incorrectly fail due to the cache.] + +There are some tests for nested quantifiers in F under the +heading 'RT #79152'. + +=item * + +The number of cache-participating C nodes is stored in the upper 4 +bits of each C's C field, while the identity of the +particular C (used as part of the index into the bit cache) is +stored in the lower 4 bits. This means that a pattern can have a maximum +of 16 participating Cs. If the flags field is zero, it indicates +that this C node won't participate in the cache mechanism. + +=back + +The runtime state of the SLC is mainly stored in various fields of the +C struct, which is initialised at the start of a match. + +A pointer to the cache is stored in C<< reginfo->info_aux.poscache >>, +which will be freed when matching ends (the aux structure is guaranteed to +be freed even on abnormal termination), and its size is recorded in +C<< reginfo->poscache_size >>. + +If zero, C<< reginfo->poscache_maxiter >> indicates that the SLC countdown +has not yet been triggered (i.e. no candidate C node has been +executed yet), or that it has been subsequently disabled again. Otherwise, +its (positive) value is used for two different purposes: what value to +start an initial (or reset) countdown from; and the size to C the +cache, in bits. Currently these values are the same, but in principle they +needn't be. + +C<< reginfo->poscache_iter >> only has meaning if C is +non-zero. In that case, it represents a countdown initialised from +C. If it reaches 1, the cache is malloced/realloced if +necessary, and then zeroed. When it reaches 0, the cache is used. + +The C macro is used at runtime in various places as a +replacement for C to set a fail bit in the cache while popping the +current state. The C and C fields are set +by the current C to the address in the cache of the byte and bit +corresponding to the current match state. These are used by C +to mark the cache during a subsequent unwinding. + =head1 MISCELLANEOUS =head2 Unicode and Localisation Support diff --git a/src/main/perl/lib/Pod/perlsub.pod b/src/main/perl/lib/Pod/perlsub.pod index b2b24e8f5..7595fb06f 100644 --- a/src/main/perl/lib/Pod/perlsub.pod +++ b/src/main/perl/lib/Pod/perlsub.pod @@ -2163,9 +2163,6 @@ associated with it. If such an attribute list is present, it is broken up at space or colon boundaries and treated as though a C had been seen. See L for details about what attributes are currently supported. -Unlike the limitation with the obsolescent C, the -C syntax works to associate the attributes with -a pre-declaration, and not just with a subroutine definition. The attributes must be valid as simple identifier names (without any punctuation other than the '_' character). They may have a parameter diff --git a/src/main/perl/lib/Test/Builder.pm b/src/main/perl/lib/Test/Builder.pm index ced9cf2bd..deb8ca667 100644 --- a/src/main/perl/lib/Test/Builder.pm +++ b/src/main/perl/lib/Test/Builder.pm @@ -4,7 +4,7 @@ use 5.006; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Scalar::Util qw/blessed reftype weaken/; @@ -261,8 +261,8 @@ sub child { sub finalize { my $self = shift; - my $ok = 1; - ($ok) = @_ if @_; + my $end_hub = 1; + ($end_hub) = @_ if @_; my $st_ctx = $self->ctx; my $chub = $self->{Hub} || return $st_ctx->release; @@ -284,7 +284,7 @@ sub finalize { delete $ctx->hub->meta(__PACKAGE__, {})->{child}; $chub->finalize($trace->snapshot(hid => $chub->hid, nested => $chub->nested), 1) - if $ok + if $end_hub && $chub->count && !$chub->no_ending && !$chub->ended; @@ -396,6 +396,12 @@ sub subtest { $err = "Subtest ended with exit code $code" if $code; } + # Record the exception inside the subtest so it fails and says why. The + # exception is still rethrown below, this only stops the subtest reporting + # success for code that never finished. + $st_ctx->send_event('Exception', error => $err) + if !$ok && defined($err); + my $st_hub = $st_ctx->hub; my $plan = $st_hub->plan; my $count = $st_hub->count; @@ -405,7 +411,7 @@ sub subtest { $st_ctx->diag('No tests run!'); } - $child->finalize($st_ctx->trace); + $child->finalize; $ctx->release; diff --git a/src/main/perl/lib/Test/Builder/Formatter.pm b/src/main/perl/lib/Test/Builder/Formatter.pm index c2785b665..103d4f8d8 100644 --- a/src/main/perl/lib/Test/Builder/Formatter.pm +++ b/src/main/perl/lib/Test/Builder/Formatter.pm @@ -2,7 +2,7 @@ package Test::Builder::Formatter; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Formatter::TAP; our @ISA = qw(Test2::Formatter::TAP) } diff --git a/src/main/perl/lib/Test/Builder/Module.pm b/src/main/perl/lib/Test/Builder/Module.pm index 2a98f1115..6ee2be024 100644 --- a/src/main/perl/lib/Test/Builder/Module.pm +++ b/src/main/perl/lib/Test/Builder/Module.pm @@ -7,7 +7,7 @@ use Test::Builder; require Exporter; our @ISA = qw(Exporter); -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; =head1 NAME diff --git a/src/main/perl/lib/Test/Builder/Tester.pm b/src/main/perl/lib/Test/Builder/Tester.pm index aad24f1d6..eec356f60 100644 --- a/src/main/perl/lib/Test/Builder/Tester.pm +++ b/src/main/perl/lib/Test/Builder/Tester.pm @@ -1,7 +1,7 @@ package Test::Builder::Tester; use strict; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test::Builder; use Symbol; diff --git a/src/main/perl/lib/Test/Builder/Tester/Color.pm b/src/main/perl/lib/Test/Builder/Tester/Color.pm index ee638e467..c6095f5b6 100644 --- a/src/main/perl/lib/Test/Builder/Tester/Color.pm +++ b/src/main/perl/lib/Test/Builder/Tester/Color.pm @@ -1,7 +1,7 @@ package Test::Builder::Tester::Color; use strict; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; require Test::Builder::Tester; diff --git a/src/main/perl/lib/Test/Builder/TodoDiag.pm b/src/main/perl/lib/Test/Builder/TodoDiag.pm index 5083518f4..a36fd9bf8 100644 --- a/src/main/perl/lib/Test/Builder/TodoDiag.pm +++ b/src/main/perl/lib/Test/Builder/TodoDiag.pm @@ -2,7 +2,7 @@ package Test::Builder::TodoDiag; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event::Diag; our @ISA = qw(Test2::Event::Diag) } diff --git a/src/main/perl/lib/Test/More.pm b/src/main/perl/lib/Test/More.pm index 97c0109db..801a1711a 100644 --- a/src/main/perl/lib/Test/More.pm +++ b/src/main/perl/lib/Test/More.pm @@ -17,7 +17,7 @@ sub _carp { return warn @_, " at $file line $line\n"; } -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test::Builder::Module; our @ISA = qw(Test::Builder::Module); @@ -796,6 +796,10 @@ considered a skip. Returns true if the subtest passed, false otherwise. +If the code dies, the subtest fails and the exception is reported inside it. +The exception is then rethrown, so it still reaches your test file and ends it +the way any other uncaught exception would. + Due to how subtests work, you may omit a plan if you desire. This adds an implicit C to the end of your subtest. The following two subtests are equivalent: diff --git a/src/main/perl/lib/Test/Simple.pm b/src/main/perl/lib/Test/Simple.pm index d32d4049b..9595dd496 100644 --- a/src/main/perl/lib/Test/Simple.pm +++ b/src/main/perl/lib/Test/Simple.pm @@ -4,7 +4,7 @@ use 5.006; use strict; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test::Builder::Module; our @ISA = qw(Test::Builder::Module); diff --git a/src/main/perl/lib/Test/Tester.pm b/src/main/perl/lib/Test/Tester.pm index b345a6221..52c2c4795 100644 --- a/src/main/perl/lib/Test/Tester.pm +++ b/src/main/perl/lib/Test/Tester.pm @@ -16,7 +16,7 @@ use Test::Tester::Delegate; require Exporter; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our @EXPORT = qw( run_tests check_tests check_test cmp_results show_space ); our @ISA = qw( Exporter ); diff --git a/src/main/perl/lib/Test/Tester/Capture.pm b/src/main/perl/lib/Test/Tester/Capture.pm index cbad3e2a7..396d7dd72 100644 --- a/src/main/perl/lib/Test/Tester/Capture.pm +++ b/src/main/perl/lib/Test/Tester/Capture.pm @@ -2,7 +2,7 @@ use strict; package Test::Tester::Capture; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test::Builder; diff --git a/src/main/perl/lib/Test/Tester/CaptureRunner.pm b/src/main/perl/lib/Test/Tester/CaptureRunner.pm index f74ab27ab..26e86cfc8 100644 --- a/src/main/perl/lib/Test/Tester/CaptureRunner.pm +++ b/src/main/perl/lib/Test/Tester/CaptureRunner.pm @@ -3,7 +3,7 @@ use strict; package Test::Tester::CaptureRunner; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test::Tester::Capture; diff --git a/src/main/perl/lib/Test/Tester/Delegate.pm b/src/main/perl/lib/Test/Tester/Delegate.pm index 4836c40ba..ed67e0c66 100644 --- a/src/main/perl/lib/Test/Tester/Delegate.pm +++ b/src/main/perl/lib/Test/Tester/Delegate.pm @@ -3,7 +3,7 @@ use warnings; package Test::Tester::Delegate; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Scalar::Util(); diff --git a/src/main/perl/lib/Test/use/ok.pm b/src/main/perl/lib/Test/use/ok.pm index 564049702..9cc54a3ef 100644 --- a/src/main/perl/lib/Test/use/ok.pm +++ b/src/main/perl/lib/Test/use/ok.pm @@ -1,7 +1,7 @@ package Test::use::ok; use 5.005; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; __END__ diff --git a/src/main/perl/lib/Test2.pm b/src/main/perl/lib/Test2.pm index d8dbee0eb..2def84ec8 100644 --- a/src/main/perl/lib/Test2.pm +++ b/src/main/perl/lib/Test2.pm @@ -2,7 +2,7 @@ package Test2; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/API.pm b/src/main/perl/lib/Test2/API.pm index 42a382213..aa2d540b5 100644 --- a/src/main/perl/lib/Test2/API.pm +++ b/src/main/perl/lib/Test2/API.pm @@ -10,7 +10,7 @@ BEGIN { $ENV{TEST2_ACTIVE} = 1; } -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; my $INST; @@ -1213,7 +1213,7 @@ It will execute the codeblock, intercepting any generated events in the process. It will return an array reference with all the generated event objects. All events should be subclasses of L. -As of version 1.302178 the events array that is returned is blssed as an +As of version 1.302178 the events array that is returned is blessed as an L instance. L Provides a helpful interface for filtering and/or inspecting the events list overall, or individual events within the list. diff --git a/src/main/perl/lib/Test2/API/Breakage.pm b/src/main/perl/lib/Test2/API/Breakage.pm index 5cf84cf67..04e9cd92c 100644 --- a/src/main/perl/lib/Test2/API/Breakage.pm +++ b/src/main/perl/lib/Test2/API/Breakage.pm @@ -2,7 +2,7 @@ package Test2::API::Breakage; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util qw/pkg_to_file/; diff --git a/src/main/perl/lib/Test2/API/Context.pm b/src/main/perl/lib/Test2/API/Context.pm index 00ab410a5..050705697 100644 --- a/src/main/perl/lib/Test2/API/Context.pm +++ b/src/main/perl/lib/Test2/API/Context.pm @@ -2,7 +2,7 @@ package Test2::API::Context; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/confess croak/; diff --git a/src/main/perl/lib/Test2/API/Instance.pm b/src/main/perl/lib/Test2/API/Instance.pm index 42795f906..a39e8abb4 100644 --- a/src/main/perl/lib/Test2/API/Instance.pm +++ b/src/main/perl/lib/Test2/API/Instance.pm @@ -2,7 +2,7 @@ package Test2::API::Instance; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our @CARP_NOT = qw/Test2::API Test2::API::Instance Test2::IPC::Driver Test2::Formatter/; use Carp qw/confess carp/; diff --git a/src/main/perl/lib/Test2/API/InterceptResult.pm b/src/main/perl/lib/Test2/API/InterceptResult.pm index 2f6faf9b5..4d162e3dc 100644 --- a/src/main/perl/lib/Test2/API/InterceptResult.pm +++ b/src/main/perl/lib/Test2/API/InterceptResult.pm @@ -2,7 +2,7 @@ package Test2::API::InterceptResult; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Scalar::Util qw/blessed/; use Test2::Util qw/pkg_to_file/; diff --git a/src/main/perl/lib/Test2/API/InterceptResult/Event.pm b/src/main/perl/lib/Test2/API/InterceptResult/Event.pm index f5e0ad8f8..af904489c 100644 --- a/src/main/perl/lib/Test2/API/InterceptResult/Event.pm +++ b/src/main/perl/lib/Test2/API/InterceptResult/Event.pm @@ -2,7 +2,7 @@ package Test2::API::InterceptResult::Event; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use List::Util qw/first/; use Test2::Util qw/pkg_to_file/; @@ -907,7 +907,7 @@ Returns an empty list if no assertion is present. =item $bool = $event->has_subtest -True if a subetest is present in this event. +True if a subtest is present in this event. =item $undef_or_hashref = $event->the_subtest diff --git a/src/main/perl/lib/Test2/API/InterceptResult/Facet.pm b/src/main/perl/lib/Test2/API/InterceptResult/Facet.pm index ffe2a7fa5..7ca1276d8 100644 --- a/src/main/perl/lib/Test2/API/InterceptResult/Facet.pm +++ b/src/main/perl/lib/Test2/API/InterceptResult/Facet.pm @@ -2,7 +2,7 @@ package Test2::API::InterceptResult::Facet; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::EventFacet; diff --git a/src/main/perl/lib/Test2/API/InterceptResult/Hub.pm b/src/main/perl/lib/Test2/API/InterceptResult/Hub.pm index 6170ec999..6bb2cfa54 100644 --- a/src/main/perl/lib/Test2/API/InterceptResult/Hub.pm +++ b/src/main/perl/lib/Test2/API/InterceptResult/Hub.pm @@ -2,7 +2,7 @@ package Test2::API::InterceptResult::Hub; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Hub; our @ISA = qw(Test2::Hub) } use Test2::Util::HashBase; diff --git a/src/main/perl/lib/Test2/API/InterceptResult/Squasher.pm b/src/main/perl/lib/Test2/API/InterceptResult/Squasher.pm index 92aeb04b9..301cab0d8 100644 --- a/src/main/perl/lib/Test2/API/InterceptResult/Squasher.pm +++ b/src/main/perl/lib/Test2/API/InterceptResult/Squasher.pm @@ -2,7 +2,7 @@ package Test2::API::InterceptResult::Squasher; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; use List::Util qw/first/; diff --git a/src/main/perl/lib/Test2/API/Stack.pm b/src/main/perl/lib/Test2/API/Stack.pm index 049b3efd1..d6ed1c8a0 100644 --- a/src/main/perl/lib/Test2/API/Stack.pm +++ b/src/main/perl/lib/Test2/API/Stack.pm @@ -2,7 +2,7 @@ package Test2::API::Stack; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Hub(); diff --git a/src/main/perl/lib/Test2/AsyncSubtest.pm b/src/main/perl/lib/Test2/AsyncSubtest.pm index fe7328152..af2a179ac 100644 --- a/src/main/perl/lib/Test2/AsyncSubtest.pm +++ b/src/main/perl/lib/Test2/AsyncSubtest.pm @@ -4,7 +4,7 @@ use warnings; use Test2::IPC; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our @CARP_NOT = qw/Test2::Util::HashBase/; diff --git a/src/main/perl/lib/Test2/AsyncSubtest/Event/Attach.pm b/src/main/perl/lib/Test2/AsyncSubtest/Event/Attach.pm index 82e0c939f..c47d6712e 100644 --- a/src/main/perl/lib/Test2/AsyncSubtest/Event/Attach.pm +++ b/src/main/perl/lib/Test2/AsyncSubtest/Event/Attach.pm @@ -2,7 +2,7 @@ package Test2::AsyncSubtest::Event::Attach; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use base 'Test2::Event'; use Test2::Util::HashBase qw/id/; diff --git a/src/main/perl/lib/Test2/AsyncSubtest/Event/Detach.pm b/src/main/perl/lib/Test2/AsyncSubtest/Event/Detach.pm index d0b565df1..f5d2892e8 100644 --- a/src/main/perl/lib/Test2/AsyncSubtest/Event/Detach.pm +++ b/src/main/perl/lib/Test2/AsyncSubtest/Event/Detach.pm @@ -2,7 +2,7 @@ package Test2::AsyncSubtest::Event::Detach; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use base 'Test2::Event'; use Test2::Util::HashBase qw/id/; diff --git a/src/main/perl/lib/Test2/AsyncSubtest/Formatter.pm b/src/main/perl/lib/Test2/AsyncSubtest/Formatter.pm index 6b182a3a0..14cddc394 100644 --- a/src/main/perl/lib/Test2/AsyncSubtest/Formatter.pm +++ b/src/main/perl/lib/Test2/AsyncSubtest/Formatter.pm @@ -2,7 +2,7 @@ package Test2::AsyncSubtest::Formatter; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; die "Should not load this anymore"; diff --git a/src/main/perl/lib/Test2/AsyncSubtest/Hub.pm b/src/main/perl/lib/Test2/AsyncSubtest/Hub.pm index c740e44b5..dd5305aff 100644 --- a/src/main/perl/lib/Test2/AsyncSubtest/Hub.pm +++ b/src/main/perl/lib/Test2/AsyncSubtest/Hub.pm @@ -2,7 +2,7 @@ package Test2::AsyncSubtest::Hub; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use base 'Test2::Hub::Subtest'; use Test2::Util::HashBase qw/ast_ids ast/; diff --git a/src/main/perl/lib/Test2/Bundle.pm b/src/main/perl/lib/Test2/Bundle.pm index f8a32d42c..03c2fb953 100644 --- a/src/main/perl/lib/Test2/Bundle.pm +++ b/src/main/perl/lib/Test2/Bundle.pm @@ -2,7 +2,7 @@ package Test2::Bundle; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Bundle/Extended.pm b/src/main/perl/lib/Test2/Bundle/Extended.pm index 75fc1e9bf..31ededf44 100644 --- a/src/main/perl/lib/Test2/Bundle/Extended.pm +++ b/src/main/perl/lib/Test2/Bundle/Extended.pm @@ -4,7 +4,7 @@ use warnings; use Test2::V0; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { push @Test2::Bundle::Extended::ISA => 'Test2::V0'; diff --git a/src/main/perl/lib/Test2/Bundle/More.pm b/src/main/perl/lib/Test2/Bundle/More.pm index f3cc1e924..514044ca5 100644 --- a/src/main/perl/lib/Test2/Bundle/More.pm +++ b/src/main/perl/lib/Test2/Bundle/More.pm @@ -2,7 +2,7 @@ package Test2::Bundle::More; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Plugin::ExitSummary; diff --git a/src/main/perl/lib/Test2/Bundle/Simple.pm b/src/main/perl/lib/Test2/Bundle/Simple.pm index 4d13fb5d1..d21dab92c 100644 --- a/src/main/perl/lib/Test2/Bundle/Simple.pm +++ b/src/main/perl/lib/Test2/Bundle/Simple.pm @@ -2,7 +2,7 @@ package Test2::Bundle::Simple; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Plugin::ExitSummary; diff --git a/src/main/perl/lib/Test2/Compare.pm b/src/main/perl/lib/Test2/Compare.pm index b3e189601..2be0e4e24 100644 --- a/src/main/perl/lib/Test2/Compare.pm +++ b/src/main/perl/lib/Test2/Compare.pm @@ -2,7 +2,7 @@ package Test2::Compare; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Scalar::Util qw/blessed/; use Test2::Util qw/try/; @@ -58,6 +58,8 @@ sub build { pop @BUILD; die $err unless $ok; + $build->verify_build; + return $build; } @@ -245,7 +247,9 @@ passed in is different from the current global. =item build($class, sub { ... }) Run the provided codeblock with a new instance of C<$class> as the current -build. Returns the new build. +build. Returns the new build. Once the codeblock has run, C is +called on the new build, so a class that rejects a combination of build +directives can throw from there. =item $check = convert($thing) diff --git a/src/main/perl/lib/Test2/Compare/Array.pm b/src/main/perl/lib/Test2/Compare/Array.pm index a7da57b60..699ca703a 100644 --- a/src/main/perl/lib/Test2/Compare/Array.pm +++ b/src/main/perl/lib/Test2/Compare/Array.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/inref meta ending items order for_each/; @@ -106,6 +106,16 @@ sub add_for_each { push @{$self->{+FOR_EACH}} => @_; } +sub verify_build { + my $self = shift; + + return unless @{$self->{+FOR_EACH}}; + return unless $self->{+ENDING}; + return if keys %{$self->{+ITEMS}}; + + $self->throw_build_error("'end' with no items specified requires an empty array, which discards the 'all_items' checks; use 'etc' instead of 'end' to check every item without bounding the array"); +} + sub deltas { my $self = shift; my %params = @_; diff --git a/src/main/perl/lib/Test2/Compare/Bag.pm b/src/main/perl/lib/Test2/Compare/Bag.pm index 5203b1817..e2f14304b 100644 --- a/src/main/perl/lib/Test2/Compare/Bag.pm +++ b/src/main/perl/lib/Test2/Compare/Bag.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/ending meta items for_each/; @@ -54,6 +54,16 @@ sub add_for_each { push @{$self->{+FOR_EACH}} => @_; } +sub verify_build { + my $self = shift; + + return unless @{$self->{+FOR_EACH}}; + return unless $self->{+ENDING}; + return if @{$self->{+ITEMS}}; + + $self->throw_build_error("'end' with no items specified requires an empty bag, which discards the 'all_items' checks; use 'etc' instead of 'end' to check every item without bounding the bag"); +} + sub deltas { my $self = shift; my %params = @_; @@ -109,9 +119,6 @@ sub deltas { my @checks = map { $convert->($_) } @for_each; for my $idx (0..$#list) { - # All items are matched if we have conditions for all items - delete $unmatched{$idx}; - my $val = $list[$idx]; for my $check (@checks) { diff --git a/src/main/perl/lib/Test2/Compare/Base.pm b/src/main/perl/lib/Test2/Compare/Base.pm index 25324e302..908cafc7b 100644 --- a/src/main/perl/lib/Test2/Compare/Base.pm +++ b/src/main/perl/lib/Test2/Compare/Base.pm @@ -2,7 +2,7 @@ package Test2::Compare::Base; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/confess croak/; use Scalar::Util qw/blessed/; @@ -69,6 +69,19 @@ sub delta_class { 'Test2::Compare::Delta' } sub deltas { () } sub got_lines { () } +sub verify_build { } + +sub throw_build_error { + my $self = shift; + my ($msg) = @_; + + my $file = $self->file || 'unknown file'; + my $lines = $self->lines; + my $line = $lines && @$lines ? $lines->[0] : 0; + + die "$msg at $file line $line.\n"; +} + sub stringify_got { 0 } sub operator { '' } @@ -207,6 +220,18 @@ checks are done in C<< $check->deltas() >>. Get the name of the check. +=item $check->verify_build() + +Called on every check built by a builder block once the block has run. This +base class does nothing; a subclass may override it to reject a combination of +build directives that cannot do anything useful, and should use +C<< $check->throw_build_error($msg) >> to report the problem. + +=item $check->throw_build_error($msg) + +Throw an exception reporting C<$msg> against the file and line of the builder +block the check came from. + =item $display = $check->render What should be displayed in a table for this check, usually the name or value. diff --git a/src/main/perl/lib/Test2/Compare/Bool.pm b/src/main/perl/lib/Test2/Compare/Bool.pm index 747d692c2..823d2c8ab 100644 --- a/src/main/perl/lib/Test2/Compare/Bool.pm +++ b/src/main/perl/lib/Test2/Compare/Bool.pm @@ -6,7 +6,7 @@ use Carp qw/confess/; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/input/; diff --git a/src/main/perl/lib/Test2/Compare/Custom.pm b/src/main/perl/lib/Test2/Compare/Custom.pm index 693ddfda7..d48b3594e 100644 --- a/src/main/perl/lib/Test2/Compare/Custom.pm +++ b/src/main/perl/lib/Test2/Compare/Custom.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/code name operator stringify_got/; diff --git a/src/main/perl/lib/Test2/Compare/DeepRef.pm b/src/main/perl/lib/Test2/Compare/DeepRef.pm index 9d5e39b98..a7f917245 100644 --- a/src/main/perl/lib/Test2/Compare/DeepRef.pm +++ b/src/main/perl/lib/Test2/Compare/DeepRef.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/input/; diff --git a/src/main/perl/lib/Test2/Compare/Delta.pm b/src/main/perl/lib/Test2/Compare/Delta.pm index 25d2545f2..9286d2792 100644 --- a/src/main/perl/lib/Test2/Compare/Delta.pm +++ b/src/main/perl/lib/Test2/Compare/Delta.pm @@ -2,7 +2,7 @@ package Test2::Compare::Delta; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw{verified id got chk children dne exception note}; diff --git a/src/main/perl/lib/Test2/Compare/Event.pm b/src/main/perl/lib/Test2/Compare/Event.pm index 73addc1ae..7d9f8c524 100644 --- a/src/main/perl/lib/Test2/Compare/Event.pm +++ b/src/main/perl/lib/Test2/Compare/Event.pm @@ -8,7 +8,7 @@ use Test2::Compare::EventMeta(); use base 'Test2::Compare::Object'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/etype/; diff --git a/src/main/perl/lib/Test2/Compare/EventMeta.pm b/src/main/perl/lib/Test2/Compare/EventMeta.pm index 2f232fe37..82ad8d161 100644 --- a/src/main/perl/lib/Test2/Compare/EventMeta.pm +++ b/src/main/perl/lib/Test2/Compare/EventMeta.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Meta'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase; diff --git a/src/main/perl/lib/Test2/Compare/Float.pm b/src/main/perl/lib/Test2/Compare/Float.pm index 30a5f3944..1018103b8 100644 --- a/src/main/perl/lib/Test2/Compare/Float.pm +++ b/src/main/perl/lib/Test2/Compare/Float.pm @@ -6,7 +6,7 @@ use Carp qw/confess/; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our $DEFAULT_TOLERANCE = 1e-08; diff --git a/src/main/perl/lib/Test2/Compare/Hash.pm b/src/main/perl/lib/Test2/Compare/Hash.pm index 785ced93f..2b962d2ba 100644 --- a/src/main/perl/lib/Test2/Compare/Hash.pm +++ b/src/main/perl/lib/Test2/Compare/Hash.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/inref meta ending items order for_each_key for_each_val/; @@ -87,6 +87,16 @@ sub add_for_each_val { push @{$self->{+FOR_EACH_VAL}} => @_; } +sub verify_build { + my $self = shift; + + return unless @{$self->{+FOR_EACH_KEY}} || @{$self->{+FOR_EACH_VAL}}; + return unless $self->{+ENDING}; + return if keys %{$self->{+ITEMS}}; + + $self->throw_build_error("'end' with no fields specified requires an empty hash, which discards the 'all_keys' and 'all_values' checks; use 'etc' instead of 'end' to check every key and value without bounding the hash"); +} + sub deltas { my $self = shift; my %params = @_; diff --git a/src/main/perl/lib/Test2/Compare/Isa.pm b/src/main/perl/lib/Test2/Compare/Isa.pm index 1c0a43dac..076d16658 100644 --- a/src/main/perl/lib/Test2/Compare/Isa.pm +++ b/src/main/perl/lib/Test2/Compare/Isa.pm @@ -7,7 +7,7 @@ use Scalar::Util qw/blessed/; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/input/; diff --git a/src/main/perl/lib/Test2/Compare/Meta.pm b/src/main/perl/lib/Test2/Compare/Meta.pm index 0d6fbbc49..499e2b152 100644 --- a/src/main/perl/lib/Test2/Compare/Meta.pm +++ b/src/main/perl/lib/Test2/Compare/Meta.pm @@ -7,7 +7,7 @@ use Test2::Compare::Isa(); use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/items/; diff --git a/src/main/perl/lib/Test2/Compare/Negatable.pm b/src/main/perl/lib/Test2/Compare/Negatable.pm index e830b4669..ab5b5d5a6 100644 --- a/src/main/perl/lib/Test2/Compare/Negatable.pm +++ b/src/main/perl/lib/Test2/Compare/Negatable.pm @@ -2,7 +2,7 @@ package Test2::Compare::Negatable; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; require overload; require Test2::Util::HashBase; diff --git a/src/main/perl/lib/Test2/Compare/Number.pm b/src/main/perl/lib/Test2/Compare/Number.pm index 558362540..b22a07454 100644 --- a/src/main/perl/lib/Test2/Compare/Number.pm +++ b/src/main/perl/lib/Test2/Compare/Number.pm @@ -6,7 +6,7 @@ use Carp qw/confess/; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/input mode/; diff --git a/src/main/perl/lib/Test2/Compare/Object.pm b/src/main/perl/lib/Test2/Compare/Object.pm index 5f1e407d2..4a86db3b1 100644 --- a/src/main/perl/lib/Test2/Compare/Object.pm +++ b/src/main/perl/lib/Test2/Compare/Object.pm @@ -8,7 +8,7 @@ use Test2::Compare::Meta(); use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/calls meta refcheck ending/; diff --git a/src/main/perl/lib/Test2/Compare/OrderedSubset.pm b/src/main/perl/lib/Test2/Compare/OrderedSubset.pm index e7aadbd0e..bf2e327f3 100644 --- a/src/main/perl/lib/Test2/Compare/OrderedSubset.pm +++ b/src/main/perl/lib/Test2/Compare/OrderedSubset.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/inref items/; diff --git a/src/main/perl/lib/Test2/Compare/Pattern.pm b/src/main/perl/lib/Test2/Compare/Pattern.pm index 25e1c2194..109a857f4 100644 --- a/src/main/perl/lib/Test2/Compare/Pattern.pm +++ b/src/main/perl/lib/Test2/Compare/Pattern.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/pattern stringify_got/; diff --git a/src/main/perl/lib/Test2/Compare/Ref.pm b/src/main/perl/lib/Test2/Compare/Ref.pm index 360ffa3e7..281881c74 100644 --- a/src/main/perl/lib/Test2/Compare/Ref.pm +++ b/src/main/perl/lib/Test2/Compare/Ref.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/input/; diff --git a/src/main/perl/lib/Test2/Compare/Regex.pm b/src/main/perl/lib/Test2/Compare/Regex.pm index 483031bd5..da1b23d42 100644 --- a/src/main/perl/lib/Test2/Compare/Regex.pm +++ b/src/main/perl/lib/Test2/Compare/Regex.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/input/; diff --git a/src/main/perl/lib/Test2/Compare/Scalar.pm b/src/main/perl/lib/Test2/Compare/Scalar.pm index 7e6f6f962..af8d4ecbe 100644 --- a/src/main/perl/lib/Test2/Compare/Scalar.pm +++ b/src/main/perl/lib/Test2/Compare/Scalar.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/item/; diff --git a/src/main/perl/lib/Test2/Compare/Set.pm b/src/main/perl/lib/Test2/Compare/Set.pm index 837bba3d7..33a5384f8 100644 --- a/src/main/perl/lib/Test2/Compare/Set.pm +++ b/src/main/perl/lib/Test2/Compare/Set.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/checks _reduction/; diff --git a/src/main/perl/lib/Test2/Compare/String.pm b/src/main/perl/lib/Test2/Compare/String.pm index 7c4b04648..9158c1787 100644 --- a/src/main/perl/lib/Test2/Compare/String.pm +++ b/src/main/perl/lib/Test2/Compare/String.pm @@ -6,7 +6,7 @@ use Carp qw/confess/; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/input/; diff --git a/src/main/perl/lib/Test2/Compare/Undef.pm b/src/main/perl/lib/Test2/Compare/Undef.pm index 7f21e1c3a..3edc0488c 100644 --- a/src/main/perl/lib/Test2/Compare/Undef.pm +++ b/src/main/perl/lib/Test2/Compare/Undef.pm @@ -6,7 +6,7 @@ use Carp qw/confess/; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase; diff --git a/src/main/perl/lib/Test2/Compare/Wildcard.pm b/src/main/perl/lib/Test2/Compare/Wildcard.pm index c220b71e7..9875024ad 100644 --- a/src/main/perl/lib/Test2/Compare/Wildcard.pm +++ b/src/main/perl/lib/Test2/Compare/Wildcard.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Compare::Base'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/expect/; diff --git a/src/main/perl/lib/Test2/Env.pm b/src/main/perl/lib/Test2/Env.pm index 9fe3b351c..b5c2c8920 100644 --- a/src/main/perl/lib/Test2/Env.pm +++ b/src/main/perl/lib/Test2/Env.pm @@ -2,7 +2,7 @@ package Test2::Env; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Event.pm b/src/main/perl/lib/Test2/Event.pm index 16fe45140..90ef94a9a 100644 --- a/src/main/perl/lib/Test2/Event.pm +++ b/src/main/perl/lib/Test2/Event.pm @@ -2,7 +2,7 @@ package Test2::Event; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Scalar::Util qw/blessed reftype/; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Event/Bail.pm b/src/main/perl/lib/Test2/Event/Bail.pm index afd21b479..0f44b3569 100644 --- a/src/main/perl/lib/Test2/Event/Bail.pm +++ b/src/main/perl/lib/Test2/Event/Bail.pm @@ -2,7 +2,7 @@ package Test2::Event::Bail; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) } diff --git a/src/main/perl/lib/Test2/Event/Diag.pm b/src/main/perl/lib/Test2/Event/Diag.pm index 882a2b165..38d64f5ba 100644 --- a/src/main/perl/lib/Test2/Event/Diag.pm +++ b/src/main/perl/lib/Test2/Event/Diag.pm @@ -2,7 +2,7 @@ package Test2::Event::Diag; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) } diff --git a/src/main/perl/lib/Test2/Event/Encoding.pm b/src/main/perl/lib/Test2/Event/Encoding.pm index bba0a404c..ddcc50792 100644 --- a/src/main/perl/lib/Test2/Event/Encoding.pm +++ b/src/main/perl/lib/Test2/Event/Encoding.pm @@ -2,7 +2,7 @@ package Test2::Event::Encoding; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Event/Exception.pm b/src/main/perl/lib/Test2/Event/Exception.pm index 0ff33ecb6..91cc7f2d5 100644 --- a/src/main/perl/lib/Test2/Event/Exception.pm +++ b/src/main/perl/lib/Test2/Event/Exception.pm @@ -2,7 +2,7 @@ package Test2::Event::Exception; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) } diff --git a/src/main/perl/lib/Test2/Event/Fail.pm b/src/main/perl/lib/Test2/Event/Fail.pm index 30102dae8..1a7b4c92a 100644 --- a/src/main/perl/lib/Test2/Event/Fail.pm +++ b/src/main/perl/lib/Test2/Event/Fail.pm @@ -2,7 +2,7 @@ package Test2::Event::Fail; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::EventFacet::Info; diff --git a/src/main/perl/lib/Test2/Event/Generic.pm b/src/main/perl/lib/Test2/Event/Generic.pm index f702b4ae3..51770c6e2 100644 --- a/src/main/perl/lib/Test2/Event/Generic.pm +++ b/src/main/perl/lib/Test2/Event/Generic.pm @@ -5,7 +5,7 @@ use warnings; use Carp qw/croak/; use Scalar::Util qw/reftype/; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) } use Test2::Util::HashBase; diff --git a/src/main/perl/lib/Test2/Event/Note.pm b/src/main/perl/lib/Test2/Event/Note.pm index b07009d4c..d549794ae 100644 --- a/src/main/perl/lib/Test2/Event/Note.pm +++ b/src/main/perl/lib/Test2/Event/Note.pm @@ -2,7 +2,7 @@ package Test2::Event::Note; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) } diff --git a/src/main/perl/lib/Test2/Event/Ok.pm b/src/main/perl/lib/Test2/Event/Ok.pm index e52c89212..60f6e6205 100644 --- a/src/main/perl/lib/Test2/Event/Ok.pm +++ b/src/main/perl/lib/Test2/Event/Ok.pm @@ -2,7 +2,7 @@ package Test2::Event::Ok; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) } diff --git a/src/main/perl/lib/Test2/Event/Pass.pm b/src/main/perl/lib/Test2/Event/Pass.pm index aaf59f662..173644a08 100644 --- a/src/main/perl/lib/Test2/Event/Pass.pm +++ b/src/main/perl/lib/Test2/Event/Pass.pm @@ -2,7 +2,7 @@ package Test2::Event::Pass; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::EventFacet::Info; diff --git a/src/main/perl/lib/Test2/Event/Plan.pm b/src/main/perl/lib/Test2/Event/Plan.pm index 126a41eb1..789d8e84c 100644 --- a/src/main/perl/lib/Test2/Event/Plan.pm +++ b/src/main/perl/lib/Test2/Event/Plan.pm @@ -2,7 +2,7 @@ package Test2::Event::Plan; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) } diff --git a/src/main/perl/lib/Test2/Event/Skip.pm b/src/main/perl/lib/Test2/Event/Skip.pm index dcd3c9881..d58a51258 100644 --- a/src/main/perl/lib/Test2/Event/Skip.pm +++ b/src/main/perl/lib/Test2/Event/Skip.pm @@ -2,7 +2,7 @@ package Test2::Event::Skip; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event::Ok; our @ISA = qw(Test2::Event::Ok) } diff --git a/src/main/perl/lib/Test2/Event/Subtest.pm b/src/main/perl/lib/Test2/Event/Subtest.pm index 0abadfb50..0fdb8d0aa 100644 --- a/src/main/perl/lib/Test2/Event/Subtest.pm +++ b/src/main/perl/lib/Test2/Event/Subtest.pm @@ -2,7 +2,7 @@ package Test2::Event::Subtest; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event::Ok; our @ISA = qw(Test2::Event::Ok) } use Test2::Util::HashBase qw{subevents buffered subtest_id subtest_uuid start_stamp stop_stamp}; diff --git a/src/main/perl/lib/Test2/Event/TAP/Version.pm b/src/main/perl/lib/Test2/Event/TAP/Version.pm index 07764af66..18143d850 100644 --- a/src/main/perl/lib/Test2/Event/TAP/Version.pm +++ b/src/main/perl/lib/Test2/Event/TAP/Version.pm @@ -2,7 +2,7 @@ package Test2::Event::TAP::Version; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Event/V2.pm b/src/main/perl/lib/Test2/Event/V2.pm index 9b54a19b2..38318a150 100644 --- a/src/main/perl/lib/Test2/Event/V2.pm +++ b/src/main/perl/lib/Test2/Event/V2.pm @@ -2,7 +2,7 @@ package Test2::Event::V2; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Scalar::Util qw/reftype/; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Event/Waiting.pm b/src/main/perl/lib/Test2/Event/Waiting.pm index c8460efa5..2d11012c2 100644 --- a/src/main/perl/lib/Test2/Event/Waiting.pm +++ b/src/main/perl/lib/Test2/Event/Waiting.pm @@ -2,7 +2,7 @@ package Test2::Event::Waiting; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Event; our @ISA = qw(Test2::Event) } diff --git a/src/main/perl/lib/Test2/EventFacet.pm b/src/main/perl/lib/Test2/EventFacet.pm index d0b2810f2..d9c1abb34 100644 --- a/src/main/perl/lib/Test2/EventFacet.pm +++ b/src/main/perl/lib/Test2/EventFacet.pm @@ -2,7 +2,7 @@ package Test2::EventFacet; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/-details/; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/EventFacet/About.pm b/src/main/perl/lib/Test2/EventFacet/About.pm index 78d056840..351a28ee3 100644 --- a/src/main/perl/lib/Test2/EventFacet/About.pm +++ b/src/main/perl/lib/Test2/EventFacet/About.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::About; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) } use Test2::Util::HashBase qw{ -package -no_display -uuid -eid }; diff --git a/src/main/perl/lib/Test2/EventFacet/Amnesty.pm b/src/main/perl/lib/Test2/EventFacet/Amnesty.pm index f0f52374e..e23b2be30 100644 --- a/src/main/perl/lib/Test2/EventFacet/Amnesty.pm +++ b/src/main/perl/lib/Test2/EventFacet/Amnesty.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Amnesty; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub is_list { 1 } diff --git a/src/main/perl/lib/Test2/EventFacet/Assert.pm b/src/main/perl/lib/Test2/EventFacet/Assert.pm index 3b927077e..22d3d0233 100644 --- a/src/main/perl/lib/Test2/EventFacet/Assert.pm +++ b/src/main/perl/lib/Test2/EventFacet/Assert.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Assert; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) } use Test2::Util::HashBase qw{ -pass -no_debug -number }; diff --git a/src/main/perl/lib/Test2/EventFacet/Control.pm b/src/main/perl/lib/Test2/EventFacet/Control.pm index 2b49abf66..25bd044f9 100644 --- a/src/main/perl/lib/Test2/EventFacet/Control.pm +++ b/src/main/perl/lib/Test2/EventFacet/Control.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Control; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) } use Test2::Util::HashBase qw{ -global -terminate -halt -has_callback -encoding -phase }; diff --git a/src/main/perl/lib/Test2/EventFacet/Error.pm b/src/main/perl/lib/Test2/EventFacet/Error.pm index a7090d86b..5816fc79c 100644 --- a/src/main/perl/lib/Test2/EventFacet/Error.pm +++ b/src/main/perl/lib/Test2/EventFacet/Error.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Error; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub facet_key { 'errors' } sub is_list { 1 } diff --git a/src/main/perl/lib/Test2/EventFacet/Hub.pm b/src/main/perl/lib/Test2/EventFacet/Hub.pm index d4831ff5c..570003a61 100644 --- a/src/main/perl/lib/Test2/EventFacet/Hub.pm +++ b/src/main/perl/lib/Test2/EventFacet/Hub.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Hub; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub is_list { 1 } sub facet_key { 'hubs' } diff --git a/src/main/perl/lib/Test2/EventFacet/Info.pm b/src/main/perl/lib/Test2/EventFacet/Info.pm index af6f61ede..92640ecb9 100644 --- a/src/main/perl/lib/Test2/EventFacet/Info.pm +++ b/src/main/perl/lib/Test2/EventFacet/Info.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Info; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub is_list { 1 } diff --git a/src/main/perl/lib/Test2/EventFacet/Info/Table.pm b/src/main/perl/lib/Test2/EventFacet/Info/Table.pm index d4a642ee5..bc55c741d 100644 --- a/src/main/perl/lib/Test2/EventFacet/Info/Table.pm +++ b/src/main/perl/lib/Test2/EventFacet/Info/Table.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Info::Table; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/confess/; diff --git a/src/main/perl/lib/Test2/EventFacet/Meta.pm b/src/main/perl/lib/Test2/EventFacet/Meta.pm index 66a73691a..32987faa4 100644 --- a/src/main/perl/lib/Test2/EventFacet/Meta.pm +++ b/src/main/perl/lib/Test2/EventFacet/Meta.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Meta; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) } diff --git a/src/main/perl/lib/Test2/EventFacet/Parent.pm b/src/main/perl/lib/Test2/EventFacet/Parent.pm index db67bd883..503e8b5bc 100644 --- a/src/main/perl/lib/Test2/EventFacet/Parent.pm +++ b/src/main/perl/lib/Test2/EventFacet/Parent.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Parent; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/confess/; diff --git a/src/main/perl/lib/Test2/EventFacet/Plan.pm b/src/main/perl/lib/Test2/EventFacet/Plan.pm index 9df4e3451..529d838e4 100644 --- a/src/main/perl/lib/Test2/EventFacet/Plan.pm +++ b/src/main/perl/lib/Test2/EventFacet/Plan.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Plan; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) } use Test2::Util::HashBase qw{ -count -skip -none }; diff --git a/src/main/perl/lib/Test2/EventFacet/Render.pm b/src/main/perl/lib/Test2/EventFacet/Render.pm index 2ccdf879e..ca2189fb6 100644 --- a/src/main/perl/lib/Test2/EventFacet/Render.pm +++ b/src/main/perl/lib/Test2/EventFacet/Render.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Render; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub is_list { 1 } diff --git a/src/main/perl/lib/Test2/EventFacet/Trace.pm b/src/main/perl/lib/Test2/EventFacet/Trace.pm index 69cad3146..ad9e28630 100644 --- a/src/main/perl/lib/Test2/EventFacet/Trace.pm +++ b/src/main/perl/lib/Test2/EventFacet/Trace.pm @@ -2,7 +2,7 @@ package Test2::EventFacet::Trace; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::EventFacet; our @ISA = qw(Test2::EventFacet) } diff --git a/src/main/perl/lib/Test2/Formatter.pm b/src/main/perl/lib/Test2/Formatter.pm index 0f862cf33..3630489a5 100644 --- a/src/main/perl/lib/Test2/Formatter.pm +++ b/src/main/perl/lib/Test2/Formatter.pm @@ -2,7 +2,7 @@ package Test2::Formatter; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; my %ADDED; diff --git a/src/main/perl/lib/Test2/Formatter/TAP.pm b/src/main/perl/lib/Test2/Formatter/TAP.pm index 0b615ce06..94e624cc2 100644 --- a/src/main/perl/lib/Test2/Formatter/TAP.pm +++ b/src/main/perl/lib/Test2/Formatter/TAP.pm @@ -2,7 +2,7 @@ package Test2::Formatter::TAP; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util qw/clone_io/; diff --git a/src/main/perl/lib/Test2/Handle.pm b/src/main/perl/lib/Test2/Handle.pm index 4e3bfb695..93b78e891 100644 --- a/src/main/perl/lib/Test2/Handle.pm +++ b/src/main/perl/lib/Test2/Handle.pm @@ -2,7 +2,7 @@ package Test2::Handle; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; require Carp; require Test2::Util; @@ -45,7 +45,7 @@ sub _HANDLE_INCLUDE { my $line = __LINE__ + 3; $self->{+IMPORT} = eval <<" EOT" or die $@; -#line $line ${ \__FILE__ } +#line $line "${ \__FILE__ }" package $ns; sub { my (\$module, \$caller, \@imports) = \@_; @@ -251,11 +251,11 @@ namespace. =item $inst = $class->import() -Used to create a C sub in your namsepace at import. +Used to create a C sub in your namespace at import. =item $inst->init() -Internally used to intialize and validate the handle object. +Internally used to initialize and validate the handle object. =item AUTOLOAD diff --git a/src/main/perl/lib/Test2/Hub.pm b/src/main/perl/lib/Test2/Hub.pm index 52847ce29..b2a6859a8 100644 --- a/src/main/perl/lib/Test2/Hub.pm +++ b/src/main/perl/lib/Test2/Hub.pm @@ -2,7 +2,7 @@ package Test2::Hub; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/carp croak confess/; diff --git a/src/main/perl/lib/Test2/Hub/Interceptor.pm b/src/main/perl/lib/Test2/Hub/Interceptor.pm index d3540ec36..e3a0f7cfd 100644 --- a/src/main/perl/lib/Test2/Hub/Interceptor.pm +++ b/src/main/perl/lib/Test2/Hub/Interceptor.pm @@ -2,7 +2,7 @@ package Test2::Hub::Interceptor; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Hub::Interceptor::Terminator(); diff --git a/src/main/perl/lib/Test2/Hub/Interceptor/Terminator.pm b/src/main/perl/lib/Test2/Hub/Interceptor/Terminator.pm index 86bb388de..1f4e1021d 100644 --- a/src/main/perl/lib/Test2/Hub/Interceptor/Terminator.pm +++ b/src/main/perl/lib/Test2/Hub/Interceptor/Terminator.pm @@ -2,7 +2,7 @@ package Test2::Hub::Interceptor::Terminator; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Hub/Subtest.pm b/src/main/perl/lib/Test2/Hub/Subtest.pm index 888a8a8ba..3bbcfb7af 100644 --- a/src/main/perl/lib/Test2/Hub/Subtest.pm +++ b/src/main/perl/lib/Test2/Hub/Subtest.pm @@ -2,7 +2,7 @@ package Test2::Hub::Subtest; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::Hub; our @ISA = qw(Test2::Hub) } use Test2::Util::HashBase qw/nested exit_code manual_skip_all/; diff --git a/src/main/perl/lib/Test2/IPC.pm b/src/main/perl/lib/Test2/IPC.pm index fd700a9a6..3a7870bde 100644 --- a/src/main/perl/lib/Test2/IPC.pm +++ b/src/main/perl/lib/Test2/IPC.pm @@ -2,7 +2,7 @@ package Test2::IPC; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API::Instance; diff --git a/src/main/perl/lib/Test2/IPC/Driver.pm b/src/main/perl/lib/Test2/IPC/Driver.pm index cfd32db5f..5b17e2a43 100644 --- a/src/main/perl/lib/Test2/IPC/Driver.pm +++ b/src/main/perl/lib/Test2/IPC/Driver.pm @@ -2,7 +2,7 @@ package Test2::IPC::Driver; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/confess/; diff --git a/src/main/perl/lib/Test2/IPC/Driver/Files.pm b/src/main/perl/lib/Test2/IPC/Driver/Files.pm index 8f3d0f13b..f9829a55d 100644 --- a/src/main/perl/lib/Test2/IPC/Driver/Files.pm +++ b/src/main/perl/lib/Test2/IPC/Driver/Files.pm @@ -2,7 +2,7 @@ package Test2::IPC::Driver::Files; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Test2::IPC::Driver; our @ISA = qw(Test2::IPC::Driver) } diff --git a/src/main/perl/lib/Test2/Manual.pm b/src/main/perl/lib/Test2/Manual.pm index 55340876b..5138196cb 100644 --- a/src/main/perl/lib/Test2/Manual.pm +++ b/src/main/perl/lib/Test2/Manual.pm @@ -2,7 +2,7 @@ package Test2::Manual; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Anatomy.pm b/src/main/perl/lib/Test2/Manual/Anatomy.pm index e2902ee93..96e10297a 100644 --- a/src/main/perl/lib/Test2/Manual/Anatomy.pm +++ b/src/main/perl/lib/Test2/Manual/Anatomy.pm @@ -2,7 +2,7 @@ package Test2::Manual::Anatomy; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Anatomy/API.pm b/src/main/perl/lib/Test2/Manual/Anatomy/API.pm index 783622dbf..31b9449be 100644 --- a/src/main/perl/lib/Test2/Manual/Anatomy/API.pm +++ b/src/main/perl/lib/Test2/Manual/Anatomy/API.pm @@ -2,7 +2,7 @@ package Test2::Manual::Anatomy::API; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Anatomy/Context.pm b/src/main/perl/lib/Test2/Manual/Anatomy/Context.pm index c101bbf61..d329cc645 100644 --- a/src/main/perl/lib/Test2/Manual/Anatomy/Context.pm +++ b/src/main/perl/lib/Test2/Manual/Anatomy/Context.pm @@ -2,7 +2,7 @@ package Test2::Manual::Anatomy::Context; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Anatomy/EndToEnd.pm b/src/main/perl/lib/Test2/Manual/Anatomy/EndToEnd.pm index acbaea9af..876a48cc4 100644 --- a/src/main/perl/lib/Test2/Manual/Anatomy/EndToEnd.pm +++ b/src/main/perl/lib/Test2/Manual/Anatomy/EndToEnd.pm @@ -2,7 +2,7 @@ package Test2::Manual::Anatomy::EndToEnd; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Anatomy/Event.pm b/src/main/perl/lib/Test2/Manual/Anatomy/Event.pm index 8315fcd69..3db16c068 100644 --- a/src/main/perl/lib/Test2/Manual/Anatomy/Event.pm +++ b/src/main/perl/lib/Test2/Manual/Anatomy/Event.pm @@ -2,7 +2,7 @@ package Test2::Manual::Anatomy::Event; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Anatomy/Hubs.pm b/src/main/perl/lib/Test2/Manual/Anatomy/Hubs.pm index ae1f0ee89..f30f9b923 100644 --- a/src/main/perl/lib/Test2/Manual/Anatomy/Hubs.pm +++ b/src/main/perl/lib/Test2/Manual/Anatomy/Hubs.pm @@ -2,7 +2,7 @@ package Test2::Manual::Anatomy::Hubs; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Anatomy/IPC.pm b/src/main/perl/lib/Test2/Manual/Anatomy/IPC.pm index 275ed5a1f..711eef77b 100644 --- a/src/main/perl/lib/Test2/Manual/Anatomy/IPC.pm +++ b/src/main/perl/lib/Test2/Manual/Anatomy/IPC.pm @@ -2,7 +2,7 @@ package Test2::Manual::Anatomy::IPC; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Anatomy/Utilities.pm b/src/main/perl/lib/Test2/Manual/Anatomy/Utilities.pm index e115c0f75..446b675e8 100644 --- a/src/main/perl/lib/Test2/Manual/Anatomy/Utilities.pm +++ b/src/main/perl/lib/Test2/Manual/Anatomy/Utilities.pm @@ -2,7 +2,7 @@ package Test2::Manual::Anatomy::Utilities; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Concurrency.pm b/src/main/perl/lib/Test2/Manual/Concurrency.pm index b0834a81e..ecfe2c5a9 100644 --- a/src/main/perl/lib/Test2/Manual/Concurrency.pm +++ b/src/main/perl/lib/Test2/Manual/Concurrency.pm @@ -2,7 +2,7 @@ package Test2::Manual::Concurrency; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Contributing.pm b/src/main/perl/lib/Test2/Manual/Contributing.pm index 5805b8057..121010941 100644 --- a/src/main/perl/lib/Test2/Manual/Contributing.pm +++ b/src/main/perl/lib/Test2/Manual/Contributing.pm @@ -1,6 +1,6 @@ package Test2::Manual::Contributing; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Testing.pm b/src/main/perl/lib/Test2/Manual/Testing.pm index df3d1bbe0..3f823895c 100644 --- a/src/main/perl/lib/Test2/Manual/Testing.pm +++ b/src/main/perl/lib/Test2/Manual/Testing.pm @@ -2,7 +2,7 @@ package Test2::Manual::Testing; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Testing/Introduction.pm b/src/main/perl/lib/Test2/Manual/Testing/Introduction.pm index c29c70c0d..c9f0b4555 100644 --- a/src/main/perl/lib/Test2/Manual/Testing/Introduction.pm +++ b/src/main/perl/lib/Test2/Manual/Testing/Introduction.pm @@ -2,7 +2,7 @@ package Test2::Manual::Testing::Introduction; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; @@ -36,10 +36,10 @@ This is all the boilerplate you need. =over 4 -=item use Test2::V1 -ipP; +=item C This loads a collection of testing tools that will be described later in the -tutorial. See L for more details, but for starters '-ipP' is a good +tutorial. See L for more details, but for starters C<-ipP> is a good set of import flags. If you do not like importing a ton of symbols or enabling pragmas/plugins all diff --git a/src/main/perl/lib/Test2/Manual/Testing/Migrating.pm b/src/main/perl/lib/Test2/Manual/Testing/Migrating.pm index 4e207514b..d353200e0 100644 --- a/src/main/perl/lib/Test2/Manual/Testing/Migrating.pm +++ b/src/main/perl/lib/Test2/Manual/Testing/Migrating.pm @@ -2,7 +2,7 @@ package Test2::Manual::Testing::Migrating; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Testing/Planning.pm b/src/main/perl/lib/Test2/Manual/Testing/Planning.pm index 79d6b9617..4a88c7ef0 100644 --- a/src/main/perl/lib/Test2/Manual/Testing/Planning.pm +++ b/src/main/perl/lib/Test2/Manual/Testing/Planning.pm @@ -2,7 +2,7 @@ package Test2::Manual::Testing::Planning; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Testing/Todo.pm b/src/main/perl/lib/Test2/Manual/Testing/Todo.pm index 08225d768..f12a9e4bc 100644 --- a/src/main/perl/lib/Test2/Manual/Testing/Todo.pm +++ b/src/main/perl/lib/Test2/Manual/Testing/Todo.pm @@ -2,7 +2,7 @@ package Test2::Manual::Testing::Todo; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling.pm b/src/main/perl/lib/Test2/Manual/Tooling.pm index 6d5e69bd0..87f215633 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling.pm @@ -2,7 +2,7 @@ package Test2::Manual::Tooling; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/FirstTool.pm b/src/main/perl/lib/Test2/Manual/Tooling/FirstTool.pm index 25a854c00..a026057f8 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/FirstTool.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/FirstTool.pm @@ -1,6 +1,6 @@ package Test2::Manual::Tooling::FirstTool; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/Formatter.pm b/src/main/perl/lib/Test2/Manual/Tooling/Formatter.pm index a597a68e2..41d9c95a3 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/Formatter.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/Formatter.pm @@ -1,6 +1,6 @@ package Test2::Manual::Tooling::Formatter; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/Nesting.pm b/src/main/perl/lib/Test2/Manual/Tooling/Nesting.pm index 773fa735a..50ea886bf 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/Nesting.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/Nesting.pm @@ -2,7 +2,7 @@ package Test2::Manual::Tooling::Nesting; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/Plugin/TestExit.pm b/src/main/perl/lib/Test2/Manual/Tooling/Plugin/TestExit.pm index 76ce64b76..353341ebe 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/Plugin/TestExit.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/Plugin/TestExit.pm @@ -1,6 +1,6 @@ package Test2::Manual::Tooling::Plugin::TestExit; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/Plugin/TestingDone.pm b/src/main/perl/lib/Test2/Manual/Tooling/Plugin/TestingDone.pm index 9e0191f19..21166ba65 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/Plugin/TestingDone.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/Plugin/TestingDone.pm @@ -1,6 +1,6 @@ package Test2::Manual::Tooling::Plugin::TestingDone; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/Plugin/ToolCompletes.pm b/src/main/perl/lib/Test2/Manual/Tooling/Plugin/ToolCompletes.pm index e3bc993a0..3223809a1 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/Plugin/ToolCompletes.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/Plugin/ToolCompletes.pm @@ -1,6 +1,6 @@ package Test2::Manual::Tooling::Plugin::ToolCompletes; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/Plugin/ToolStarts.pm b/src/main/perl/lib/Test2/Manual/Tooling/Plugin/ToolStarts.pm index 425788b85..1e3d2e102 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/Plugin/ToolStarts.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/Plugin/ToolStarts.pm @@ -1,6 +1,6 @@ package Test2::Manual::Tooling::Plugin::ToolStarts; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/Subtest.pm b/src/main/perl/lib/Test2/Manual/Tooling/Subtest.pm index 99dbb664e..358536e8f 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/Subtest.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/Subtest.pm @@ -2,7 +2,7 @@ package Test2::Manual::Tooling::Subtest; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/TestBuilder.pm b/src/main/perl/lib/Test2/Manual/Tooling/TestBuilder.pm index faaa0666a..40432354d 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/TestBuilder.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/TestBuilder.pm @@ -1,6 +1,6 @@ package Test2::Manual::Tooling::TestBuilder; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Manual/Tooling/Testing.pm b/src/main/perl/lib/Test2/Manual/Tooling/Testing.pm index 521e483b8..a87d9cad3 100644 --- a/src/main/perl/lib/Test2/Manual/Tooling/Testing.pm +++ b/src/main/perl/lib/Test2/Manual/Tooling/Testing.pm @@ -2,7 +2,7 @@ package Test2::Manual::Tooling::Testing; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Mock.pm b/src/main/perl/lib/Test2/Mock.pm index c15a88cd5..03e0723c2 100644 --- a/src/main/perl/lib/Test2/Mock.pm +++ b/src/main/perl/lib/Test2/Mock.pm @@ -2,7 +2,7 @@ package Test2::Mock; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak confess/; our @CARP_NOT = (__PACKAGE__); diff --git a/src/main/perl/lib/Test2/Plugin.pm b/src/main/perl/lib/Test2/Plugin.pm index c5b666d6f..c790a2e37 100644 --- a/src/main/perl/lib/Test2/Plugin.pm +++ b/src/main/perl/lib/Test2/Plugin.pm @@ -2,7 +2,7 @@ package Test2::Plugin; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Plugin/BailOnFail.pm b/src/main/perl/lib/Test2/Plugin/BailOnFail.pm index 5fd4b56dc..87c0e1201 100644 --- a/src/main/perl/lib/Test2/Plugin/BailOnFail.pm +++ b/src/main/perl/lib/Test2/Plugin/BailOnFail.pm @@ -2,7 +2,7 @@ package Test2::Plugin::BailOnFail; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API qw/test2_add_callback_context_release/; @@ -47,6 +47,21 @@ diagnostics they may need. T2->ok(0, "fail"); T2->ok(1, "Will not run"); +=head1 FORKED AND ASYNC SUBTESTS + +This plugin acts on the pass/fail state of the hub in the process that is +running, and a process that does not own its hub never sees that state. A +forked subtest sends its events to the process that owns the hub instead of +recording them locally, so inside one the hub reports no tests and no +failures no matter what happened. + +A failure inside a forked subtest therefore does not bail there. It bails in +the owning process once that subtest is finished and its events have been +merged, by which point sibling subtests have run whatever they were going to +run. Their output is not suppressed, and there is no way to suppress it from +here: a process cannot receive events for a hub it does not own, so it cannot +be told that a sibling failed. + =head1 SOURCE The source code repository for Test2-Suite can be found at diff --git a/src/main/perl/lib/Test2/Plugin/DieOnFail.pm b/src/main/perl/lib/Test2/Plugin/DieOnFail.pm index f1ebc6511..0c99191c9 100644 --- a/src/main/perl/lib/Test2/Plugin/DieOnFail.pm +++ b/src/main/perl/lib/Test2/Plugin/DieOnFail.pm @@ -2,7 +2,7 @@ package Test2::Plugin::DieOnFail; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API qw/test2_add_callback_context_release/; @@ -45,6 +45,19 @@ This gives the tools the ability to output any extra diagnostics they may need. T2->ok(0, "fail"); T2->ok(1, "Will not run"); +=head1 FORKED AND ASYNC SUBTESTS + +This plugin acts on the pass/fail state of the hub in the process that is +running, and a process that does not own its hub never sees that state. A +forked subtest sends its events to the process that owns the hub instead of +recording them locally, so inside one the hub reports no tests and no +failures no matter what happened. + +A failure inside a forked subtest therefore does not throw there. It throws in +the owning process once that subtest is finished and its events have been +merged, by which point sibling subtests have run whatever they were going to +run. + =head1 SOURCE The source code repository for Test2-Suite can be found at diff --git a/src/main/perl/lib/Test2/Plugin/ExitSummary.pm b/src/main/perl/lib/Test2/Plugin/ExitSummary.pm index b46d1b156..3c9ce6e0f 100644 --- a/src/main/perl/lib/Test2/Plugin/ExitSummary.pm +++ b/src/main/perl/lib/Test2/Plugin/ExitSummary.pm @@ -2,7 +2,7 @@ package Test2::Plugin::ExitSummary; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API qw/test2_add_callback_exit/; diff --git a/src/main/perl/lib/Test2/Plugin/SRand.pm b/src/main/perl/lib/Test2/Plugin/SRand.pm index 01055a44f..1f0107905 100644 --- a/src/main/perl/lib/Test2/Plugin/SRand.pm +++ b/src/main/perl/lib/Test2/Plugin/SRand.pm @@ -2,7 +2,7 @@ package Test2::Plugin::SRand; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/carp/; diff --git a/src/main/perl/lib/Test2/Plugin/Times.pm b/src/main/perl/lib/Test2/Plugin/Times.pm index de8965eee..e0921b5b2 100644 --- a/src/main/perl/lib/Test2/Plugin/Times.pm +++ b/src/main/perl/lib/Test2/Plugin/Times.pm @@ -10,7 +10,7 @@ use Test2::API qw{ use Time::HiRes qw/time/; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; my $ADDED_HOOK = 0; my $START; diff --git a/src/main/perl/lib/Test2/Plugin/UTF8.pm b/src/main/perl/lib/Test2/Plugin/UTF8.pm index 3c65f817e..192193835 100644 --- a/src/main/perl/lib/Test2/Plugin/UTF8.pm +++ b/src/main/perl/lib/Test2/Plugin/UTF8.pm @@ -2,7 +2,7 @@ package Test2::Plugin::UTF8; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Require.pm b/src/main/perl/lib/Test2/Require.pm index 40a96f77f..f45420093 100644 --- a/src/main/perl/lib/Test2/Require.pm +++ b/src/main/perl/lib/Test2/Require.pm @@ -2,7 +2,7 @@ package Test2::Require; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API qw/context/; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Require/AuthorTesting.pm b/src/main/perl/lib/Test2/Require/AuthorTesting.pm index b0099fed4..61defc1a3 100644 --- a/src/main/perl/lib/Test2/Require/AuthorTesting.pm +++ b/src/main/perl/lib/Test2/Require/AuthorTesting.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub skip { my $class = shift; diff --git a/src/main/perl/lib/Test2/Require/AutomatedTesting.pm b/src/main/perl/lib/Test2/Require/AutomatedTesting.pm index b93275ea0..efb9e1612 100644 --- a/src/main/perl/lib/Test2/Require/AutomatedTesting.pm +++ b/src/main/perl/lib/Test2/Require/AutomatedTesting.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub skip { my $class = shift; diff --git a/src/main/perl/lib/Test2/Require/EnvVar.pm b/src/main/perl/lib/Test2/Require/EnvVar.pm index 0fc927358..d672cdd24 100644 --- a/src/main/perl/lib/Test2/Require/EnvVar.pm +++ b/src/main/perl/lib/Test2/Require/EnvVar.pm @@ -5,7 +5,7 @@ use warnings; use Carp qw/confess/; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub skip { my $class = shift; diff --git a/src/main/perl/lib/Test2/Require/ExtendedTesting.pm b/src/main/perl/lib/Test2/Require/ExtendedTesting.pm index 6b5f6f72d..a47d194c1 100644 --- a/src/main/perl/lib/Test2/Require/ExtendedTesting.pm +++ b/src/main/perl/lib/Test2/Require/ExtendedTesting.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub skip { my $class = shift; diff --git a/src/main/perl/lib/Test2/Require/Fork.pm b/src/main/perl/lib/Test2/Require/Fork.pm index 46428ea29..ec3ab6ba4 100644 --- a/src/main/perl/lib/Test2/Require/Fork.pm +++ b/src/main/perl/lib/Test2/Require/Fork.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util qw/CAN_FORK/; diff --git a/src/main/perl/lib/Test2/Require/Module.pm b/src/main/perl/lib/Test2/Require/Module.pm index 0033c7c50..a168274e5 100644 --- a/src/main/perl/lib/Test2/Require/Module.pm +++ b/src/main/perl/lib/Test2/Require/Module.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util qw/pkg_to_file/; diff --git a/src/main/perl/lib/Test2/Require/NonInteractiveTesting.pm b/src/main/perl/lib/Test2/Require/NonInteractiveTesting.pm index ade12d6aa..2fc07d4bf 100644 --- a/src/main/perl/lib/Test2/Require/NonInteractiveTesting.pm +++ b/src/main/perl/lib/Test2/Require/NonInteractiveTesting.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub skip { my $class = shift; diff --git a/src/main/perl/lib/Test2/Require/Perl.pm b/src/main/perl/lib/Test2/Require/Perl.pm index 9075b45a9..4d0e6005c 100644 --- a/src/main/perl/lib/Test2/Require/Perl.pm +++ b/src/main/perl/lib/Test2/Require/Perl.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util qw/pkg_to_file/; use Scalar::Util qw/reftype/; diff --git a/src/main/perl/lib/Test2/Require/RealFork.pm b/src/main/perl/lib/Test2/Require/RealFork.pm index 802b12eab..6963287d2 100644 --- a/src/main/perl/lib/Test2/Require/RealFork.pm +++ b/src/main/perl/lib/Test2/Require/RealFork.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util qw/CAN_REALLY_FORK/; diff --git a/src/main/perl/lib/Test2/Require/ReleaseTesting.pm b/src/main/perl/lib/Test2/Require/ReleaseTesting.pm index 06005abc7..5333de0a8 100644 --- a/src/main/perl/lib/Test2/Require/ReleaseTesting.pm +++ b/src/main/perl/lib/Test2/Require/ReleaseTesting.pm @@ -4,7 +4,7 @@ use warnings; use base 'Test2::Require'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub skip { my $class = shift; diff --git a/src/main/perl/lib/Test2/Require/Threads.pm b/src/main/perl/lib/Test2/Require/Threads.pm index 67463986e..be0287bac 100644 --- a/src/main/perl/lib/Test2/Require/Threads.pm +++ b/src/main/perl/lib/Test2/Require/Threads.pm @@ -4,7 +4,7 @@ use warnings; BEGIN { require Test2::Require; our @ISA = qw(Test2::Require) } -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util qw/CAN_THREAD/; diff --git a/src/main/perl/lib/Test2/Suite.pm b/src/main/perl/lib/Test2/Suite.pm index 3fd7e40c9..fb7f501cb 100644 --- a/src/main/perl/lib/Test2/Suite.pm +++ b/src/main/perl/lib/Test2/Suite.pm @@ -2,7 +2,7 @@ package Test2::Suite; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Todo.pm b/src/main/perl/lib/Test2/Todo.pm index b3842a01d..e1c285d57 100644 --- a/src/main/perl/lib/Test2/Todo.pm +++ b/src/main/perl/lib/Test2/Todo.pm @@ -9,7 +9,7 @@ use Test2::API qw/test2_stack/; use overload '""' => \&reason, fallback => 1; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub init { my $self = shift; diff --git a/src/main/perl/lib/Test2/Tools.pm b/src/main/perl/lib/Test2/Tools.pm index c86a2e101..1a9edb1ee 100644 --- a/src/main/perl/lib/Test2/Tools.pm +++ b/src/main/perl/lib/Test2/Tools.pm @@ -2,7 +2,7 @@ package Test2::Tools; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/Tools/AsyncSubtest.pm b/src/main/perl/lib/Test2/Tools/AsyncSubtest.pm index 0d21d2393..9b48a41fa 100644 --- a/src/main/perl/lib/Test2/Tools/AsyncSubtest.pm +++ b/src/main/perl/lib/Test2/Tools/AsyncSubtest.pm @@ -2,7 +2,7 @@ package Test2::Tools::AsyncSubtest; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::IPC; use Test2::AsyncSubtest; @@ -86,7 +86,7 @@ other events are also being generated. =head1 SYNOPSIS - use Test2::Bundle::Extended; + use Test2::V0; use Test2::Tools::AsyncSubtest; my $ast1 = async_subtest local => sub { diff --git a/src/main/perl/lib/Test2/Tools/Basic.pm b/src/main/perl/lib/Test2/Tools/Basic.pm index 8c88ec37c..40bdddcf9 100644 --- a/src/main/perl/lib/Test2/Tools/Basic.pm +++ b/src/main/perl/lib/Test2/Tools/Basic.pm @@ -2,7 +2,7 @@ package Test2::Tools::Basic; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; use Test2::API qw/context/; @@ -104,7 +104,9 @@ sub skip_all { sub done_testing { my $ctx = context(); $ctx->hub->finalize($ctx->trace, 1); + my $count = $ctx->hub->count; $ctx->release; + return $count; } sub bail_out { @@ -202,6 +204,8 @@ tests are run. Used to mark the end of testing. This is a safe way to have a dynamic or unknown number of tests. +Returns the number of assertions that were made, which is 0 when none were. + =item bail_out($reason) Invoked when something has gone horribly wrong: stop everything, kill all threads and diff --git a/src/main/perl/lib/Test2/Tools/Class.pm b/src/main/perl/lib/Test2/Tools/Class.pm index fa5895453..b9908a9e7 100644 --- a/src/main/perl/lib/Test2/Tools/Class.pm +++ b/src/main/perl/lib/Test2/Tools/Class.pm @@ -2,7 +2,7 @@ package Test2::Tools::Class; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API qw/context/; use Test2::Util::Ref qw/render_ref/; diff --git a/src/main/perl/lib/Test2/Tools/ClassicCompare.pm b/src/main/perl/lib/Test2/Tools/ClassicCompare.pm index 4535b09bf..3f82d4c67 100644 --- a/src/main/perl/lib/Test2/Tools/ClassicCompare.pm +++ b/src/main/perl/lib/Test2/Tools/ClassicCompare.pm @@ -2,7 +2,7 @@ package Test2::Tools::ClassicCompare; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our @EXPORT = qw/is is_deeply isnt like unlike cmp_ok/; use base 'Exporter'; diff --git a/src/main/perl/lib/Test2/Tools/Compare.pm b/src/main/perl/lib/Test2/Tools/Compare.pm index d25b48c77..8d56afb63 100644 --- a/src/main/perl/lib/Test2/Tools/Compare.pm +++ b/src/main/perl/lib/Test2/Tools/Compare.pm @@ -2,7 +2,7 @@ package Test2::Tools::Compare; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; use Scalar::Util qw/reftype/; @@ -1341,6 +1341,13 @@ Enforce that no keys are found in the hash other than those specified. This is essentially the C of a hash check. This can be used anywhere in the hash builder, though typically it is placed at the end. +C and C do not specify any fields, so they do not +keep C from rejecting a key. Using either or both together with +C in a builder that specifies no fields throws an exception once the +builder block finishes: such a check can only match an empty hash, which +discards the C and C checks. Use C to check +every key or value without limiting which keys the hash may have. + =item etc() Ignore any extra keys found in the hash. This is the opposite of C. @@ -1436,6 +1443,13 @@ block, and can call it any number of times with any number of arguments. Enforce that there are no indexes after the last one specified. This will not force checking of skipped indexes. +C does not specify any indexes, so it does not keep C from +rejecting an item. Using it together with C in a builder that specifies +no items throws an exception once the builder block finishes: such a check can +only match an empty array, which discards the C checks. Use +C to check every item without limiting how many items the array may +have. + =item etc() Ignore any extra items found in the array. This is the opposite of C. @@ -1489,7 +1503,14 @@ block, and can call it any number of times with any number of arguments. =item end() -Enforce that there are no more items after the last one specified. +Enforce that the array contains no items other than the ones specified. + +C does not specify any items, so it does not keep C from +rejecting an item. Using it together with C in a builder that specifies +no items throws an exception once the builder block finishes: such a check can +only match an empty array, which discards the C checks. Use +C to check every item without limiting how many items the array may +have. =item etc() diff --git a/src/main/perl/lib/Test2/Tools/Defer.pm b/src/main/perl/lib/Test2/Tools/Defer.pm index 85b5a1233..243efc0d8 100644 --- a/src/main/perl/lib/Test2/Tools/Defer.pm +++ b/src/main/perl/lib/Test2/Tools/Defer.pm @@ -2,7 +2,7 @@ package Test2::Tools::Defer; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Tools/Encoding.pm b/src/main/perl/lib/Test2/Tools/Encoding.pm index 353e7dc3e..fce3b3e23 100644 --- a/src/main/perl/lib/Test2/Tools/Encoding.pm +++ b/src/main/perl/lib/Test2/Tools/Encoding.pm @@ -8,7 +8,7 @@ use Test2::API qw/test2_stack/; use base 'Exporter'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our @EXPORT = qw/set_encoding/; diff --git a/src/main/perl/lib/Test2/Tools/Event.pm b/src/main/perl/lib/Test2/Tools/Event.pm index db4e56671..cb7dbf8e7 100644 --- a/src/main/perl/lib/Test2/Tools/Event.pm +++ b/src/main/perl/lib/Test2/Tools/Event.pm @@ -2,7 +2,7 @@ package Test2::Tools::Event; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util qw/pkg_to_file/; diff --git a/src/main/perl/lib/Test2/Tools/Exception.pm b/src/main/perl/lib/Test2/Tools/Exception.pm index b9dbc5643..c1409da46 100644 --- a/src/main/perl/lib/Test2/Tools/Exception.pm +++ b/src/main/perl/lib/Test2/Tools/Exception.pm @@ -2,7 +2,7 @@ package Test2::Tools::Exception; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/carp/; use Test2::API qw/context test2_add_pending_diag test2_clear_pending_diags/; diff --git a/src/main/perl/lib/Test2/Tools/Exports.pm b/src/main/perl/lib/Test2/Tools/Exports.pm index b4706a21f..144a9f6dd 100644 --- a/src/main/perl/lib/Test2/Tools/Exports.pm +++ b/src/main/perl/lib/Test2/Tools/Exports.pm @@ -2,7 +2,7 @@ package Test2::Tools::Exports; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak carp/; use Test2::API qw/context/; diff --git a/src/main/perl/lib/Test2/Tools/GenTemp.pm b/src/main/perl/lib/Test2/Tools/GenTemp.pm index 445e25af5..1c9ca0fef 100644 --- a/src/main/perl/lib/Test2/Tools/GenTemp.pm +++ b/src/main/perl/lib/Test2/Tools/GenTemp.pm @@ -3,7 +3,7 @@ package Test2::Tools::GenTemp; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use File::Temp qw/tempdir/; use File::Spec; diff --git a/src/main/perl/lib/Test2/Tools/Grab.pm b/src/main/perl/lib/Test2/Tools/Grab.pm index 7c9580bd5..045df8705 100644 --- a/src/main/perl/lib/Test2/Tools/Grab.pm +++ b/src/main/perl/lib/Test2/Tools/Grab.pm @@ -2,7 +2,7 @@ package Test2::Tools::Grab; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::Grabber; use Test2::EventFacet::Trace(); diff --git a/src/main/perl/lib/Test2/Tools/Mock.pm b/src/main/perl/lib/Test2/Tools/Mock.pm index 901c429a7..4a9e3af1f 100644 --- a/src/main/perl/lib/Test2/Tools/Mock.pm +++ b/src/main/perl/lib/Test2/Tools/Mock.pm @@ -11,7 +11,7 @@ use Test2::Mock(); use base 'Exporter'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our @CARP_NOT = (__PACKAGE__, 'Test2::Mock'); our @EXPORT = qw/mock mocked/; diff --git a/src/main/perl/lib/Test2/Tools/Ref.pm b/src/main/perl/lib/Test2/Tools/Ref.pm index e509231d9..741d17108 100644 --- a/src/main/perl/lib/Test2/Tools/Ref.pm +++ b/src/main/perl/lib/Test2/Tools/Ref.pm @@ -2,7 +2,7 @@ package Test2::Tools::Ref; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Scalar::Util qw/reftype refaddr/; use Test2::API qw/context/; diff --git a/src/main/perl/lib/Test2/Tools/Refcount.pm b/src/main/perl/lib/Test2/Tools/Refcount.pm index 04d1778d2..a24f5bf73 100644 --- a/src/main/perl/lib/Test2/Tools/Refcount.pm +++ b/src/main/perl/lib/Test2/Tools/Refcount.pm @@ -13,7 +13,7 @@ use Test2::API qw(context release); use Scalar::Util qw( weaken refaddr ); use B qw( svref_2object ); -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our @EXPORT = qw( is_refcount diff --git a/src/main/perl/lib/Test2/Tools/Spec.pm b/src/main/perl/lib/Test2/Tools/Spec.pm index 5632670ea..08a9ca2f3 100644 --- a/src/main/perl/lib/Test2/Tools/Spec.pm +++ b/src/main/perl/lib/Test2/Tools/Spec.pm @@ -2,7 +2,7 @@ package Test2::Tools::Spec; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; use Test2::Workflow qw/parse_args build current_build root_build init_root build_stack/; @@ -301,7 +301,7 @@ supports isolation and/or concurrency via forking or threads. =head1 SYNOPSIS - use Test2::Bundle::Extended; + use Test2::V0; use Test2::Tools::Spec; describe foo => sub { @@ -580,7 +580,7 @@ Same as: Sometimes you want to apply default attributes to all C or C blocks. This can be done, and is lexical to your describe or package root! - use Test2::Bundle::Extended; + use Test2::V0; use Test2::Tools::Spec ':ALL'; # All 'tests' blocks after this declaration will have C< 1>> by default diff --git a/src/main/perl/lib/Test2/Tools/Subtest.pm b/src/main/perl/lib/Test2/Tools/Subtest.pm index 55017178c..86fe22f81 100644 --- a/src/main/perl/lib/Test2/Tools/Subtest.pm +++ b/src/main/perl/lib/Test2/Tools/Subtest.pm @@ -2,7 +2,7 @@ package Test2::Tools::Subtest; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API qw/context run_subtest/; use Test2::Util qw/try/; diff --git a/src/main/perl/lib/Test2/Tools/Target.pm b/src/main/perl/lib/Test2/Tools/Target.pm index f313adaae..65438e8d9 100644 --- a/src/main/perl/lib/Test2/Tools/Target.pm +++ b/src/main/perl/lib/Test2/Tools/Target.pm @@ -2,7 +2,7 @@ package Test2::Tools::Target; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Tools/Tester.pm b/src/main/perl/lib/Test2/Tools/Tester.pm index 686ce37fb..f7851135c 100644 --- a/src/main/perl/lib/Test2/Tools/Tester.pm +++ b/src/main/perl/lib/Test2/Tools/Tester.pm @@ -2,7 +2,7 @@ package Test2::Tools::Tester; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; use Test2::Util::Ref qw/rtype/; diff --git a/src/main/perl/lib/Test2/Tools/Tiny.pm b/src/main/perl/lib/Test2/Tools/Tiny.pm index f7ad9dd44..ce490e9a0 100644 --- a/src/main/perl/lib/Test2/Tools/Tiny.pm +++ b/src/main/perl/lib/Test2/Tools/Tiny.pm @@ -10,7 +10,7 @@ use Test2::API qw/context run_subtest test2_stack/; use Test2::Hub::Interceptor(); use Test2::Hub::Interceptor::Terminator(); -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; BEGIN { require Exporter; our @ISA = qw(Exporter) } our @EXPORT = qw{ @@ -208,7 +208,9 @@ sub plan { sub done_testing { my $ctx = context(); $ctx->done_testing; + my $count = $ctx->hub->count; $ctx->release; + return $count; } sub warnings(&) { @@ -364,6 +366,8 @@ Set the plan. Set the plan to the current test count. +Returns the number of assertions that were made, which is 0 when none were. + =item $warnings = warnings { ... } Capture an arrayref of warnings from the block. diff --git a/src/main/perl/lib/Test2/Tools/Warnings.pm b/src/main/perl/lib/Test2/Tools/Warnings.pm index ceeb4a43e..272da895f 100644 --- a/src/main/perl/lib/Test2/Tools/Warnings.pm +++ b/src/main/perl/lib/Test2/Tools/Warnings.pm @@ -2,7 +2,7 @@ package Test2::Tools::Warnings; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/carp/; use Test2::API qw/context test2_add_pending_diag/; diff --git a/src/main/perl/lib/Test2/Util.pm b/src/main/perl/lib/Test2/Util.pm index df505f95c..027fd4170 100644 --- a/src/main/perl/lib/Test2/Util.pm +++ b/src/main/perl/lib/Test2/Util.pm @@ -2,7 +2,7 @@ package Test2::Util; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Config qw/%Config/; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Util/ExternalMeta.pm b/src/main/perl/lib/Test2/Util/ExternalMeta.pm index 4bcdb6fe7..dad99cfda 100644 --- a/src/main/perl/lib/Test2/Util/ExternalMeta.pm +++ b/src/main/perl/lib/Test2/Util/ExternalMeta.pm @@ -2,7 +2,7 @@ package Test2::Util::ExternalMeta; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/Util/Facets2Legacy.pm b/src/main/perl/lib/Test2/Util/Facets2Legacy.pm index b3a97a34e..e53b81058 100644 --- a/src/main/perl/lib/Test2/Util/Facets2Legacy.pm +++ b/src/main/perl/lib/Test2/Util/Facets2Legacy.pm @@ -2,7 +2,7 @@ package Test2::Util::Facets2Legacy; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak confess/; use Scalar::Util qw/blessed/; diff --git a/src/main/perl/lib/Test2/Util/Grabber.pm b/src/main/perl/lib/Test2/Util/Grabber.pm index 55dce00ca..c516a81b7 100644 --- a/src/main/perl/lib/Test2/Util/Grabber.pm +++ b/src/main/perl/lib/Test2/Util/Grabber.pm @@ -2,7 +2,7 @@ package Test2::Util::Grabber; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Hub::Interceptor(); use Test2::EventFacet::Trace(); diff --git a/src/main/perl/lib/Test2/Util/Guard.pm b/src/main/perl/lib/Test2/Util/Guard.pm index 03dc287e8..5d0d3a3cb 100644 --- a/src/main/perl/lib/Test2/Util/Guard.pm +++ b/src/main/perl/lib/Test2/Util/Guard.pm @@ -5,7 +5,7 @@ use warnings; use Carp qw(confess); -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub new { confess "Can't create a Test2::Util::Guard in void context" unless (defined wantarray); diff --git a/src/main/perl/lib/Test2/Util/HashBase.pm b/src/main/perl/lib/Test2/Util/HashBase.pm index 6c1aa6b0a..4e29b7089 100644 --- a/src/main/perl/lib/Test2/Util/HashBase.pm +++ b/src/main/perl/lib/Test2/Util/HashBase.pm @@ -2,7 +2,7 @@ package Test2::Util::HashBase; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; ################################################################# # # diff --git a/src/main/perl/lib/Test2/Util/Importer.pm b/src/main/perl/lib/Test2/Util/Importer.pm index 2bfdffe05..10013527a 100644 --- a/src/main/perl/lib/Test2/Util/Importer.pm +++ b/src/main/perl/lib/Test2/Util/Importer.pm @@ -2,7 +2,7 @@ package Test2::Util::Importer; use strict; no strict 'refs'; use warnings; no warnings 'once'; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; my %SIG_TO_SLOT = ( '&' => 'CODE', diff --git a/src/main/perl/lib/Test2/Util/Ref.pm b/src/main/perl/lib/Test2/Util/Ref.pm index 52f0ff6a5..1527e5d75 100644 --- a/src/main/perl/lib/Test2/Util/Ref.pm +++ b/src/main/perl/lib/Test2/Util/Ref.pm @@ -2,7 +2,7 @@ package Test2::Util::Ref; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Scalar::Util qw/reftype blessed refaddr/; diff --git a/src/main/perl/lib/Test2/Util/Sig.pm b/src/main/perl/lib/Test2/Util/Sig.pm index 8f705fa32..5b4bd74c2 100644 --- a/src/main/perl/lib/Test2/Util/Sig.pm +++ b/src/main/perl/lib/Test2/Util/Sig.pm @@ -2,7 +2,7 @@ package Test2::Util::Sig; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use POSIX(); use Test2::Util qw/try IS_WIN32/; diff --git a/src/main/perl/lib/Test2/Util/Stash.pm b/src/main/perl/lib/Test2/Util/Stash.pm index ac823c892..13cec6a34 100644 --- a/src/main/perl/lib/Test2/Util/Stash.pm +++ b/src/main/perl/lib/Test2/Util/Stash.pm @@ -2,7 +2,7 @@ package Test2::Util::Stash; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; use B; diff --git a/src/main/perl/lib/Test2/Util/Sub.pm b/src/main/perl/lib/Test2/Util/Sub.pm index e09a175cc..c2f7f358d 100644 --- a/src/main/perl/lib/Test2/Util/Sub.pm +++ b/src/main/perl/lib/Test2/Util/Sub.pm @@ -2,7 +2,7 @@ package Test2::Util::Sub; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak carp/; use B(); diff --git a/src/main/perl/lib/Test2/Util/Table.pm b/src/main/perl/lib/Test2/Util/Table.pm index 81d001fa7..b547f7172 100644 --- a/src/main/perl/lib/Test2/Util/Table.pm +++ b/src/main/perl/lib/Test2/Util/Table.pm @@ -2,7 +2,7 @@ package Test2::Util::Table; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use base 'Term::Table'; diff --git a/src/main/perl/lib/Test2/Util/Table/Cell.pm b/src/main/perl/lib/Test2/Util/Table/Cell.pm index 71a30f7cf..cc57cf478 100644 --- a/src/main/perl/lib/Test2/Util/Table/Cell.pm +++ b/src/main/perl/lib/Test2/Util/Table/Cell.pm @@ -2,7 +2,7 @@ package Test2::Util::Table::Cell; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use base 'Term::Table::Cell'; diff --git a/src/main/perl/lib/Test2/Util/Table/LineBreak.pm b/src/main/perl/lib/Test2/Util/Table/LineBreak.pm index 53630023e..62d44767c 100644 --- a/src/main/perl/lib/Test2/Util/Table/LineBreak.pm +++ b/src/main/perl/lib/Test2/Util/Table/LineBreak.pm @@ -2,7 +2,7 @@ package Test2::Util::Table::LineBreak; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use base 'Term::Table::LineBreak'; diff --git a/src/main/perl/lib/Test2/Util/Term.pm b/src/main/perl/lib/Test2/Util/Term.pm index a38c31d7d..2a3f0c626 100644 --- a/src/main/perl/lib/Test2/Util/Term.pm +++ b/src/main/perl/lib/Test2/Util/Term.pm @@ -4,7 +4,7 @@ use warnings; use Term::Table::Util qw/term_size USE_GCS USE_TERM_READKEY uni_length/; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::Importer 'Test2::Util::Importer' => 'import'; our @EXPORT_OK = qw/term_size USE_GCS USE_TERM_READKEY uni_length/; diff --git a/src/main/perl/lib/Test2/Util/Times.pm b/src/main/perl/lib/Test2/Util/Times.pm index e6dcfc8d3..0a973883a 100644 --- a/src/main/perl/lib/Test2/Util/Times.pm +++ b/src/main/perl/lib/Test2/Util/Times.pm @@ -4,7 +4,7 @@ use warnings; use List::Util qw/sum/; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our @EXPORT_OK = qw/render_bench render_duration/; use base 'Exporter'; diff --git a/src/main/perl/lib/Test2/Util/Trace.pm b/src/main/perl/lib/Test2/Util/Trace.pm index a78a7fe09..a08e8e5f7 100644 --- a/src/main/perl/lib/Test2/Util/Trace.pm +++ b/src/main/perl/lib/Test2/Util/Trace.pm @@ -6,7 +6,7 @@ use strict; our @ISA = ('Test2::EventFacet::Trace'); -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; 1; diff --git a/src/main/perl/lib/Test2/V0.pm b/src/main/perl/lib/Test2/V0.pm index 63e498bc6..80dd71648 100644 --- a/src/main/perl/lib/Test2/V0.pm +++ b/src/main/perl/lib/Test2/V0.pm @@ -4,7 +4,7 @@ use warnings; use Test2::Util::Importer; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; diff --git a/src/main/perl/lib/Test2/V1.pm b/src/main/perl/lib/Test2/V1.pm index 6c5b3ec75..89936f4a1 100644 --- a/src/main/perl/lib/Test2/V1.pm +++ b/src/main/perl/lib/Test2/V1.pm @@ -2,7 +2,7 @@ package Test2::V1; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; @@ -320,7 +320,7 @@ thrown. =item C You can prefix an export name with C to exclude it at import time. This is -really only usedul when combined with C<-import> or C<-i>. +really only useful when combined with C<-import> or C<-i>. =item C<< EXPORT_NAME => { -as => "ALT_NAME" } >> @@ -360,8 +360,8 @@ C =head1 PRAGMAS AND PLUGINS -B -B +B +B This is a significant departure from L. @@ -369,7 +369,7 @@ You can enable all of these with the C<-pP> argument, which is short for C<-plugins, -pragmas>. C

is short for plugins, and C

is short for pragmas. When using the single-letter form they may both be together following a single dash, and can be in any order. They may also be combined with C to -bring in all imports. C<-p> or C<-P> ont heir own are also perfectly valid. +bring in all imports. C<-p> or C<-P> on their own are also perfectly valid. =over 4 @@ -434,7 +434,7 @@ See L for a list of meaningful environment variables. =head1 API FUNCTIONS -See L for these +See L for these. =over 4 @@ -487,10 +487,10 @@ can have additional tools added to it. Note that you MAY override original tools such as ok(), note(), etc. by importing different copies this way. The first time you do this there should be -no warnings or errors. If you pull in multiple tools of the same name an +no warnings or errors. If you pull in multiple tools of the same name, a redefine warning is likely. -This also effects exports: +This also affects exports: use Test2::V1 -import, -include => ['Data::Dumper']; @@ -532,7 +532,7 @@ Used to allow the handle to stomp on an existing namespace (NOT RECOMMENDED). Set the base class from which functions should be inherited. Normally this is set to L. -Another interesting use case is to have multiple handles that use eachothers +Another interesting use case is to have multiple handles that use each other's namespaces as base classes: use Test2::V1; @@ -552,7 +552,7 @@ namespaces as base classes: =head2 OVERRIDING INCLUDED TOOLS WITH ALTERNATES -Lets say you want to use the L version of C, +Let's say you want to use the L version of C, C instead of the L versions, and also wanted to import everything else L provides. @@ -1047,11 +1047,11 @@ scripts, but they can get in the way in many cases. Many people would put custom strict/warnings settings at the top of their tests, only to have them wiped out when they use L. -=item Assumptions of UTF8 +=item Assumptions of UTF-8 Occasionally you do not want this assumption. The way it impacts all your regular and test handles, as well as how your source is read, can be a problem -if you are not working with UTF8, or have other plans entirly. +if you are not working with UTF-8, or have other plans entirely. =item Huge default set of exports, which can grow @@ -1063,16 +1063,16 @@ a point not to break/remove exports, but there is no such commitment about adding new ones. Now the only default export is C which gives you a handle where all the -tools we expose are provided as methods. You can also use the L module (Not +tools we expose are provided as methods. You can also use the L module (not bundled with Test-Simple) for use with an identical number of keystrokes, which -allow you to leverage the prototypes on the original tool subroutines. +allows you to leverage the prototypes on the original tool subroutines. =back =head1 SOURCE The source code repository for Test2-Suite can be found at -F. +L. =head1 MAINTAINERS @@ -1097,6 +1097,6 @@ Copyright Chad Granum Eexodist@cpan.orgE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. -See F +See L. =cut diff --git a/src/main/perl/lib/Test2/V1/Base.pm b/src/main/perl/lib/Test2/V1/Base.pm index 271da3d2c..00f30c16a 100644 --- a/src/main/perl/lib/Test2/V1/Base.pm +++ b/src/main/perl/lib/Test2/V1/Base.pm @@ -2,7 +2,7 @@ package Test2::V1::Base; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API qw/intercept context/; diff --git a/src/main/perl/lib/Test2/V1/Handle.pm b/src/main/perl/lib/Test2/V1/Handle.pm index f0c06d1ae..f34241918 100644 --- a/src/main/perl/lib/Test2/V1/Handle.pm +++ b/src/main/perl/lib/Test2/V1/Handle.pm @@ -2,7 +2,7 @@ package Test2::V1::Handle; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; sub DEFAULT_HANDLE_BASE { 'Test2::V1::Base' } diff --git a/src/main/perl/lib/Test2/Workflow.pm b/src/main/perl/lib/Test2/Workflow.pm index 4661f43f6..e3cf625c0 100644 --- a/src/main/perl/lib/Test2/Workflow.pm +++ b/src/main/perl/lib/Test2/Workflow.pm @@ -2,7 +2,7 @@ package Test2::Workflow; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; our @EXPORT_OK = qw/parse_args current_build build root_build init_root build_stack/; use base 'Exporter'; diff --git a/src/main/perl/lib/Test2/Workflow/BlockBase.pm b/src/main/perl/lib/Test2/Workflow/BlockBase.pm index cffc266b0..5a7fe0791 100644 --- a/src/main/perl/lib/Test2/Workflow/BlockBase.pm +++ b/src/main/perl/lib/Test2/Workflow/BlockBase.pm @@ -2,7 +2,7 @@ package Test2::Workflow::BlockBase; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Util::HashBase qw/code frame _info _lines/; use Test2::Util::Sub qw/sub_info/; diff --git a/src/main/perl/lib/Test2/Workflow/Build.pm b/src/main/perl/lib/Test2/Workflow/Build.pm index e1608bf90..9adaccca7 100644 --- a/src/main/perl/lib/Test2/Workflow/Build.pm +++ b/src/main/perl/lib/Test2/Workflow/Build.pm @@ -2,7 +2,7 @@ package Test2::Workflow::Build; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::Workflow::Task::Group; diff --git a/src/main/perl/lib/Test2/Workflow/Runner.pm b/src/main/perl/lib/Test2/Workflow/Runner.pm index 928629715..8cdbc284a 100644 --- a/src/main/perl/lib/Test2/Workflow/Runner.pm +++ b/src/main/perl/lib/Test2/Workflow/Runner.pm @@ -2,7 +2,7 @@ package Test2::Workflow::Runner; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API(); use Test2::Todo(); diff --git a/src/main/perl/lib/Test2/Workflow/Task.pm b/src/main/perl/lib/Test2/Workflow/Task.pm index 749c5ddbf..694be177f 100644 --- a/src/main/perl/lib/Test2/Workflow/Task.pm +++ b/src/main/perl/lib/Test2/Workflow/Task.pm @@ -2,7 +2,7 @@ package Test2::Workflow::Task; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Test2::API(); use Test2::Event::Exception(); diff --git a/src/main/perl/lib/Test2/Workflow/Task/Action.pm b/src/main/perl/lib/Test2/Workflow/Task/Action.pm index 5223028b0..ab6808ff3 100644 --- a/src/main/perl/lib/Test2/Workflow/Task/Action.pm +++ b/src/main/perl/lib/Test2/Workflow/Task/Action.pm @@ -2,7 +2,7 @@ package Test2::Workflow::Task::Action; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use base 'Test2::Workflow::Task'; use Test2::Util::HashBase qw/around/; diff --git a/src/main/perl/lib/Test2/Workflow/Task/Group.pm b/src/main/perl/lib/Test2/Workflow/Task/Group.pm index 0628691f4..477c17137 100644 --- a/src/main/perl/lib/Test2/Workflow/Task/Group.pm +++ b/src/main/perl/lib/Test2/Workflow/Task/Group.pm @@ -2,7 +2,7 @@ package Test2::Workflow::Task::Group; use strict; use warnings; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use Carp qw/croak/; diff --git a/src/main/perl/lib/ok.pm b/src/main/perl/lib/ok.pm index 0c577929a..39c285e16 100644 --- a/src/main/perl/lib/ok.pm +++ b/src/main/perl/lib/ok.pm @@ -1,5 +1,5 @@ package ok; -our $VERSION = '1.302222'; +our $VERSION = '1.302225'; use strict; use Test::More (); From f69f48657110c139172513874d884816777e3dbc Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Mon, 7 Sep 2026 19:28:12 +0200 Subject: [PATCH 3/5] fix: support Perl defined comparison operators Implement Perl's equ, neu, ===, and !== operators across the parser, JVM backend, bytecode backend, chaining logic, and overload dispatch. Add focused regression coverage for defined and undefined operands. Generated with [Codex](https://openai.com/codex) Co-Authored-By: Codex <158243242+openai-codex[bot]@users.noreply.github.com> --- .../backend/bytecode/BytecodeInterpreter.java | 21 ++++++++- .../bytecode/CompileBinaryOperatorHelper.java | 24 ++++++++++ .../perlonjava/backend/bytecode/Opcodes.java | 12 +++++ .../backend/jvm/EmitBinaryOperatorNode.java | 3 +- .../backend/jvm/EmitOperatorChained.java | 2 +- .../frontend/parser/ParseInfix.java | 15 ++---- .../frontend/parser/ParserTables.java | 2 + .../runtime/operators/CompareOperators.java | 47 +++++++++++++++++++ .../runtime/operators/OperatorHandler.java | 4 ++ .../unit/defined_comparison_operators.t | 13 +++++ 10 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 src/test/resources/unit/defined_comparison_operators.t diff --git a/src/main/java/org/perlonjava/backend/bytecode/BytecodeInterpreter.java b/src/main/java/org/perlonjava/backend/bytecode/BytecodeInterpreter.java index e31c2ce78..e8e5accdc 100644 --- a/src/main/java/org/perlonjava/backend/bytecode/BytecodeInterpreter.java +++ b/src/main/java/org/perlonjava/backend/bytecode/BytecodeInterpreter.java @@ -1347,7 +1347,9 @@ private static RuntimeList execute(SuspendedInterpreterFrame frame) { case Opcodes.COMPARE_NUM, Opcodes.COMPARE_STR, Opcodes.EQ_NUM, Opcodes.NE_NUM, Opcodes.LT_NUM, Opcodes.GT_NUM, Opcodes.LE_NUM, Opcodes.GE_NUM, Opcodes.EQ_STR, - Opcodes.NE_STR, Opcodes.NOT, Opcodes.NOT_NO_OVERLOAD -> { + Opcodes.NE_STR, Opcodes.EQU_STR, Opcodes.NEU_STR, + Opcodes.STRICT_EQ_NUM, Opcodes.STRICT_NE_NUM, + Opcodes.NOT, Opcodes.NOT_NO_OVERLOAD -> { pc = executeComparisons(opcode, bytecode, pc, registers); } @@ -3580,6 +3582,23 @@ private static int executeComparisons(int opcode, int[] bytecode, int pc, return pc; } + case Opcodes.EQU_STR, Opcodes.NEU_STR, Opcodes.STRICT_EQ_NUM, Opcodes.STRICT_NE_NUM -> { + int rd = bytecode[pc++]; + int rs1 = bytecode[pc++]; + int rs2 = bytecode[pc++]; + RuntimeBase val1 = registers[rs1]; + RuntimeBase val2 = registers[rs2]; + RuntimeScalar s1 = (val1 instanceof RuntimeScalar) ? (RuntimeScalar) val1 : val1.scalar(); + RuntimeScalar s2 = (val2 instanceof RuntimeScalar) ? (RuntimeScalar) val2 : val2.scalar(); + registers[rd] = switch (opcode) { + case Opcodes.EQU_STR -> CompareOperators.equ(s1, s2); + case Opcodes.NEU_STR -> CompareOperators.neu(s1, s2); + case Opcodes.STRICT_EQ_NUM -> CompareOperators.strictEqual(s1, s2); + default -> CompareOperators.strictNotEqual(s1, s2); + }; + return pc; + } + case Opcodes.NOT -> { int rd = bytecode[pc++]; int rs = bytecode[pc++]; diff --git a/src/main/java/org/perlonjava/backend/bytecode/CompileBinaryOperatorHelper.java b/src/main/java/org/perlonjava/backend/bytecode/CompileBinaryOperatorHelper.java index 8d5df1a82..ab27709c0 100644 --- a/src/main/java/org/perlonjava/backend/bytecode/CompileBinaryOperatorHelper.java +++ b/src/main/java/org/perlonjava/backend/bytecode/CompileBinaryOperatorHelper.java @@ -195,6 +195,30 @@ private static int compileBinaryOperatorSwitch(BytecodeCompiler bytecodeCompiler bytecodeCompiler.emitReg(rs1); bytecodeCompiler.emitReg(rs2); } + case "equ" -> { + bytecodeCompiler.emit(Opcodes.EQU_STR); + bytecodeCompiler.emitReg(rd); + bytecodeCompiler.emitReg(rs1); + bytecodeCompiler.emitReg(rs2); + } + case "neu" -> { + bytecodeCompiler.emit(Opcodes.NEU_STR); + bytecodeCompiler.emitReg(rd); + bytecodeCompiler.emitReg(rs1); + bytecodeCompiler.emitReg(rs2); + } + case "===" -> { + bytecodeCompiler.emit(Opcodes.STRICT_EQ_NUM); + bytecodeCompiler.emitReg(rd); + bytecodeCompiler.emitReg(rs1); + bytecodeCompiler.emitReg(rs2); + } + case "!==" -> { + bytecodeCompiler.emit(Opcodes.STRICT_NE_NUM); + bytecodeCompiler.emitReg(rd); + bytecodeCompiler.emitReg(rs1); + bytecodeCompiler.emitReg(rs2); + } case "lt", "gt", "le", "ge" -> { // String comparisons using COMPARE_STR (like cmp) // cmp returns: -1 if $a lt $b, 0 if equal, 1 if $a gt $b diff --git a/src/main/java/org/perlonjava/backend/bytecode/Opcodes.java b/src/main/java/org/perlonjava/backend/bytecode/Opcodes.java index f609b6586..4140371ed 100644 --- a/src/main/java/org/perlonjava/backend/bytecode/Opcodes.java +++ b/src/main/java/org/perlonjava/backend/bytecode/Opcodes.java @@ -252,6 +252,18 @@ public class Opcodes { */ public static final short NE_STR = 38; + /** Defined string equality: equ. */ + public static final short EQU_STR = 547; + + /** Defined string inequality: neu. */ + public static final short NEU_STR = 548; + + /** Defined numeric equality: ===. */ + public static final short STRICT_EQ_NUM = 552; + + /** Defined numeric inequality: !==. */ + public static final short STRICT_NE_NUM = 553; + // ================================================================= // LOGICAL OPERATORS (39-41) // ================================================================= diff --git a/src/main/java/org/perlonjava/backend/jvm/EmitBinaryOperatorNode.java b/src/main/java/org/perlonjava/backend/jvm/EmitBinaryOperatorNode.java index 816a937e9..b4d5b3dba 100644 --- a/src/main/java/org/perlonjava/backend/jvm/EmitBinaryOperatorNode.java +++ b/src/main/java/org/perlonjava/backend/jvm/EmitBinaryOperatorNode.java @@ -83,7 +83,8 @@ public static void emitBinaryOperatorNode(EmitterVisitor emitterVisitor, BinaryO // Comparison operators (chained) case "<", ">", "<=", ">=", "lt", "gt", "le", "ge", - "==", "!=", "eq", "ne" -> EmitOperatorChained.emitChainedComparison(emitterVisitor, node); + "==", "!=", "===", "!==", "eq", "ne", "equ", "neu" -> + EmitOperatorChained.emitChainedComparison(emitterVisitor, node); // Binary operators case "%", "&", "&.", "binary&", "*", "**", "+", "-", "/", diff --git a/src/main/java/org/perlonjava/backend/jvm/EmitOperatorChained.java b/src/main/java/org/perlonjava/backend/jvm/EmitOperatorChained.java index 15c5f9b50..26980b607 100644 --- a/src/main/java/org/perlonjava/backend/jvm/EmitOperatorChained.java +++ b/src/main/java/org/perlonjava/backend/jvm/EmitOperatorChained.java @@ -13,7 +13,7 @@ public class EmitOperatorChained { public static final String[] CHAIN_COMPARISON_OP = new String[]{"<", ">", "<=", ">=", "lt", "gt", "le", "ge"}; - public static final String[] CHAIN_EQUALITY_OP = new String[]{"==", "!=", "eq", "ne"}; + public static final String[] CHAIN_EQUALITY_OP = new String[]{"==", "!=", "===", "!==", "eq", "ne", "equ", "neu"}; static public void emitChainedComparison(EmitterVisitor emitterVisitor, BinaryOperatorNode node) { EmitterVisitor scalarVisitor = diff --git a/src/main/java/org/perlonjava/frontend/parser/ParseInfix.java b/src/main/java/org/perlonjava/frontend/parser/ParseInfix.java index 18917012c..699ebf8d1 100644 --- a/src/main/java/org/perlonjava/frontend/parser/ParseInfix.java +++ b/src/main/java/org/perlonjava/frontend/parser/ParseInfix.java @@ -37,7 +37,8 @@ public class ParseInfix { private static final List NON_CHAINABLE_RELATIONAL_OPS = List.of("isa"); // Chainable equality operators (can chain with each other) - private static final List CHAINABLE_EQUALITY_OPS = Arrays.asList("==", "!=", "eq", "ne"); + private static final List CHAINABLE_EQUALITY_OPS = + Arrays.asList("==", "!=", "===", "!==", "eq", "ne", "equ", "neu"); // Chainable relational operators (can chain with each other) private static final List CHAINABLE_RELATIONAL_OPS = Arrays.asList("<", ">", "<=", ">=", "lt", "gt", "le", "ge"); @@ -59,17 +60,7 @@ public static Node parseInfixOperation(Parser parser, Node left, int precedence) Node right; if (ParserTables.INFIX_OP.contains(token.text)) { - String operator = switch (token.text) { - // Perl 5.44's undef-aware comparison operators currently share - // the established numeric/string comparison execution paths. - // Preserve their precedence and parseability while the runtime - // comparison implementation remains centralized. - case "===" -> "=="; - case "!==" -> "!="; - case "equ" -> "eq"; - case "neu" -> "ne"; - default -> token.text; - }; + String operator = token.text; // Check if left operand is a DECLARED REFERENCE (my \$a, our \@arr, etc.) // Most operators cannot be applied to declared references diff --git a/src/main/java/org/perlonjava/frontend/parser/ParserTables.java b/src/main/java/org/perlonjava/frontend/parser/ParserTables.java index e56c40a2c..107427700 100644 --- a/src/main/java/org/perlonjava/frontend/parser/ParserTables.java +++ b/src/main/java/org/perlonjava/frontend/parser/ParserTables.java @@ -113,6 +113,7 @@ public class ParserTables { CORE_PROTOTYPES.put("endservent", ""); CORE_PROTOTYPES.put("eof", ";*"); CORE_PROTOTYPES.put("eq", null); + CORE_PROTOTYPES.put("equ", null); CORE_PROTOTYPES.put("eval", null); CORE_PROTOTYPES.put("evalbytes", "_"); CORE_PROTOTYPES.put("exec", null); @@ -195,6 +196,7 @@ public class ParserTables { CORE_PROTOTYPES.put("msgsnd", "$$$"); CORE_PROTOTYPES.put("my", null); CORE_PROTOTYPES.put("ne", null); + CORE_PROTOTYPES.put("neu", null); CORE_PROTOTYPES.put("next", null); CORE_PROTOTYPES.put("no", null); CORE_PROTOTYPES.put("not", "$;"); diff --git a/src/main/java/org/perlonjava/runtime/operators/CompareOperators.java b/src/main/java/org/perlonjava/runtime/operators/CompareOperators.java index e6d84479a..1ccfd4260 100644 --- a/src/main/java/org/perlonjava/runtime/operators/CompareOperators.java +++ b/src/main/java/org/perlonjava/runtime/operators/CompareOperators.java @@ -564,6 +564,53 @@ public static RuntimeScalar ne(RuntimeScalar runtimeScalar, RuntimeScalar arg2) return getScalarBoolean(!stringEquals(runtimeScalar, arg2)); } + /** + * Defined string equality ({@code equ}). Unlike {@code eq}, undef is a + * value in its own right: two undefs compare equal, while undef and any + * defined value compare unequal without producing an uninitialized warning. + */ + public static RuntimeScalar equ(RuntimeScalar arg1, RuntimeScalar arg2) { + boolean defined1 = arg1.getDefinedBoolean(); + boolean defined2 = arg2.getDefinedBoolean(); + if (!defined1 || !defined2) { + return getScalarBoolean(defined1 == defined2); + } + return eq(arg1, arg2); + } + + /** Defined string inequality ({@code neu}), the inverse of {@code equ}. */ + public static RuntimeScalar neu(RuntimeScalar arg1, RuntimeScalar arg2) { + boolean defined1 = arg1.getDefinedBoolean(); + boolean defined2 = arg2.getDefinedBoolean(); + if (!defined1 || !defined2) { + return getScalarBoolean(defined1 != defined2); + } + return ne(arg1, arg2); + } + + /** + * Defined numeric equality ({@code ===}). It has the same overload + * behavior as {@code ==}, but does not coerce undef or warn about it. + */ + public static RuntimeScalar strictEqual(RuntimeScalar arg1, RuntimeScalar arg2) { + boolean defined1 = arg1.getDefinedBoolean(); + boolean defined2 = arg2.getDefinedBoolean(); + if (!defined1 || !defined2) { + return getScalarBoolean(defined1 == defined2); + } + return equalTo(arg1, arg2); + } + + /** Defined numeric inequality ({@code !==}), the inverse of {@code ===}. */ + public static RuntimeScalar strictNotEqual(RuntimeScalar arg1, RuntimeScalar arg2) { + boolean defined1 = arg1.getDefinedBoolean(); + boolean defined2 = arg2.getDefinedBoolean(); + if (!defined1 || !defined2) { + return getScalarBoolean(defined1 != defined2); + } + return notEqualTo(arg1, arg2); + } + /** * Throws a Perl-5-style "Operation '': no method found" error when * the overloaded package on either side does not permit fallback diff --git a/src/main/java/org/perlonjava/runtime/operators/OperatorHandler.java b/src/main/java/org/perlonjava/runtime/operators/OperatorHandler.java index 31205bf88..7733b0370 100644 --- a/src/main/java/org/perlonjava/runtime/operators/OperatorHandler.java +++ b/src/main/java/org/perlonjava/runtime/operators/OperatorHandler.java @@ -120,6 +120,10 @@ public record OperatorHandler(String className, String methodName, int methodTyp put("<=>", "spaceship", "org/perlonjava/runtime/operators/CompareOperators"); put("eq", "eq", "org/perlonjava/runtime/operators/CompareOperators"); put("ne", "ne", "org/perlonjava/runtime/operators/CompareOperators"); + put("equ", "equ", "org/perlonjava/runtime/operators/CompareOperators"); + put("neu", "neu", "org/perlonjava/runtime/operators/CompareOperators"); + put("===", "strictEqual", "org/perlonjava/runtime/operators/CompareOperators"); + put("!==", "strictNotEqual", "org/perlonjava/runtime/operators/CompareOperators"); put("lt", "lt", "org/perlonjava/runtime/operators/CompareOperators"); put("le", "le", "org/perlonjava/runtime/operators/CompareOperators"); put("gt", "gt", "org/perlonjava/runtime/operators/CompareOperators"); diff --git a/src/test/resources/unit/defined_comparison_operators.t b/src/test/resources/unit/defined_comparison_operators.t new file mode 100644 index 000000000..2d34ef5f4 --- /dev/null +++ b/src/test/resources/unit/defined_comparison_operators.t @@ -0,0 +1,13 @@ +use strict; +use warnings; +my ($a, $b); + +print "1..8\n"; +print "ok 1 - equ compares defined strings\n" if 'abc' equ 'abc'; +print "ok 2 - equ distinguishes different strings\n" if !('abc' equ 'def'); +print "ok 3 - equ considers two undefs equal\n" if !defined($a) && !defined($b) && ($a equ $b); +print "ok 4 - equ distinguishes undef from empty string\n" if !($a equ ''); +print "ok 5 - neu is the inverse of equ\n" if 'abc' neu 'def'; +print "ok 6 - strict numeric equality compares numbers\n" if 123 === 123; +print "ok 7 - strict numeric equality considers two undefs equal\n" if $a === $b; +print "ok 8 - strict numeric inequality distinguishes undef and zero\n" if $a !== 0; From 098b8eb795f27148d892e77306430f460a296423 Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Mon, 7 Sep 2026 19:41:53 +0200 Subject: [PATCH 4/5] fix: execute chained comparisons in interpreter Compile nested comparison ASTs as left-to-right short-circuit chains in the bytecode backend, matching JVM behavior and evaluating each operand once. Extend the defined-comparison regression test with mixed chains and a short-circuit side-effect check. Generated with [Codex](https://openai.com/codex) Co-Authored-By: Codex <158243242+openai-codex[bot]@users.noreply.github.com> --- .../bytecode/CompileBinaryOperator.java | 79 +++++++++++++++++++ .../unit/defined_comparison_operators.t | 9 ++- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/perlonjava/backend/bytecode/CompileBinaryOperator.java b/src/main/java/org/perlonjava/backend/bytecode/CompileBinaryOperator.java index f8d9879f2..9e342a6d8 100644 --- a/src/main/java/org/perlonjava/backend/bytecode/CompileBinaryOperator.java +++ b/src/main/java/org/perlonjava/backend/bytecode/CompileBinaryOperator.java @@ -8,6 +8,10 @@ import org.perlonjava.runtime.runtimetypes.RuntimeContextType; import org.perlonjava.runtime.runtimetypes.RuntimeScalar; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class CompileBinaryOperator { static void visitBinaryOperator(BytecodeCompiler bytecodeCompiler, BinaryOperatorNode node) { int savedCallerLineOverride = bytecodeCompiler.callerLineTokenOverride; @@ -30,6 +34,16 @@ private static void visitBinaryOperatorBody(BytecodeCompiler bytecodeCompiler, B // Track token index for error reporting bytecodeCompiler.currentTokenIndex = node.getIndex(); + // Perl evaluates chained comparisons left-to-right, evaluating each + // operand once and stopping as soon as a comparison is false. The JVM + // backend has a dedicated emitter for this shape; keep the bytecode + // interpreter backend equivalent instead of compiling the nested AST as + // ordinary boolean comparisons. + if (isChainedComparison(node)) { + compileChainedComparison(bytecodeCompiler, node); + return; + } + // Handle print/say early (special handling for filehandle) if (node.operator.equals("print") || node.operator.equals("say")) { // print/say FILEHANDLE LIST @@ -798,6 +812,71 @@ else if (node.right instanceof BinaryOperatorNode rightCall) { bytecodeCompiler.lastResultReg = rd; } + private static final List CHAIN_COMPARISON_OPS = + Arrays.asList("<", ">", "<=", ">=", "lt", "gt", "le", "ge"); + private static final List CHAIN_EQUALITY_OPS = + Arrays.asList("==", "!=", "===", "!==", "eq", "ne", "equ", "neu"); + + private static boolean isChainedComparison(BinaryOperatorNode node) { + if (!(node.left instanceof BinaryOperatorNode left)) { + return false; + } + boolean equality = CHAIN_EQUALITY_OPS.contains(node.operator); + boolean comparison = CHAIN_COMPARISON_OPS.contains(node.operator); + if (!equality && !comparison) { + return false; + } + return (equality && CHAIN_EQUALITY_OPS.contains(left.operator)) + || (comparison && CHAIN_COMPARISON_OPS.contains(left.operator)); + } + + private static void compileChainedComparison(BytecodeCompiler bytecodeCompiler, + BinaryOperatorNode node) { + List operands = new ArrayList<>(); + List operators = new ArrayList<>(); + BinaryOperatorNode current = node; + boolean equality = CHAIN_EQUALITY_OPS.contains(node.operator); + while (true) { + operators.add(0, current.operator); + operands.add(0, current.right); + if (current.left instanceof BinaryOperatorNode left + && ((equality && CHAIN_EQUALITY_OPS.contains(left.operator)) + || (!equality && CHAIN_COMPARISON_OPS.contains(left.operator)))) { + current = left; + } else { + operands.add(0, current.left); + break; + } + } + + int resultReg = bytecodeCompiler.allocateOutputRegister(); + bytecodeCompiler.compileNode(operands.get(0), -1, RuntimeContextType.SCALAR); + int leftReg = bytecodeCompiler.lastResultReg; + List falseJumpPositions = new ArrayList<>(); + + for (int i = 0; i < operators.size(); i++) { + bytecodeCompiler.compileNode(operands.get(i + 1), -1, RuntimeContextType.SCALAR); + int rightReg = bytecodeCompiler.lastResultReg; + int comparisonReg = CompileBinaryOperatorHelper.compileBinaryOperatorSwitch( + bytecodeCompiler, operators.get(i), leftReg, rightReg, node.getIndex()); + bytecodeCompiler.emitAliasWithTarget(resultReg, comparisonReg); + + if (i + 1 < operators.size()) { + bytecodeCompiler.emit(bytecodeCompiler.gotoIfFalseOpcode()); + bytecodeCompiler.emitReg(resultReg); + falseJumpPositions.add(bytecodeCompiler.bytecode.size()); + bytecodeCompiler.emitInt(0); + } + leftReg = rightReg; + } + + int endPc = bytecodeCompiler.bytecode.size(); + for (int patchPosition : falseJumpPositions) { + bytecodeCompiler.patchIntOffset(patchPosition, endPc); + } + bytecodeCompiler.lastResultReg = resultReg; + } + private static boolean isDirectScalarLvalue(Node node) { if (node instanceof OperatorNode operator) { return operator.operator.equals("$"); diff --git a/src/test/resources/unit/defined_comparison_operators.t b/src/test/resources/unit/defined_comparison_operators.t index 2d34ef5f4..8d24b9348 100644 --- a/src/test/resources/unit/defined_comparison_operators.t +++ b/src/test/resources/unit/defined_comparison_operators.t @@ -1,8 +1,10 @@ use strict; use warnings; my ($a, $b); +my $calls = 0; +sub chain_value { ++$calls; $_[0] } -print "1..8\n"; +print "1..11\n"; print "ok 1 - equ compares defined strings\n" if 'abc' equ 'abc'; print "ok 2 - equ distinguishes different strings\n" if !('abc' equ 'def'); print "ok 3 - equ considers two undefs equal\n" if !defined($a) && !defined($b) && ($a equ $b); @@ -11,3 +13,8 @@ print "ok 5 - neu is the inverse of equ\n" if 'abc' neu 'def'; print "ok 6 - strict numeric equality compares numbers\n" if 123 === 123; print "ok 7 - strict numeric equality considers two undefs equal\n" if $a === $b; print "ok 8 - strict numeric inequality distinguishes undef and zero\n" if $a !== 0; +print "ok 9 - equ chains\n" if ('abc' equ 'abc' equ 'abc'); +print "ok 10 - mixed strict equality chains\n" if (123 === 123 == 123); +my $chain_result = chain_value(0) equ chain_value(1) equ chain_value(1); +print "ok 11 - chains short-circuit after false\n" + if $calls == 2 && !$chain_result; From 707b43459b84840a9fb03c7a7bfdea06a67c084f Mon Sep 17 00:00:00 2001 From: "Flavio S. Glock" Date: Mon, 7 Sep 2026 20:22:46 +0200 Subject: [PATCH 5/5] fix: avoid duplicate FETCH in defined comparisons Fetch tied operands once before equ, neu, ===, and !== check definedness and perform the comparison on the fetched values. This preserves Perl's fetch count semantics for the new operators. Generated with [Codex](https://openai.com/codex) Co-Authored-By: Codex <158243242+openai-codex[bot]@users.noreply.github.com> --- .../runtime/operators/CompareOperators.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/org/perlonjava/runtime/operators/CompareOperators.java b/src/main/java/org/perlonjava/runtime/operators/CompareOperators.java index 1ccfd4260..e4687c052 100644 --- a/src/main/java/org/perlonjava/runtime/operators/CompareOperators.java +++ b/src/main/java/org/perlonjava/runtime/operators/CompareOperators.java @@ -570,6 +570,8 @@ public static RuntimeScalar ne(RuntimeScalar runtimeScalar, RuntimeScalar arg2) * defined value compare unequal without producing an uninitialized warning. */ public static RuntimeScalar equ(RuntimeScalar arg1, RuntimeScalar arg2) { + arg1 = fetchDefinedComparisonOperand(arg1); + arg2 = fetchDefinedComparisonOperand(arg2); boolean defined1 = arg1.getDefinedBoolean(); boolean defined2 = arg2.getDefinedBoolean(); if (!defined1 || !defined2) { @@ -580,6 +582,8 @@ public static RuntimeScalar equ(RuntimeScalar arg1, RuntimeScalar arg2) { /** Defined string inequality ({@code neu}), the inverse of {@code equ}. */ public static RuntimeScalar neu(RuntimeScalar arg1, RuntimeScalar arg2) { + arg1 = fetchDefinedComparisonOperand(arg1); + arg2 = fetchDefinedComparisonOperand(arg2); boolean defined1 = arg1.getDefinedBoolean(); boolean defined2 = arg2.getDefinedBoolean(); if (!defined1 || !defined2) { @@ -593,6 +597,8 @@ public static RuntimeScalar neu(RuntimeScalar arg1, RuntimeScalar arg2) { * behavior as {@code ==}, but does not coerce undef or warn about it. */ public static RuntimeScalar strictEqual(RuntimeScalar arg1, RuntimeScalar arg2) { + arg1 = fetchDefinedComparisonOperand(arg1); + arg2 = fetchDefinedComparisonOperand(arg2); boolean defined1 = arg1.getDefinedBoolean(); boolean defined2 = arg2.getDefinedBoolean(); if (!defined1 || !defined2) { @@ -603,6 +609,8 @@ public static RuntimeScalar strictEqual(RuntimeScalar arg1, RuntimeScalar arg2) /** Defined numeric inequality ({@code !==}), the inverse of {@code ===}. */ public static RuntimeScalar strictNotEqual(RuntimeScalar arg1, RuntimeScalar arg2) { + arg1 = fetchDefinedComparisonOperand(arg1); + arg2 = fetchDefinedComparisonOperand(arg2); boolean defined1 = arg1.getDefinedBoolean(); boolean defined2 = arg2.getDefinedBoolean(); if (!defined1 || !defined2) { @@ -611,6 +619,16 @@ public static RuntimeScalar strictNotEqual(RuntimeScalar arg1, RuntimeScalar arg return notEqualTo(arg1, arg2); } + /** + * Fetch a tied operand once before the definedness check and subsequent + * comparison. Calling {@code getDefinedBoolean()} on the tied wrapper and + * then passing that same wrapper to the ordinary comparison would invoke + * FETCH twice. + */ + private static RuntimeScalar fetchDefinedComparisonOperand(RuntimeScalar arg) { + return arg.type == RuntimeScalarType.TIED_SCALAR ? arg.tiedFetch() : arg; + } + /** * Throws a Perl-5-style "Operation '': no method found" error when * the overloaded package on either side does not permit fallback