| 1 | #!/usr/bin/perl |
|---|
| 2 | |
|---|
| 3 | use strict; |
|---|
| 4 | use warnings; |
|---|
| 5 | use lib 'lib'; |
|---|
| 6 | |
|---|
| 7 | use Test::More tests => 35; |
|---|
| 8 | |
|---|
| 9 | BEGIN { $ENV{CATALYST_DEBUG} = 0; } |
|---|
| 10 | BEGIN { use_ok 'Catalyst::Test', 'Vee' } |
|---|
| 11 | BEGIN { use_ok 'Vee::Controller::Dex::Search' } |
|---|
| 12 | |
|---|
| 13 | sub search_ok; |
|---|
| 14 | |
|---|
| 15 | ### Simple search tests; these get slightly more complex as they go on, and in |
|---|
| 16 | ### general I tried to keep the resultset small so it's easy to verify manually |
|---|
| 17 | |
|---|
| 18 | ok request('/dex/pokemon/search')->is_success, "Pokemon search page loads"; |
|---|
| 19 | |
|---|
| 20 | search_ok { name => 'eon' }, |
|---|
| 21 | [qw/ 5 134 135 136 196 197 352 395 456 457 470 471 /], |
|---|
| 22 | "Name substring"; |
|---|
| 23 | |
|---|
| 24 | search_ok { name => '???' }, |
|---|
| 25 | [qw/ 89 151 /], |
|---|
| 26 | "Name with wildcards"; |
|---|
| 27 | |
|---|
| 28 | search_ok { ability => 'Drizzle' }, |
|---|
| 29 | [qw/ 382 /], |
|---|
| 30 | "Ability"; |
|---|
| 31 | |
|---|
| 32 | search_ok { color => 'black', habitat => 'urban' }, |
|---|
| 33 | [qw/ 197 353 354 /], |
|---|
| 34 | "Color and habitat"; |
|---|
| 35 | |
|---|
| 36 | search_ok { name => 'eon', evo_stage => 'base' }, |
|---|
| 37 | [qw/ 352 456 /], |
|---|
| 38 | "Baseforms (+ name)"; |
|---|
| 39 | |
|---|
| 40 | search_ok { name => 'char', evo_stage => 'final' }, |
|---|
| 41 | [qw/ 6 /], |
|---|
| 42 | "Final forms (+ name)"; |
|---|
| 43 | |
|---|
| 44 | # Gender dropdown had a few problems at one point, so I gave it several tests |
|---|
| 45 | search_ok { gender_rate => 254, generation => 0 }, |
|---|
| 46 | [qw/ 29 30 31 113 115 124 /], |
|---|
| 47 | "Female-only (+ generation)"; |
|---|
| 48 | |
|---|
| 49 | search_ok { name => 'voltorb', gender_rate => 'not255' }, |
|---|
| 50 | [qw/ /], |
|---|
| 51 | "Any gender (+ name)"; |
|---|
| 52 | |
|---|
| 53 | search_ok { name => 'eevee', gender_rate => 255 }, |
|---|
| 54 | [qw/ /], |
|---|
| 55 | "No gender (+ impossible name)"; |
|---|
| 56 | |
|---|
| 57 | # Likewise with the breeding; that's gone wrong several times |
|---|
| 58 | search_ok { breed_mode => 'and', breed => [1, 2], evo_stage => 'base' }, |
|---|
| 59 | [qw/ 7 79 131 158 258 /], |
|---|
| 60 | "Two different egg groups with 'and' (+ baseform)"; |
|---|
| 61 | |
|---|
| 62 | search_ok { breed_mode => 'and', breed => [13, 13] }, |
|---|
| 63 | [qw/ 132 /], |
|---|
| 64 | "Two identical egg groups with 'and'"; |
|---|
| 65 | |
|---|
| 66 | search_ok { breed_mode => 'and', breed => [13, 0] }, |
|---|
| 67 | [qw/ 132 /], |
|---|
| 68 | "One egg group plus n/a with 'and'"; |
|---|
| 69 | |
|---|
| 70 | search_ok { breed_mode => 'and', breed => [13, 5] }, |
|---|
| 71 | [qw/ /], |
|---|
| 72 | "Two different egg groups with 'and' that can't occur together"; |
|---|
| 73 | |
|---|
| 74 | search_ok { |
|---|
| 75 | breed_mode => 'or', |
|---|
| 76 | breed => [9, 11], |
|---|
| 77 | evo_stage => 'base', |
|---|
| 78 | generation => 0, |
|---|
| 79 | }, |
|---|
| 80 | [qw/ 72 88 90 92 98 109 120 138 140 /], |
|---|
| 81 | "Two different egg groups with 'or' (+ generation and baseform)"; |
|---|
| 82 | |
|---|
| 83 | search_ok { generation => 2, basedex => 3 }, |
|---|
| 84 | [qw/ 265 266 267 268 269 278 279 298 307 308 315 339 340 349 350 358 /], |
|---|
| 85 | "Generation and base Pokedex"; |
|---|
| 86 | |
|---|
| 87 | # Types are another common problem area |
|---|
| 88 | search_ok { name => 'eon', type_mode => 'any', type => [qw/ fire /] }, |
|---|
| 89 | [qw/ 5 136 /], |
|---|
| 90 | "Single type with 'any' (+ name)"; |
|---|
| 91 | |
|---|
| 92 | search_ok { name => 'eon', type_mode => 'any', type => [qw/ fire water /] }, |
|---|
| 93 | [qw/ 5 134 136 395 456 457 /], |
|---|
| 94 | "Two types with 'any' (+ name)"; |
|---|
| 95 | |
|---|
| 96 | search_ok { name => 'eon', type_mode => 'any', type => [qw/ fire water electric /] }, |
|---|
| 97 | [qw/ 5 134 135 136 395 456 457 /], |
|---|
| 98 | "Three types with 'any' (+ name)"; |
|---|
| 99 | |
|---|
| 100 | search_ok { type_mode => 'all', type => [qw/ bug dragon /] }, |
|---|
| 101 | [qw/ /], |
|---|
| 102 | "Two types with 'all' that never occur"; |
|---|
| 103 | |
|---|
| 104 | search_ok { type_mode => 'all', type => [qw/ ghost dragon /] }, |
|---|
| 105 | [qw/ 487 /], |
|---|
| 106 | "Two types with 'all'"; |
|---|
| 107 | |
|---|
| 108 | search_ok { type_mode => 'all', type => [qw/ dragon ghost /] }, |
|---|
| 109 | [qw/ 487 /], |
|---|
| 110 | "Same two types with 'all', reversed (i.e. order doesn't matter)"; |
|---|
| 111 | |
|---|
| 112 | search_ok { type_mode => 'all', type => [qw/ normal flying psychic /] }, |
|---|
| 113 | [qw/ /], |
|---|
| 114 | "Three types with 'all'"; |
|---|
| 115 | |
|---|
| 116 | # Moves have a lot of possibilities; I just try a few easy ones here |
|---|
| 117 | search_ok { move => 'judgment' }, |
|---|
| 118 | [qw/ 493 /], |
|---|
| 119 | "Single move"; |
|---|
| 120 | |
|---|
| 121 | search_ok { move => 'judgment', move_method => [qw/ egg machine tutor /] }, |
|---|
| 122 | [qw/ /], |
|---|
| 123 | "Single move not by leveling up"; |
|---|
| 124 | |
|---|
| 125 | search_ok { move => 'judgment', move_version => [qw/ rb y gs c rusa frlg e /] }, |
|---|
| 126 | [qw/ /], |
|---|
| 127 | "Single move by not in D/P"; |
|---|
| 128 | |
|---|
| 129 | search_ok { move => [qw/ splash tackle /], move_version => 'rb' }, |
|---|
| 130 | [qw/ 129 /], |
|---|
| 131 | "Two moves in a specific generation"; |
|---|
| 132 | |
|---|
| 133 | # Similar for the stats; these all work the same so whatever |
|---|
| 134 | search_ok { stat_hp_lb => 250 }, |
|---|
| 135 | [qw/ 113 242 /], |
|---|
| 136 | "Lower bound on HP"; |
|---|
| 137 | |
|---|
| 138 | # Height and weight had some rounding issues |
|---|
| 139 | search_ok { generation => 1, height_lb => 16, height_ub => 16 }, |
|---|
| 140 | [qw/ 182 183 187 194 220 238 /], |
|---|
| 141 | "Exact height in inches (+ generation)"; |
|---|
| 142 | |
|---|
| 143 | search_ok { height_lb => '0.2m', height_ub => '0.2m' }, |
|---|
| 144 | [qw/ 50 177 298 406 412 433 492 /], |
|---|
| 145 | "Exact height in meters"; |
|---|
| 146 | |
|---|
| 147 | search_ok { height_lb => '20cm', height_ub => '20cm' }, |
|---|
| 148 | [qw/ 50 177 298 406 412 433 492 /], |
|---|
| 149 | "Exact height in centimeters"; |
|---|
| 150 | |
|---|
| 151 | # Quick sorting checks |
|---|
| 152 | search_ok { name => 'q', sort => 'stat_avg' }, |
|---|
| 153 | [qw/ 155 7 156 284 195 211 416 31 384 /], |
|---|
| 154 | "Sorting by average stat"; |
|---|
| 155 | |
|---|
| 156 | search_ok { name => 'q', sort => 'id', sort_desc => 'on' }, |
|---|
| 157 | [qw/ 416 384 284 211 195 156 155 31 7 /], |
|---|
| 158 | "Reverse sort by id"; |
|---|
| 159 | |
|---|
| 160 | sub search_ok { |
|---|
| 161 | my ($params, $expected, $test_name) = @_; |
|---|
| 162 | |
|---|
| 163 | if (not $params->{sort}) { |
|---|
| 164 | # sort by id for simplicity |
|---|
| 165 | $params->{sort} = 'id'; |
|---|
| 166 | delete $params->{sort_desc}; |
|---|
| 167 | } |
|---|
| 168 | |
|---|
| 169 | my $context = Vee->prepare; |
|---|
| 170 | $context->req->params($params); |
|---|
| 171 | Vee::Controller::Dex::Search->pokemon_search($context); |
|---|
| 172 | |
|---|
| 173 | my $pokemon_rows = $context->stash->{results} || []; |
|---|
| 174 | my @pokemon = map { $_->id } @$pokemon_rows; |
|---|
| 175 | |
|---|
| 176 | is_deeply \@pokemon, $expected, $test_name; |
|---|
| 177 | } |
|---|