| 1 | module veb |
| 2 | |
| 3 | struct RoutePair { |
| 4 | url string |
| 5 | route string |
| 6 | } |
| 7 | |
| 8 | fn (rp RoutePair) test() ?[]string { |
| 9 | url := rp.url.split('/').filter(it != '') |
| 10 | route := rp.route.split('/').filter(it != '') |
| 11 | return route_matches(url, route) |
| 12 | } |
| 13 | |
| 14 | fn (rp RoutePair) test_match() { |
| 15 | rp.test() or { panic('should match: ${rp}') } |
| 16 | } |
| 17 | |
| 18 | fn (rp RoutePair) test_no_match() { |
| 19 | rp.test() or { return } |
| 20 | panic('should not match: ${rp}') |
| 21 | } |
| 22 | |
| 23 | fn (rp RoutePair) test_param(expected []string) { |
| 24 | res := rp.test() or { panic('should match: ${rp}') } |
| 25 | assert res == expected |
| 26 | } |
| 27 | |
| 28 | fn test_route_no_match() { |
| 29 | tests := [ |
| 30 | RoutePair{ |
| 31 | url: '/a' |
| 32 | route: '/a/b/c' |
| 33 | }, |
| 34 | RoutePair{ |
| 35 | url: '/a/' |
| 36 | route: '/a/b/c' |
| 37 | }, |
| 38 | RoutePair{ |
| 39 | url: '/a/b' |
| 40 | route: '/a/b/c' |
| 41 | }, |
| 42 | RoutePair{ |
| 43 | url: '/a/b/' |
| 44 | route: '/a/b/c' |
| 45 | }, |
| 46 | RoutePair{ |
| 47 | url: '/a/c/b' |
| 48 | route: '/a/b/c' |
| 49 | }, |
| 50 | RoutePair{ |
| 51 | url: '/a/c/b/' |
| 52 | route: '/a/b/c' |
| 53 | }, |
| 54 | RoutePair{ |
| 55 | url: '/a/b/c/d' |
| 56 | route: '/a/b/c' |
| 57 | }, |
| 58 | RoutePair{ |
| 59 | url: '/a/b/c' |
| 60 | route: '/' |
| 61 | }, |
| 62 | ] |
| 63 | for test in tests { |
| 64 | test.test_no_match() |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | fn test_route_exact_match() { |
| 69 | tests := [ |
| 70 | RoutePair{ |
| 71 | url: '/a/b/c' |
| 72 | route: '/a/b/c' |
| 73 | }, |
| 74 | RoutePair{ |
| 75 | url: '/a/b/c/' |
| 76 | route: '/a/b/c' |
| 77 | }, |
| 78 | RoutePair{ |
| 79 | url: '/a' |
| 80 | route: '/a' |
| 81 | }, |
| 82 | RoutePair{ |
| 83 | url: '/' |
| 84 | route: '/' |
| 85 | }, |
| 86 | ] |
| 87 | for test in tests { |
| 88 | test.test_match() |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | fn test_route_params_match() { |
| 93 | RoutePair{ |
| 94 | url: '/a/b/c' |
| 95 | route: '/:a/b/c' |
| 96 | }.test_match() |
| 97 | |
| 98 | RoutePair{ |
| 99 | url: '/a/b/c' |
| 100 | route: '/a/:b/c' |
| 101 | }.test_match() |
| 102 | |
| 103 | RoutePair{ |
| 104 | url: '/a/b/c' |
| 105 | route: '/a/b/:c' |
| 106 | }.test_match() |
| 107 | |
| 108 | RoutePair{ |
| 109 | url: '/a/b/c' |
| 110 | route: '/:a/b/:c' |
| 111 | }.test_match() |
| 112 | |
| 113 | RoutePair{ |
| 114 | url: '/a/b/c' |
| 115 | route: '/:a/:b/:c' |
| 116 | }.test_match() |
| 117 | |
| 118 | RoutePair{ |
| 119 | url: '/one/two/three' |
| 120 | route: '/:a/:b/:c' |
| 121 | }.test_match() |
| 122 | |
| 123 | RoutePair{ |
| 124 | url: '/one/b/c' |
| 125 | route: '/:a/b/c' |
| 126 | }.test_match() |
| 127 | |
| 128 | RoutePair{ |
| 129 | url: '/one/two/three' |
| 130 | route: '/:a/b/c' |
| 131 | }.test_no_match() |
| 132 | |
| 133 | RoutePair{ |
| 134 | url: '/one/two/three' |
| 135 | route: '/:a/:b/c' |
| 136 | }.test_no_match() |
| 137 | |
| 138 | RoutePair{ |
| 139 | url: '/one/two/three' |
| 140 | route: '/:a/b/:c' |
| 141 | }.test_no_match() |
| 142 | |
| 143 | RoutePair{ |
| 144 | url: '/a/b/c/d' |
| 145 | route: '/:a/:b/:c' |
| 146 | }.test_no_match() |
| 147 | |
| 148 | RoutePair{ |
| 149 | url: '/1/2/3/4' |
| 150 | route: '/:a/:b/:c' |
| 151 | }.test_no_match() |
| 152 | |
| 153 | RoutePair{ |
| 154 | url: '/a/b' |
| 155 | route: '/:a/:b/:c' |
| 156 | }.test_no_match() |
| 157 | |
| 158 | RoutePair{ |
| 159 | url: '/1/2' |
| 160 | route: '/:a/:b/:c' |
| 161 | }.test_no_match() |
| 162 | } |
| 163 | |
| 164 | fn test_route_params() { |
| 165 | RoutePair{ |
| 166 | url: '/a/b/c' |
| 167 | route: '/:a/b/c' |
| 168 | }.test_param(['a']) |
| 169 | |
| 170 | RoutePair{ |
| 171 | url: '/one/b/c' |
| 172 | route: '/:a/b/c' |
| 173 | }.test_param(['one']) |
| 174 | |
| 175 | RoutePair{ |
| 176 | url: '/one/two/c' |
| 177 | route: '/:a/:b/c' |
| 178 | }.test_param(['one', 'two']) |
| 179 | |
| 180 | RoutePair{ |
| 181 | url: '/one/two/three' |
| 182 | route: '/:a/:b/:c' |
| 183 | }.test_param(['one', 'two', 'three']) |
| 184 | |
| 185 | RoutePair{ |
| 186 | url: '/one/b/three' |
| 187 | route: '/:a/b/:c' |
| 188 | }.test_param(['one', 'three']) |
| 189 | } |
| 190 | |
| 191 | fn test_route_params_array_match() { |
| 192 | // array can only be used on the last word (TODO: add parsing / tests to ensure this) |
| 193 | |
| 194 | RoutePair{ |
| 195 | url: '/a/b/c' |
| 196 | route: '/a/b/:c...' |
| 197 | }.test_match() |
| 198 | |
| 199 | RoutePair{ |
| 200 | url: '/a/b/c/d' |
| 201 | route: '/a/b/:c...' |
| 202 | }.test_match() |
| 203 | |
| 204 | RoutePair{ |
| 205 | url: '/a/b/c/d/e' |
| 206 | route: '/a/b/:c...' |
| 207 | }.test_match() |
| 208 | |
| 209 | RoutePair{ |
| 210 | url: '/one/b/c/d/e' |
| 211 | route: '/:a/b/:c...' |
| 212 | }.test_match() |
| 213 | |
| 214 | RoutePair{ |
| 215 | url: '/one/two/c/d/e' |
| 216 | route: '/:a/:b/:c...' |
| 217 | }.test_match() |
| 218 | |
| 219 | RoutePair{ |
| 220 | url: '/one/two/three/four/five' |
| 221 | route: '/:a/:b/:c...' |
| 222 | }.test_match() |
| 223 | |
| 224 | RoutePair{ |
| 225 | url: '/a/b' |
| 226 | route: '/:a/:b/:c...' |
| 227 | }.test_no_match() |
| 228 | |
| 229 | RoutePair{ |
| 230 | url: '/a/b/' |
| 231 | route: '/:a/:b/:c...' |
| 232 | }.test_no_match() |
| 233 | } |
| 234 | |
| 235 | fn test_route_params_array() { |
| 236 | RoutePair{ |
| 237 | url: '/a/b/c' |
| 238 | route: '/a/b/:c...' |
| 239 | }.test_param(['c']) |
| 240 | |
| 241 | RoutePair{ |
| 242 | url: '/a/b/c/d' |
| 243 | route: '/a/b/:c...' |
| 244 | }.test_param(['c/d']) |
| 245 | |
| 246 | RoutePair{ |
| 247 | url: '/a/b/c/d/' |
| 248 | route: '/a/b/:c...' |
| 249 | }.test_param(['c/d']) |
| 250 | |
| 251 | RoutePair{ |
| 252 | url: '/a/b/c/d/e' |
| 253 | route: '/a/b/:c...' |
| 254 | }.test_param(['c/d/e']) |
| 255 | |
| 256 | RoutePair{ |
| 257 | url: '/one/b/c/d/e' |
| 258 | route: '/:a/b/:c...' |
| 259 | }.test_param(['one', 'c/d/e']) |
| 260 | |
| 261 | RoutePair{ |
| 262 | url: '/one/two/c/d/e' |
| 263 | route: '/:a/:b/:c...' |
| 264 | }.test_param(['one', 'two', 'c/d/e']) |
| 265 | |
| 266 | RoutePair{ |
| 267 | url: '/one/two/three/d/e' |
| 268 | route: '/:a/:b/:c...' |
| 269 | }.test_param(['one', 'two', 'three/d/e']) |
| 270 | } |
| 271 | |
| 272 | fn test_route_index_path() { |
| 273 | RoutePair{ |
| 274 | url: '/' |
| 275 | route: '/:path...' |
| 276 | }.test_param(['/']) |
| 277 | |
| 278 | RoutePair{ |
| 279 | url: '/foo/bar' |
| 280 | route: '/:path...' |
| 281 | }.test_param(['/foo/bar']) |
| 282 | } |
| 283 | |