{"id":19640374,"url":"https://github.com/kentnl/generic-assertions","last_synced_at":"2026-06-18T14:31:41.412Z","repository":{"id":22390813,"uuid":"25727703","full_name":"kentnl/Generic-Assertions","owner":"kentnl","description":"A Generic Assertion checking class","archived":false,"fork":false,"pushed_at":"2017-03-03T16:41:05.000Z","size":102,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-09T18:57:06.347Z","etag":null,"topics":["perl"],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kentnl.png","metadata":{"files":{"readme":"README.mkdn","changelog":"Changes","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-25T10:26:04.000Z","updated_at":"2017-03-03T15:08:58.000Z","dependencies_parsed_at":"2022-07-25T13:17:06.945Z","dependency_job_id":null,"html_url":"https://github.com/kentnl/Generic-Assertions","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kentnl%2FGeneric-Assertions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kentnl%2FGeneric-Assertions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kentnl%2FGeneric-Assertions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kentnl%2FGeneric-Assertions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kentnl","download_url":"https://codeload.github.com/kentnl/Generic-Assertions/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240947648,"owners_count":19883030,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["perl"],"created_at":"2024-11-11T14:05:36.575Z","updated_at":"2025-11-21T14:04:39.339Z","avatar_url":"https://github.com/kentnl.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NAME\n\nGeneric::Assertions - A Generic Assertion checking class\n\n# VERSION\n\nversion 0.001003\n\n# ALPHA\n\nThis is pre-release code, and as such `API` is very much subject to change.\n\nBest attempts at being consolidated is already made, but there's no guarantees at this time\nthings won't change and break `API` without warning.\n\n# SYNOPSIS\n\n    use Generic::Assertions;\n    use Path::Tiny qw(path);\n\n    my $assert = Generic::Assertions-\u003enew(\n      exist =\u003e sub {\n        return (1, \"Path $_[0] exists\") if path($_[0])-\u003eexists;\n        return (0, \"Path $_[0] does not exist\");\n      },\n    );\n\n    ...\n\n    sub foo {\n      my ( $path ) = @_;\n\n      # carp unless $path exists with \"Path $path does not exist\"\n      $assert-\u003eshould( exist =\u003e $path );\n\n      # carp if $path exists with \"Path $path exists\"\n      $assert-\u003eshould_not( exist =\u003e $path );\n\n      # croak unless $path exists with \"Path $path does not exist\"\n      $assert-\u003emust( exist =\u003e $path );\n\n      # Lower level way to use the assertion simply to return truth value\n      # without side effects.\n      if ( $assert-\u003etest( exist =\u003e $path ) ) {\n\n      }\n\n      # carp unconditionally showing the test result and its message\n      $assert-\u003elog( exist =\u003e $path );\n    }\n\n# DESCRIPTION\n\n`Generic::Assertions` allows you to create portable containers of classes of assertions, and allows keeping\nseverity of assertions from their implementation.\n\nBasic implementation entails\n\n- Defining a list of things to test for\n- Returning a pair of ( OK / NOT\\_OK , \"reason\" ) for the tests conclusion\n- \\[optional\\] Defining a default handler for various classes of severity ( `should`, `must` etc. )\n- \\[optional\\] Defining an input transform (eg: always converting the first argument to a path)\n- Invoking the assertion at the callpoint as `$instance-\u003eseverity_level( test_name =\u003e @args_for_test )`\n\n# METHODS\n\n## `new`\n\nConstructs a Generic::Assertions object.\n\n    my $assertion = Generic::Assertions-\u003enew( ARGS );\n\nThe following forms of `ARGS` is supported:\n\n    -\u003enew(   key =\u003e value    );\n    -\u003enew({  key =\u003e value   });\n\nAll `keys` without a `-` prefix are assumed to be test names, and are equivalent to:\n\n    -\u003enew( -tests =\u003e { key =\u003e value } );\n\n### `-tests`\n\nAll tests must have a simple string key, and a `CodeRef` value.\n\nAn example test looks like:\n\n    sub {\n       my ( @slurpy ) = @_;\n       if ( -e $slurpy[0] ) {\n         return ( 1, \"$slurpy[0] exists\" );\n       }\n       return ( 0, \"$slurpy[1] does not exist\" );\n    }\n\nThat is, each test must return either a `true` value or a `false` value.\nAnd each test must return a string describing the condition.\n\nThis is so it composes nicely:\n\n    $ass-\u003eshould( exist =\u003e $foo ); # warns \"$foo does not exist\" if it doesn't\n    $ass-\u003eshould_not( exist =\u003e $foo ); # warns \"$foo exists\" if it does.\n\nNote the test itself can only see the arguments passed directly to it at the calling point.\n\n### `-handlers`\n\nEach of the various assertion types have a handler underlying them, which can be overridden\nduring construction.\n\n    -\u003enew( -handlers =\u003e { should =\u003e sub { ... } } );\n\nThis for instance will override the default handler for \"should\" and will be invoked\nsomewhere after the result from\n\n    $assertion-\u003eshould(  )\n\nIs obtained.\n\nAn example handler approximating the default `should` handler.\n\n    sub {\n      my ( $status, $message, $name, @slurpy ) = @_;\n      # $status is the 0/1 returned by the test.\n      # $message is the message the test gave.\n      # $name is the name of the test invoked ( ie: -\u003eshould( foo =\u003e ... )\n      # @slurpy is the arguments passed from the user to the test.\n      carp $message if $status;\n      return $slurpy[0];\n    }\n\nIts worth noting that handlers dictate in entirety:\n\n- What calls will be invoked in response to the fail/pass returned by the test\n- What will be returned to the caller who invoked the test\n\nFor instance, the `test` handler is simply:\n\n    sub {\n      my ( $status ) = @_;\n      return $status;\n    }\n\nAnd you could perhaps change that to\n\n    sub {\n      my ( $status, $message ) = @_;\n      return $message;\n    }\n\nAnd then invoking\n\n    -\u003etest( foo =\u003e @args );\n\nWould return `foo`'s message instead of its return value.\n\nUse this power with care.\n\n#### Custom Handlers\n\nYou can of course define custom handlers outside the core functionality,\nexcept of course they won't be accessible as convenient methods.\n\nYou can perhaps invoke them via\n\n    -\u003e_assert( $handler_name, $test_name, @slurpy_args )\n\nBut it would be probably nicer for you to sub-class `Generic::Assertions` and make\nit available as a native method:\n\n    -\u003e$handler_name( $test_name, @slurpy_args )\n\n### `-input_transformer`\n\nYou can specify a `CodeRef` through which all tests get passed as a primary step.\n\n    -\u003enew(\n      -input_transformer =\u003e sub {\n        # Gets both the name, and all the tests arguments\n        my ( $name, $path )  = @_;\n        # Returns a substitute argument list\n        return path( $path );\n      },\n      exist =\u003e sub {\n        return ( 0, \"$_[0] does not exist\" ) unless $_[0]-\u003eexists;\n        return ( 1, \"$_[1] exists\" );\n      },\n    );\n\n    ...\n    # The following code will now check that foo.pm exist\n    # and if it exists, return a path() object for it as $rval.\n    # If foo.pm does not exist, it will warn.\n    #\n    # $rval will be a path object in both cases.\n    my $rval = $ass-\u003eshould( exist =\u003e \"./foo.pm\" );\n\n    # Under default configuration, this is basically the same as:\n    sub should_exist {\n      my @args = @_;\n      my $path = path($args[0]);\n      if ( not $path-\u003eexists() ) {\n        warn \"$path does not exist\";\n      }\n      return $path;\n    }\n    my $rval = $thing-\u003eshould_exist(\"./foo.pm\");\n    # Except of course more composable.\n\n## `test`\n\nDefault implementation simply returns the result of the given test.\n\n    if ( $assertion-\u003etest( test_name =\u003e @args ) ) {\n\n    }\n\n## `log`\n\nDefault implementation 'carp's the message and status given by `test_name`, and returns `$args[0]`\n\n    $assertion-\u003elog( test_name =\u003e @args );\n\n## `should`\n\nDefault implementation carps if `test_name` returns `false` with the message provided by `test_name`.\nIt then returns `$args[0]`\n\n    $assertion-\u003eshould( test_name =\u003e @args );\n\n## `should_not`\n\nDefault implementation carps if `test_name` returns `true` with the message provided by `test_name`.\nIt then returns `$args[0]`\n\n    $assertion-\u003eshould_not( test_name =\u003e @args );\n\n## `must`\n\nDefault implementation croaks if `test_name` returns `false` with the message provided by `test_name`.\n\n    $assertion-\u003emust( test_name =\u003e @args );\n\n## `must_not`\n\nDefault implementation croaks if `test_name` returns `true` with the message provided by `test_name`.\n\n    $assertion-\u003emust_not( test_name =\u003e @args );\n\n# THANKS\n\nTo David Golden/xdg for oversight on some of the design concerns on this module.\n\nIt would be for sure much uglier than it presently is without his help :)\n\n# AUTHOR\n\nKent Fredric \u003ckentnl@cpan.org\u003e\n\n# COPYRIGHT AND LICENSE\n\nThis software is copyright (c) 2017 by Kent Fredric \u003ckentfredric@gmail.com\u003e.\n\nThis is free software; you can redistribute it and/or modify it under\nthe same terms as the Perl 5 programming language system itself.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkentnl%2Fgeneric-assertions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkentnl%2Fgeneric-assertions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkentnl%2Fgeneric-assertions/lists"}