khrt / Raisin

Raisin - a REST API micro framework for Perl 🐫 🐪
61 stars 29 forks source link

t/unit/plugin/swagger.t fails (with Type::Tiny 1.006000?) #93

Closed eserte closed 4 years ago

eserte commented 4 years ago

On my smokers I see the following test failure:

    #   Failed test 'POST body enum'
    #   at t/unit/plugin/swagger.t line 272.
    #     Structures begin differing at:
    #          $got->[0]{enum}[0] = 'foo'
    #     $expected->[0]{enum}[0] = 'bar'
    # Looks like you failed 1 test of 6.

#   Failed test '_parameters_object'
#   at t/unit/plugin/swagger.t line 274.
# Looks like you failed 1 test of 9.
t/unit/plugin/swagger.t ............... 
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/9 subtests 
    (less 4 skipped subtests: 4 okay)

Statistical analysis suggests that this problem happens if Type::Tiny 1.006000 is installed (@tobyink: FYI):

****************************************************************
Regression 'mod:Type::Tiny'
****************************************************************
Name                   Theta          StdErr     T-stat
[0='const']           1.0000          0.0000    22478982614387572.00
[1='eq_1.004004']        -0.0000          0.0000      -4.26
[2='eq_1.006000']        -1.0000          0.0000    -21597107912751200.00

R^2= 1.000, N= 47, K= 3
****************************************************************
tobyink commented 4 years ago

In older versions of Type::Tiny::Enum, the values method and the @{} overload would return the enum values sorted alphabetically and filtered to remove duplicates. The deduping and sorting was never documented. And it was inconsistent with Moose::Meta::TypeConstraint::Enum's values method which doesn't dedupe or sort the list. (And Type::Tiny::Enum tries to emulate the Moose API where possible.)

Since 1.006000, values and @{} now return the original list of values, not sorted or deduped. (But non-strings are stringified.) There's a new method called unique_values that returns a sorted deduped list.

tobyink commented 4 years ago

I've had a quick look at the Raisin code and it looks like having Moose and Type::Tiny's behaviour match up here will actually be helpful as you're supporting both kinds of Enum. The test case can be fixed by just changing qw( foo bar ) to qw( bar foo ) when you create the type (rather than when you test it in the expected bit). That way $enum->values will return bar first in both older and newer releases of Type::Tiny.

khrt commented 4 years ago

Thanks @tobyink. Fixed as suggested.

tobyink commented 4 years ago

You've changed the expected. The way you've changed it, it will work on 1.006000 but I think it will fail on older versions.

You want something like this:

    {
        method => 'POST',
        params => [
            Raisin::Param->new(
                named => 0,
                type  => 'required',
                spec  => { name => 'enum', type => Enum[qw(bar foo)], default => 'foo', in => 'body' }, # the change is here
            )
        ],
        expected => [
            {
                default     => 'foo',
                description => '',
                in          => 'body',
                name        => 'enum',
                required    => JSON::MaybeXS::true,
                type        => 'string',
                enum        => [qw(bar foo)],
            }
        ]
    },

This way, whether Enum sorts qw(bar foo) or leaves it in its original order doesn't matter, because the original order is already sorted.

khrt commented 4 years ago

Thanks!

Updated: https://github.com/khrt/Raisin/commit/8ad81b7802d4ec9e26d1aa37ca29f300c079acea