mustermann 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +429 -672
  3. data/lib/mustermann.rb +95 -20
  4. data/lib/mustermann/ast/boundaries.rb +44 -0
  5. data/lib/mustermann/ast/compiler.rb +13 -7
  6. data/lib/mustermann/ast/expander.rb +22 -12
  7. data/lib/mustermann/ast/node.rb +69 -5
  8. data/lib/mustermann/ast/param_scanner.rb +20 -0
  9. data/lib/mustermann/ast/parser.rb +138 -19
  10. data/lib/mustermann/ast/pattern.rb +59 -7
  11. data/lib/mustermann/ast/template_generator.rb +28 -0
  12. data/lib/mustermann/ast/transformer.rb +2 -2
  13. data/lib/mustermann/ast/translator.rb +20 -0
  14. data/lib/mustermann/ast/validation.rb +4 -3
  15. data/lib/mustermann/composite.rb +101 -0
  16. data/lib/mustermann/expander.rb +2 -2
  17. data/lib/mustermann/identity.rb +56 -0
  18. data/lib/mustermann/pattern.rb +185 -10
  19. data/lib/mustermann/pattern_cache.rb +49 -0
  20. data/lib/mustermann/regexp.rb +1 -0
  21. data/lib/mustermann/regexp_based.rb +18 -1
  22. data/lib/mustermann/regular.rb +4 -1
  23. data/lib/mustermann/simple_match.rb +5 -0
  24. data/lib/mustermann/sinatra.rb +22 -5
  25. data/lib/mustermann/to_pattern.rb +11 -6
  26. data/lib/mustermann/version.rb +1 -1
  27. data/mustermann.gemspec +1 -14
  28. data/spec/ast_spec.rb +14 -0
  29. data/spec/composite_spec.rb +147 -0
  30. data/spec/expander_spec.rb +15 -0
  31. data/spec/identity_spec.rb +44 -0
  32. data/spec/mustermann_spec.rb +17 -2
  33. data/spec/pattern_spec.rb +7 -3
  34. data/spec/regular_spec.rb +25 -0
  35. data/spec/sinatra_spec.rb +184 -9
  36. data/spec/to_pattern_spec.rb +49 -0
  37. metadata +15 -180
  38. data/.gitignore +0 -18
  39. data/.rspec +0 -2
  40. data/.travis.yml +0 -4
  41. data/.yardopts +0 -1
  42. data/Gemfile +0 -2
  43. data/LICENSE +0 -22
  44. data/Rakefile +0 -6
  45. data/internals.md +0 -64
  46. data/lib/mustermann/ast/tree_renderer.rb +0 -29
  47. data/lib/mustermann/rails.rb +0 -17
  48. data/lib/mustermann/shell.rb +0 -29
  49. data/lib/mustermann/simple.rb +0 -35
  50. data/lib/mustermann/template.rb +0 -47
  51. data/spec/rails_spec.rb +0 -521
  52. data/spec/shell_spec.rb +0 -108
  53. data/spec/simple_spec.rb +0 -236
  54. data/spec/support.rb +0 -5
  55. data/spec/support/coverage.rb +0 -16
  56. data/spec/support/env.rb +0 -16
  57. data/spec/support/expand_matcher.rb +0 -27
  58. data/spec/support/match_matcher.rb +0 -39
  59. data/spec/support/pattern.rb +0 -39
  60. data/spec/template_spec.rb +0 -814
@@ -15,7 +15,7 @@ describe Mustermann do
15
15
  example { Mustermann.new('', type: :template) .should be_a(Mustermann::Template) }
16
16
 
17
17
  example { expect { Mustermann.new('', foo: :bar) }.to raise_error(ArgumentError, "unsupported option :foo for Mustermann::Sinatra") }
18
- example { expect { Mustermann.new('', type: :ast) }.to raise_error(ArgumentError, "unsupported type :ast") }
18
+ example { expect { Mustermann.new('', type: :ast) }.to raise_error(ArgumentError, "unsupported type :ast (cannot load such file -- mustermann/ast)") }
19
19
  end
20
20
 
21
21
  context "pattern argument" do
@@ -35,6 +35,20 @@ describe Mustermann do
35
35
  example { Mustermann.new(pattern, type: :rails) .should be_a(Mustermann::Rails) }
36
36
  example { Mustermann.new(pattern).to_s.should be == 'foo' }
37
37
  end
38
+
39
+ context "multiple arguments" do
40
+ example { Mustermann.new('', '') .should be_a(Mustermann::Composite) }
41
+ example { Mustermann.new('', '').patterns.first .should be_a(Mustermann::Sinatra) }
42
+ example { Mustermann.new('', '').operator .should be == :| }
43
+ example { Mustermann.new('', '', operator: :&).operator .should be == :& }
44
+ example { Mustermann.new('', '', greedy: true) .should be_a(Mustermann::Composite) }
45
+ end
46
+
47
+ context "invalid arguments" do
48
+ it "raise a TypeError for unsupported types" do
49
+ expect { Mustermann.new(10) }.to raise_error(TypeError, "Fixnum can't be coerced into Mustermann::Pattern")
50
+ end
51
+ end
38
52
  end
39
53
 
40
54
  describe :[] do
@@ -45,7 +59,8 @@ describe Mustermann do
45
59
  example { Mustermann[:simple] .should be == Mustermann::Simple }
46
60
  example { Mustermann[:template] .should be == Mustermann::Template }
47
61
 
48
- example { expect { Mustermann[:ast] }.to raise_error(ArgumentError, "unsupported type :ast") }
62
+ example { expect { Mustermann[:ast] }.to raise_error(ArgumentError, "unsupported type :ast (cannot load such file -- mustermann/ast)") }
63
+ example { expect { Mustermann[:expander] }.to raise_error(ArgumentError, "unsupported type :expander") }
49
64
  end
50
65
 
51
66
  describe :extend_object do
@@ -20,10 +20,14 @@ describe Mustermann::Pattern do
20
20
  end
21
21
  end
22
22
 
23
- describe :expand do
23
+ describe :respond_to? do
24
24
  subject(:pattern) { Mustermann::Pattern.new("") }
25
- it { should_not respond_to(:expand) }
26
- it { expect { pattern.expand }.to raise_error(NotImplementedError) }
25
+
26
+ it { should_not respond_to(:expand) }
27
+ it { should_not respond_to(:to_templates) }
28
+
29
+ it { expect { pattern.expand } .to raise_error(NotImplementedError) }
30
+ it { expect { pattern.to_templates } .to raise_error(NotImplementedError) }
27
31
  end
28
32
 
29
33
  describe :== do
@@ -7,6 +7,9 @@ describe Mustermann::Regular do
7
7
  pattern '' do
8
8
  it { should match('') }
9
9
  it { should_not match('/') }
10
+
11
+ it { should_not respond_to(:expand) }
12
+ it { should_not respond_to(:to_templates) }
10
13
  end
11
14
 
12
15
  pattern '/' do
@@ -33,4 +36,26 @@ describe Mustermann::Regular do
33
36
  it { should match('/%0Afoo') .capturing foo: '%0Afoo' }
34
37
  it { should match('/foo%2Fbar') .capturing foo: 'foo%2Fbar' }
35
38
  end
39
+
40
+ context "peeking" do
41
+ subject(:pattern) { Mustermann::Regular.new("(?<name>[^/]+)") }
42
+
43
+ describe :peek_size do
44
+ example { pattern.peek_size("foo bar/blah") .should be == "foo bar".size }
45
+ example { pattern.peek_size("foo%20bar/blah") .should be == "foo%20bar".size }
46
+ example { pattern.peek_size("/foo bar") .should be_nil }
47
+ end
48
+
49
+ describe :peek_match do
50
+ example { pattern.peek_match("foo bar/blah") .to_s .should be == "foo bar" }
51
+ example { pattern.peek_match("foo%20bar/blah") .to_s .should be == "foo%20bar" }
52
+ example { pattern.peek_match("/foo bar") .should be_nil }
53
+ end
54
+
55
+ describe :peek_params do
56
+ example { pattern.peek_params("foo bar/blah") .should be == [{"name" => "foo bar"}, "foo bar".size] }
57
+ example { pattern.peek_params("foo%20bar/blah") .should be == [{"name" => "foo bar"}, "foo%20bar".size] }
58
+ example { pattern.peek_params("/foo bar") .should be_nil }
59
+ end
60
+ end
36
61
  end
@@ -7,6 +7,11 @@ describe Mustermann::Sinatra do
7
7
  pattern '' do
8
8
  it { should match('') }
9
9
  it { should_not match('/') }
10
+
11
+ it { should generate_template('') }
12
+
13
+ it { should respond_to(:expand) }
14
+ it { should respond_to(:to_templates) }
10
15
  end
11
16
 
12
17
  pattern '/' do
@@ -43,6 +48,8 @@ describe Mustermann::Sinatra do
43
48
  it { should_not match('/foo/bar') }
44
49
  it { should_not match('/') }
45
50
  it { should_not match('/foo/') }
51
+
52
+ it { should generate_template('/{foo}') }
46
53
  end
47
54
 
48
55
  pattern '/föö' do
@@ -61,10 +68,34 @@ describe Mustermann::Sinatra do
61
68
 
62
69
  example { pattern.params('/bar/foo').should be == {"foo" => "bar", "bar" => "foo"} }
63
70
  example { pattern.params('').should be_nil }
71
+
72
+ it { should generate_template('/{foo}/{bar}') }
73
+ end
74
+
75
+ pattern "/{foo}/{bar}" do
76
+ it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' }
77
+ it { should match('/foo.bar/bar.foo') .capturing foo: 'foo.bar', bar: 'bar.foo' }
78
+ it { should match('/user@example.com/name') .capturing foo: 'user@example.com', bar: 'name' }
79
+ it { should match('/10.1/te.st') .capturing foo: '10.1', bar: 'te.st' }
80
+ it { should match('/10.1.2/te.st') .capturing foo: '10.1.2', bar: 'te.st' }
81
+
82
+ it { should_not match('/foo%2Fbar') }
83
+ it { should_not match('/foo%2fbar') }
84
+
85
+ example { pattern.params('/bar/foo').should be == {"foo" => "bar", "bar" => "foo"} }
86
+ example { pattern.params('').should be_nil }
87
+
88
+ it { should generate_template('/{foo}/{bar}') }
64
89
  end
65
90
 
66
91
  pattern '/hello/:person' do
67
92
  it { should match('/hello/Frank').capturing person: 'Frank' }
93
+ it { should generate_template('/hello/{person}') }
94
+ end
95
+
96
+ pattern '/hello/{person}' do
97
+ it { should match('/hello/Frank').capturing person: 'Frank' }
98
+ it { should generate_template('/hello/{person}') }
68
99
  end
69
100
 
70
101
  pattern '/?:foo?/?:bar?' do
@@ -73,23 +104,40 @@ describe Mustermann::Sinatra do
73
104
  it { should match('/') .capturing foo: nil, bar: nil }
74
105
  it { should match('') .capturing foo: nil, bar: nil }
75
106
 
76
- it { should_not match('/hello/world/') }
107
+ it { should expand(foo: 'hello') .to('/hello/') }
108
+ it { should expand(foo: 'hello', bar: 'world') .to('/hello/world') }
109
+ it { should expand(bar: 'world') .to('//world') }
110
+ it { should expand .to('//') }
111
+ it { should_not expand(baz: '') }
77
112
 
78
- # it { should expand(foo: 'hello') .to('/hello') }
79
- # it { should expand(foo: 'hello', bar: 'world') .to('/hello/world') }
80
- # it { should expand(bar: 'world') .to('//world') }
81
- # it { should expand .to('') }
82
- # it { should_not expand(baz: '') }
113
+ it { should_not match('/hello/world/') }
114
+ it { should generate_templates("", "/", "//", "//{bar}", "/{bar}", "/{foo}", "/{foo}/", "/{foo}/{bar}", "/{foo}{bar}", "{bar}", "{foo}", "{foo}/", "{foo}/{bar}", "{foo}{bar}") }
83
115
  end
84
116
 
85
117
  pattern '/:foo_bar' do
86
118
  it { should match('/hello').capturing foo_bar: 'hello' }
119
+ it { should generate_template('/{foo_bar}') }
120
+ end
121
+
122
+ pattern '/{foo.bar}' do
123
+ it { should match('/hello').capturing :"foo.bar" => 'hello' }
124
+ it { should generate_template('/{foo.bar}') }
87
125
  end
88
126
 
89
127
  pattern '/*' do
90
128
  it { should match('/') .capturing splat: '' }
91
129
  it { should match('/foo') .capturing splat: 'foo' }
92
130
  it { should match('/foo/bar') .capturing splat: 'foo/bar' }
131
+ it { should generate_template('/{+splat}') }
132
+
133
+ example { pattern.params('/foo').should be == {"splat" => ["foo"]} }
134
+ end
135
+
136
+ pattern '/{+splat}' do
137
+ it { should match('/') .capturing splat: '' }
138
+ it { should match('/foo') .capturing splat: 'foo' }
139
+ it { should match('/foo/bar') .capturing splat: 'foo/bar' }
140
+ it { should generate_template('/{+splat}') }
93
141
 
94
142
  example { pattern.params('/foo').should be == {"splat" => ["foo"]} }
95
143
  end
@@ -98,6 +146,17 @@ describe Mustermann::Sinatra do
98
146
  it { should match('/') .capturing foo: '' }
99
147
  it { should match('/foo') .capturing foo: 'foo' }
100
148
  it { should match('/foo/bar') .capturing foo: 'foo/bar' }
149
+ it { should generate_template('/{+foo}') }
150
+
151
+ example { pattern.params('/foo') .should be == {"foo" => "foo" } }
152
+ example { pattern.params('/foo/bar') .should be == {"foo" => "foo/bar" } }
153
+ end
154
+
155
+ pattern '/{+foo}' do
156
+ it { should match('/') .capturing foo: '' }
157
+ it { should match('/foo') .capturing foo: 'foo' }
158
+ it { should match('/foo/bar') .capturing foo: 'foo/bar' }
159
+ it { should generate_template('/{+foo}') }
101
160
 
102
161
  example { pattern.params('/foo') .should be == {"foo" => "foo" } }
103
162
  example { pattern.params('/foo/bar') .should be == {"foo" => "foo/bar" } }
@@ -105,6 +164,12 @@ describe Mustermann::Sinatra do
105
164
 
106
165
  pattern '/*foo/*bar' do
107
166
  it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' }
167
+ it { should generate_template('/{+foo}/{+bar}') }
168
+ end
169
+
170
+ pattern '/{+foo}/{+bar}' do
171
+ it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' }
172
+ it { should generate_template('/{+foo}/{+bar}') }
108
173
  end
109
174
 
110
175
  pattern '/:foo/*' do
@@ -112,6 +177,18 @@ describe Mustermann::Sinatra do
112
177
  it { should match("/foo/") .capturing foo: 'foo', splat: '' }
113
178
  it { should match('/h%20w/h%20a%20y') .capturing foo: 'h%20w', splat: 'h%20a%20y' }
114
179
  it { should_not match('/foo') }
180
+ it { should generate_template('/{foo}/{+splat}') }
181
+
182
+ example { pattern.params('/bar/foo').should be == {"splat" => ["foo"], "foo" => "bar"} }
183
+ example { pattern.params('/bar/foo/f%20o').should be == {"splat" => ["foo/f o"], "foo" => "bar"} }
184
+ end
185
+
186
+ pattern '/{foo}/*' do
187
+ it { should match("/foo/bar/baz") .capturing foo: 'foo', splat: 'bar/baz' }
188
+ it { should match("/foo/") .capturing foo: 'foo', splat: '' }
189
+ it { should match('/h%20w/h%20a%20y') .capturing foo: 'h%20w', splat: 'h%20a%20y' }
190
+ it { should_not match('/foo') }
191
+ it { should generate_template('/{foo}/{+splat}') }
115
192
 
116
193
  example { pattern.params('/bar/foo').should be == {"splat" => ["foo"], "foo" => "bar"} }
117
194
  example { pattern.params('/bar/foo/f%20o').should be == {"splat" => ["foo/f o"], "foo" => "bar"} }
@@ -131,12 +208,18 @@ describe Mustermann::Sinatra do
131
208
  it { should match('/path%20with%20spaces') }
132
209
  it { should match('/path%2Bwith%2Bspaces') }
133
210
  it { should match('/path+with+spaces') }
211
+
212
+ it { should generate_template('/path%20with%20spaces') }
134
213
  end
135
214
 
136
215
  pattern '/foo&bar' do
137
216
  it { should match('/foo&bar') }
138
217
  end
139
218
 
219
+ pattern '/foo\{bar' do
220
+ it { should match('/foo%7Bbar') }
221
+ end
222
+
140
223
  pattern '/*/:foo/*/*' do
141
224
  it { should match('/bar/foo/bling/baz/boom') }
142
225
 
@@ -153,13 +236,29 @@ describe Mustermann::Sinatra do
153
236
  end
154
237
  end
155
238
 
239
+ pattern '/{+splat}/{foo}/{+splat}/{+splat}' do
240
+ it { should match('/bar/foo/bling/baz/boom') }
241
+
242
+ it "should capture all splat parts" do
243
+ match = pattern.match('/bar/foo/bling/baz/boom')
244
+ match.captures.should be == ['bar', 'foo', 'bling', 'baz/boom']
245
+ match.names.should be == ['splat', 'foo']
246
+ end
247
+
248
+ it 'should map to proper params' do
249
+ pattern.params('/bar/foo/bling/baz/boom').should be == {
250
+ "foo" => "foo", "splat" => ['bar', 'bling', 'baz/boom']
251
+ }
252
+ end
253
+ end
254
+
156
255
  pattern '/test.bar' do
157
256
  it { should match('/test.bar') }
158
257
  it { should_not match('/test0bar') }
159
258
  end
160
259
 
161
260
  pattern '/:file.:ext' do
162
- it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
261
+ it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
163
262
  it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' }
164
263
  it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' }
165
264
 
@@ -179,12 +278,18 @@ describe Mustermann::Sinatra do
179
278
  it { should match('/ax') .capturing a: 'a' }
180
279
  it { should match('/axax') .capturing a: 'axa' }
181
280
  it { should match('/axaxx') .capturing a: 'axax' }
281
+
282
+ it { should generate_template('/{a}x') }
283
+ it { should generate_template('/{a}') }
182
284
  end
183
285
 
184
286
  pattern '/:user(@:host)?' do
185
287
  it { should match('/foo@bar') .capturing user: 'foo', host: 'bar' }
186
288
  it { should match('/foo.foo@bar') .capturing user: 'foo.foo', host: 'bar' }
187
289
  it { should match('/foo@bar.bar') .capturing user: 'foo', host: 'bar.bar' }
290
+
291
+ it { should generate_template('/{user}') }
292
+ it { should generate_template('/{user}@{host}') }
188
293
  end
189
294
 
190
295
  pattern '/:file(.:ext)?' do
@@ -195,6 +300,10 @@ describe Mustermann::Sinatra do
195
300
  it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: 'jpg' }
196
301
  it { should match('/pony.') .capturing file: 'pony.' }
197
302
  it { should_not match('/.jpg') }
303
+
304
+ it { should generate_template('/{file}') }
305
+ it { should generate_template('/{file}.{ext}') }
306
+ it { should_not generate_template('/{file}.') }
198
307
  end
199
308
 
200
309
  pattern '/:id/test.bar' do
@@ -323,6 +432,37 @@ describe Mustermann::Sinatra do
323
432
  it { should match('/foo/bar/baz').capturing foo: 'foo', bar: 'bar', baz: 'baz' }
324
433
  end
325
434
 
435
+ pattern "/(foo|bar)" do
436
+ it { should match("/foo") }
437
+ it { should match("/bar") }
438
+
439
+ it { should generate_template('/foo') }
440
+ it { should generate_template('/bar') }
441
+ end
442
+
443
+ pattern "/(foo\\|bar)" do
444
+ it { should match "/foo%7Cbar" }
445
+ it { should generate_template "/foo%7Cbar" }
446
+
447
+ it { should_not match("/foo") }
448
+ it { should_not match("/bar") }
449
+
450
+ it { should_not generate_template('/foo') }
451
+ it { should_not generate_template('/bar') }
452
+ end
453
+
454
+ pattern "/(:a/:b|:c)" do
455
+ it { should match("/foo") .capturing c: 'foo' }
456
+ it { should match("/foo/bar") .capturing a: 'foo', b: 'bar' }
457
+
458
+ it { should generate_template('/{a}/{b}') }
459
+ it { should generate_template('/{c}') }
460
+
461
+ it { should expand(a: 'foo', b: 'bar') .to('/foo/bar') }
462
+ it { should expand(c: 'foo') .to('/foo') }
463
+ it { should_not expand(a: 'foo', b: 'bar', c: 'baz') }
464
+ end
465
+
326
466
  pattern '/:foo', capture: /\d+/ do
327
467
  it { should match('/1') .capturing foo: '1' }
328
468
  it { should match('/123') .capturing foo: '123' }
@@ -508,6 +648,11 @@ describe Mustermann::Sinatra do
508
648
  to raise_error(Mustermann::ParseError, 'unexpected ? while parsing "foo??bar"')
509
649
  end
510
650
 
651
+ example '| outside of group' do
652
+ expect { Mustermann::Sinatra.new('foo|bar') }.
653
+ to raise_error(Mustermann::ParseError, 'unexpected | while parsing "foo|bar"')
654
+ end
655
+
511
656
  example 'dangling escape' do
512
657
  expect { Mustermann::Sinatra.new('foo\\') }.
513
658
  to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo\\\\"')
@@ -563,11 +708,41 @@ describe Mustermann::Sinatra do
563
708
  end
564
709
 
565
710
  describe :to_regexp do
566
- example('empty pattern') { Mustermann::Sinatra.new('').to_regexp.should be == /\A\Z/ }
711
+ example('empty pattern') { Mustermann::Sinatra.new('').to_regexp.should be == /\A(?-mix:)\Z/ }
567
712
 
568
713
  context 'Regexp.try_convert' do
569
- example('empty pattern') { Regexp.try_convert(Mustermann::Sinatra.new('')).should be == /\A\Z/ }
714
+ example('empty pattern') { Regexp.try_convert(Mustermann::Sinatra.new('')).should be == /\A(?-mix:)\Z/ }
570
715
  end
571
716
  end
572
717
  end
718
+
719
+ context 'Proc compatibility' do
720
+ describe :to_proc do
721
+ example { Mustermann::Sinatra.new("/").to_proc.should be_a(Proc) }
722
+ example('non-matching') { Mustermann::Sinatra.new("/") .to_proc.call('/foo').should be == false }
723
+ example('matching') { Mustermann::Sinatra.new("/:foo") .to_proc.call('/foo').should be == true }
724
+ end
725
+ end
726
+
727
+ context "peeking" do
728
+ subject(:pattern) { Mustermann::Sinatra.new(":name") }
729
+
730
+ describe :peek_size do
731
+ example { pattern.peek_size("foo bar/blah") .should be == "foo bar".size }
732
+ example { pattern.peek_size("foo%20bar/blah") .should be == "foo%20bar".size }
733
+ example { pattern.peek_size("/foo bar") .should be_nil }
734
+ end
735
+
736
+ describe :peek_match do
737
+ example { pattern.peek_match("foo bar/blah") .to_s .should be == "foo bar" }
738
+ example { pattern.peek_match("foo%20bar/blah") .to_s .should be == "foo%20bar" }
739
+ example { pattern.peek_match("/foo bar") .should be_nil }
740
+ end
741
+
742
+ describe :peek_params do
743
+ example { pattern.peek_params("foo bar/blah") .should be == [{"name" => "foo bar"}, "foo bar".size] }
744
+ example { pattern.peek_params("foo%20bar/blah") .should be == [{"name" => "foo bar"}, "foo%20bar".size] }
745
+ example { pattern.peek_params("/foo bar") .should be_nil }
746
+ end
747
+ end
573
748
  end
@@ -1,5 +1,6 @@
1
1
  require 'support'
2
2
  require 'mustermann/to_pattern'
3
+ require 'delegate'
3
4
 
4
5
  describe Mustermann::ToPattern do
5
6
  context String do
@@ -12,9 +13,57 @@ describe Mustermann::ToPattern do
12
13
  example { //.to_pattern(type: :rails) .should be_a(Mustermann::Regular) }
13
14
  end
14
15
 
16
+ context Symbol do
17
+ example { :foo.to_pattern .should be_a(Mustermann::Sinatra) }
18
+ example { :foo.to_pattern(type: :rails) .should be_a(Mustermann::Sinatra) }
19
+ end
20
+
21
+ context Array do
22
+ example { [:foo, :bar].to_pattern .should be_a(Mustermann::Composite) }
23
+ example { [:foo, :bar].to_pattern(type: :rails) .should be_a(Mustermann::Composite) }
24
+ end
25
+
15
26
  context Mustermann::Pattern do
16
27
  subject(:pattern) { Mustermann.new('') }
17
28
  example { pattern.to_pattern.should be == pattern }
18
29
  example { pattern.to_pattern(type: :rails).should be_a(Mustermann::Sinatra) }
19
30
  end
31
+
32
+ context 'custom class' do
33
+ let(:example_class) do
34
+ Class.new do
35
+ include Mustermann::ToPattern
36
+ def to_s
37
+ ":foo/:bar"
38
+ end
39
+ end
40
+ end
41
+
42
+ example { example_class.new.to_pattern .should be_a(Mustermann::Sinatra) }
43
+ example { example_class.new.to_pattern(type: :rails) .should be_a(Mustermann::Rails) }
44
+ example { Mustermann.new(example_class.new) .should be_a(Mustermann::Sinatra) }
45
+ example { Mustermann.new(example_class.new, type: :rails) .should be_a(Mustermann::Rails) }
46
+ end
47
+
48
+ context 'primitive delegate' do
49
+ let(:example_class) do
50
+ Class.new(DelegateClass(Array)) do
51
+ include Mustermann::ToPattern
52
+ end
53
+ end
54
+
55
+ example { example_class.new([:foo, :bar]).to_pattern .should be_a(Mustermann::Composite) }
56
+ example { example_class.new([:foo, :bar]).to_pattern(type: :rails) .should be_a(Mustermann::Composite) }
57
+ end
58
+
59
+ context 'primitive subclass' do
60
+ let(:example_class) do
61
+ Class.new(Array) do
62
+ include Mustermann::ToPattern
63
+ end
64
+ end
65
+
66
+ example { example_class.new([:foo, :bar]).to_pattern .should be_a(Mustermann::Composite) }
67
+ example { example_class.new([:foo, :bar]).to_pattern(type: :rails) .should be_a(Mustermann::Composite) }
68
+ end
20
69
  end