mustermann 1.0.2.rc1 → 1.0.2.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +799 -230
  3. data/{mustermann/bench → bench}/capturing.rb +0 -0
  4. data/{mustermann/bench → bench}/regexp.rb +0 -0
  5. data/{mustermann/bench → bench}/simple_vs_sinatra.rb +0 -0
  6. data/{mustermann/bench → bench}/template_vs_addressable.rb +0 -0
  7. data/{mustermann/lib → lib}/mustermann.rb +0 -0
  8. data/{mustermann/lib → lib}/mustermann/ast/boundaries.rb +0 -0
  9. data/{mustermann/lib → lib}/mustermann/ast/compiler.rb +0 -0
  10. data/{mustermann/lib → lib}/mustermann/ast/expander.rb +0 -0
  11. data/{mustermann/lib → lib}/mustermann/ast/node.rb +0 -0
  12. data/{mustermann/lib → lib}/mustermann/ast/param_scanner.rb +0 -0
  13. data/{mustermann/lib → lib}/mustermann/ast/parser.rb +0 -0
  14. data/{mustermann/lib → lib}/mustermann/ast/pattern.rb +0 -0
  15. data/{mustermann/lib → lib}/mustermann/ast/template_generator.rb +0 -0
  16. data/{mustermann/lib → lib}/mustermann/ast/transformer.rb +0 -0
  17. data/{mustermann/lib → lib}/mustermann/ast/translator.rb +0 -0
  18. data/{mustermann/lib → lib}/mustermann/ast/validation.rb +0 -0
  19. data/{mustermann/lib → lib}/mustermann/caster.rb +0 -0
  20. data/{mustermann/lib → lib}/mustermann/composite.rb +0 -0
  21. data/{mustermann/lib → lib}/mustermann/concat.rb +0 -0
  22. data/{mustermann/lib → lib}/mustermann/equality_map.rb +0 -0
  23. data/{mustermann/lib → lib}/mustermann/error.rb +0 -0
  24. data/{mustermann/lib → lib}/mustermann/expander.rb +0 -0
  25. data/{mustermann/lib → lib}/mustermann/extension.rb +0 -0
  26. data/{mustermann/lib → lib}/mustermann/identity.rb +0 -0
  27. data/{mustermann/lib → lib}/mustermann/mapper.rb +0 -0
  28. data/{mustermann/lib → lib}/mustermann/pattern.rb +0 -0
  29. data/{mustermann/lib → lib}/mustermann/pattern_cache.rb +0 -0
  30. data/{mustermann/lib → lib}/mustermann/regexp.rb +0 -0
  31. data/{mustermann/lib → lib}/mustermann/regexp_based.rb +0 -0
  32. data/{mustermann/lib → lib}/mustermann/regular.rb +0 -0
  33. data/{mustermann/lib → lib}/mustermann/simple_match.rb +0 -0
  34. data/{mustermann/lib → lib}/mustermann/sinatra.rb +0 -0
  35. data/{mustermann/lib → lib}/mustermann/sinatra/parser.rb +0 -0
  36. data/{mustermann/lib → lib}/mustermann/sinatra/safe_renderer.rb +0 -0
  37. data/{mustermann/lib → lib}/mustermann/sinatra/try_convert.rb +0 -0
  38. data/{mustermann/lib → lib}/mustermann/to_pattern.rb +0 -0
  39. data/{mustermann/lib → lib}/mustermann/version.rb +1 -1
  40. data/{mustermann/mustermann.gemspec → mustermann.gemspec} +0 -0
  41. data/{mustermann/spec → spec}/ast_spec.rb +0 -0
  42. data/{mustermann/spec → spec}/composite_spec.rb +0 -0
  43. data/{mustermann/spec → spec}/concat_spec.rb +0 -0
  44. data/{mustermann/spec → spec}/equality_map_spec.rb +0 -0
  45. data/{mustermann/spec → spec}/expander_spec.rb +0 -0
  46. data/{mustermann/spec → spec}/extension_spec.rb +0 -0
  47. data/{mustermann/spec → spec}/identity_spec.rb +0 -0
  48. data/{mustermann/spec → spec}/mapper_spec.rb +0 -0
  49. data/{mustermann/spec → spec}/mustermann_spec.rb +0 -0
  50. data/{mustermann/spec → spec}/pattern_spec.rb +0 -0
  51. data/{mustermann/spec → spec}/regexp_based_spec.rb +0 -0
  52. data/{mustermann/spec → spec}/regular_spec.rb +0 -0
  53. data/{mustermann/spec → spec}/simple_match_spec.rb +0 -0
  54. data/{mustermann/spec → spec}/sinatra_spec.rb +0 -0
  55. data/{mustermann/spec → spec}/to_pattern_spec.rb +0 -0
  56. metadata +71 -126
  57. data/.gitignore +0 -18
  58. data/.rspec +0 -5
  59. data/.travis.yml +0 -25
  60. data/.yardopts +0 -3
  61. data/Gemfile +0 -7
  62. data/Rakefile +0 -27
  63. data/mustermann-contrib/LICENSE +0 -23
  64. data/mustermann-contrib/README.md +0 -1155
  65. data/mustermann-contrib/examples/highlighting.rb +0 -35
  66. data/mustermann-contrib/highlighting.png +0 -0
  67. data/mustermann-contrib/irb.png +0 -0
  68. data/mustermann-contrib/lib/mustermann/cake.rb +0 -19
  69. data/mustermann-contrib/lib/mustermann/express.rb +0 -38
  70. data/mustermann-contrib/lib/mustermann/file_utils.rb +0 -218
  71. data/mustermann-contrib/lib/mustermann/file_utils/glob_pattern.rb +0 -40
  72. data/mustermann-contrib/lib/mustermann/fileutils.rb +0 -1
  73. data/mustermann-contrib/lib/mustermann/flask.rb +0 -199
  74. data/mustermann-contrib/lib/mustermann/pyramid.rb +0 -29
  75. data/mustermann-contrib/lib/mustermann/rails.rb +0 -47
  76. data/mustermann-contrib/lib/mustermann/shell.rb +0 -57
  77. data/mustermann-contrib/lib/mustermann/simple.rb +0 -51
  78. data/mustermann-contrib/lib/mustermann/string_scanner.rb +0 -314
  79. data/mustermann-contrib/lib/mustermann/strscan.rb +0 -1
  80. data/mustermann-contrib/lib/mustermann/template.rb +0 -63
  81. data/mustermann-contrib/lib/mustermann/uri_template.rb +0 -1
  82. data/mustermann-contrib/lib/mustermann/versions.rb +0 -47
  83. data/mustermann-contrib/lib/mustermann/visualizer.rb +0 -39
  84. data/mustermann-contrib/lib/mustermann/visualizer/highlight.rb +0 -138
  85. data/mustermann-contrib/lib/mustermann/visualizer/highlighter.rb +0 -38
  86. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/ad_hoc.rb +0 -95
  87. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/ast.rb +0 -103
  88. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/composite.rb +0 -46
  89. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/dummy.rb +0 -19
  90. data/mustermann-contrib/lib/mustermann/visualizer/highlighter/regular.rb +0 -105
  91. data/mustermann-contrib/lib/mustermann/visualizer/pattern_extension.rb +0 -69
  92. data/mustermann-contrib/lib/mustermann/visualizer/renderer/ansi.rb +0 -24
  93. data/mustermann-contrib/lib/mustermann/visualizer/renderer/generic.rb +0 -47
  94. data/mustermann-contrib/lib/mustermann/visualizer/renderer/hansi_template.rb +0 -35
  95. data/mustermann-contrib/lib/mustermann/visualizer/renderer/html.rb +0 -51
  96. data/mustermann-contrib/lib/mustermann/visualizer/renderer/sexp.rb +0 -38
  97. data/mustermann-contrib/lib/mustermann/visualizer/tree.rb +0 -64
  98. data/mustermann-contrib/lib/mustermann/visualizer/tree_renderer.rb +0 -79
  99. data/mustermann-contrib/mustermann-contrib.gemspec +0 -19
  100. data/mustermann-contrib/spec/cake_spec.rb +0 -91
  101. data/mustermann-contrib/spec/express_spec.rb +0 -210
  102. data/mustermann-contrib/spec/file_utils_spec.rb +0 -120
  103. data/mustermann-contrib/spec/flask_spec.rb +0 -362
  104. data/mustermann-contrib/spec/flask_subclass_spec.rb +0 -369
  105. data/mustermann-contrib/spec/pattern_extension_spec.rb +0 -50
  106. data/mustermann-contrib/spec/pyramid_spec.rb +0 -102
  107. data/mustermann-contrib/spec/rails_spec.rb +0 -648
  108. data/mustermann-contrib/spec/shell_spec.rb +0 -148
  109. data/mustermann-contrib/spec/simple_spec.rb +0 -269
  110. data/mustermann-contrib/spec/string_scanner_spec.rb +0 -272
  111. data/mustermann-contrib/spec/template_spec.rb +0 -842
  112. data/mustermann-contrib/spec/visualizer_spec.rb +0 -199
  113. data/mustermann-contrib/theme.png +0 -0
  114. data/mustermann-contrib/tree.png +0 -0
  115. data/mustermann/LICENSE +0 -23
  116. data/mustermann/README.md +0 -853
  117. data/support/lib/support.rb +0 -7
  118. data/support/lib/support/coverage.rb +0 -23
  119. data/support/lib/support/env.rb +0 -19
  120. data/support/lib/support/expand_matcher.rb +0 -28
  121. data/support/lib/support/generate_template_matcher.rb +0 -27
  122. data/support/lib/support/match_matcher.rb +0 -39
  123. data/support/lib/support/pattern.rb +0 -42
  124. data/support/lib/support/projects.rb +0 -20
  125. data/support/lib/support/scan_matcher.rb +0 -63
  126. data/support/support.gemspec +0 -27
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'support'
3
- require 'mustermann/visualizer'
4
- require 'pp'
5
- require 'stringio'
6
-
7
- describe Mustermann::Visualizer::PatternExtension do
8
- subject(:pattern) { Mustermann.new("/:name") }
9
- before { Hansi.mode = 16 }
10
- after { Hansi.mode = nil }
11
-
12
- specify :to_ansi do
13
- pattern.to_ansi(inspect: true, capture: :red, default: nil).should be == "\e[0m\"\e[0m/\e[0m\e[91m:\e[0m\e[91mname\e[0m\"\e[0m"
14
- pattern.to_ansi(inspect: false, capture: :green, default: nil).should be == "\e[0m/\e[0m\e[32m:\e[0m\e[32mname\e[0m"
15
- pattern.to_ansi(inspect: nil, capture: :green, default: nil).should be == "\e[0m/\e[0m\e[32m:\e[0m\e[32mname\e[0m"
16
- end
17
-
18
- specify :to_html do
19
- pattern.to_html(css: false, class_prefix: "", tag: :tt).should be == '<tt class="pattern"><tt class="root"><tt class="separator">/</tt><tt class="capture">:<tt class="name">name</tt></tt></tt></tt>'
20
- end
21
-
22
- specify :to_tree do
23
- pattern.to_tree.should be == Mustermann::Visualizer.tree(pattern).to_s
24
- end
25
-
26
- specify :color_inspect do
27
- pattern.color_inspect.should include(pattern.to_ansi(inspect: true))
28
- pattern.color_inspect.should include("#<Mustermann::Sinatra:")
29
- end
30
-
31
- specify :to_s do
32
- object = Class.new { def puts(arg) arg.to_s end }.new
33
- object.puts(pattern).should be == pattern.to_ansi
34
- end
35
-
36
- context :pretty_print do
37
- before(:all) { ColorPrinter = Class.new(::PP) }
38
- let(:output) { StringIO.new }
39
-
40
- specify 'with color printer' do
41
- ColorPrinter.new(output, 79).pp(pattern)
42
- output.string.should be == pattern.color_inspect
43
- end
44
-
45
- specify 'without color printer' do
46
- ::PP.new(output, 79).pp(pattern)
47
- output.string.should be == pattern.inspect
48
- end
49
- end
50
- end
@@ -1,102 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'support'
3
- require 'mustermann/pyramid'
4
-
5
- describe Mustermann::Pyramid do
6
- extend Support::Pattern
7
-
8
- pattern '' do
9
- it { should match('') }
10
- it { should_not match('/') }
11
-
12
- it { should expand.to('') }
13
- it { should_not expand(a: 1) }
14
-
15
- it { should generate_template('') }
16
-
17
- it { should respond_to(:expand) }
18
- it { should respond_to(:to_templates) }
19
- end
20
-
21
- pattern '/' do
22
- it { should match('/') }
23
- it { should_not match('/foo') }
24
-
25
- it { should expand.to('/') }
26
- it { should_not expand(a: 1) }
27
- end
28
-
29
- pattern '/foo' do
30
- it { should match('/foo') }
31
- it { should_not match('/bar') }
32
- it { should_not match('/foo.bar') }
33
-
34
- it { should expand.to('/foo') }
35
- it { should_not expand(a: 1) }
36
- end
37
-
38
- pattern '/foo/bar' do
39
- it { should match('/foo/bar') }
40
- it { should_not match('/foo%2Fbar') }
41
- it { should_not match('/foo%2fbar') }
42
-
43
- it { should expand.to('/foo/bar') }
44
- it { should_not expand(a: 1) }
45
- end
46
-
47
- pattern '/{foo}' do
48
- it { should match('/foo') .capturing foo: 'foo' }
49
- it { should match('/bar') .capturing foo: 'bar' }
50
- it { should match('/foo.bar') .capturing foo: 'foo.bar' }
51
- it { should match('/%0Afoo') .capturing foo: '%0Afoo' }
52
- it { should match('/foo%2Fbar') .capturing foo: 'foo%2Fbar' }
53
-
54
- it { should_not match('/foo?') }
55
- it { should_not match('/foo/bar') }
56
- it { should_not match('/') }
57
- it { should_not match('/foo/') }
58
-
59
- example { pattern.params('/foo') .should be == {"foo" => "foo"} }
60
- example { pattern.params('/f%20o') .should be == {"foo" => "f o"} }
61
- example { pattern.params('').should be_nil }
62
-
63
- it { should expand(foo: 'bar') .to('/bar') }
64
- it { should expand(foo: 'b r') .to('/b%20r') }
65
- it { should expand(foo: 'foo/bar') .to('/foo%2Fbar') }
66
-
67
- it { should_not expand(foo: 'foo', bar: 'bar') }
68
- it { should_not expand(bar: 'bar') }
69
- it { should_not expand }
70
-
71
- it { should generate_template('/{foo}') }
72
- end
73
-
74
- pattern '/*foo' do
75
- it { should match('/foo') .capturing foo: 'foo' }
76
- it { should match('/foo/bar') .capturing foo: 'foo/bar' }
77
-
78
- it { should expand .to('/') }
79
- it { should expand(foo: nil) .to('/') }
80
- it { should expand(foo: '') .to('/') }
81
- it { should expand(foo: 'foo') .to('/foo') }
82
- it { should expand(foo: 'foo/bar') .to('/foo/bar') }
83
- it { should expand(foo: 'foo.bar') .to('/foo.bar') }
84
-
85
- example { pattern.params("/foo/bar").should be == {"foo" => ["foo", "bar"]}}
86
- it { should generate_template('/{+foo}') }
87
- end
88
-
89
- pattern '/{foo:.*}' do
90
- it { should match('/') .capturing foo: '' }
91
- it { should match('/foo') .capturing foo: 'foo' }
92
- it { should match('/foo/bar') .capturing foo: 'foo/bar' }
93
-
94
- it { should expand(foo: '') .to('/') }
95
- it { should expand(foo: 'foo') .to('/foo') }
96
- it { should expand(foo: 'foo/bar') .to('/foo/bar') }
97
- it { should expand(foo: 'foo.bar') .to('/foo.bar') }
98
-
99
- example { pattern.params("/foo/bar").should be == {"foo" => "foo/bar"}}
100
- it { should generate_template('/{foo}') }
101
- end
102
- end
@@ -1,648 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'support'
3
- require 'mustermann/rails'
4
-
5
- describe Mustermann::Rails do
6
- extend Support::Pattern
7
-
8
- pattern '' do
9
- it { should match('') }
10
- it { should_not match('/') }
11
-
12
- it { should expand.to('') }
13
- it { should_not expand(a: 1) }
14
-
15
- it { should generate_template('') }
16
-
17
- it { should respond_to(:expand) }
18
- it { should respond_to(:to_templates) }
19
- end
20
-
21
- pattern '/' do
22
- it { should match('/') }
23
- it { should_not match('/foo') }
24
-
25
- it { should expand.to('/') }
26
- it { should_not expand(a: 1) }
27
- end
28
-
29
- pattern '/foo' do
30
- it { should match('/foo') }
31
- it { should_not match('/bar') }
32
- it { should_not match('/foo.bar') }
33
-
34
- it { should expand.to('/foo') }
35
- it { should_not expand(a: 1) }
36
- end
37
-
38
- pattern '/foo/bar' do
39
- it { should match('/foo/bar') }
40
- it { should_not match('/foo%2Fbar') }
41
- it { should_not match('/foo%2fbar') }
42
-
43
- it { should expand.to('/foo/bar') }
44
- it { should_not expand(a: 1) }
45
- end
46
-
47
- pattern '/:foo' do
48
- it { should match('/foo') .capturing foo: 'foo' }
49
- it { should match('/bar') .capturing foo: 'bar' }
50
- it { should match('/foo.bar') .capturing foo: 'foo.bar' }
51
- it { should match('/%0Afoo') .capturing foo: '%0Afoo' }
52
- it { should match('/foo%2Fbar') .capturing foo: 'foo%2Fbar' }
53
-
54
- it { should_not match('/foo?') }
55
- it { should_not match('/foo/bar') }
56
- it { should_not match('/') }
57
- it { should_not match('/foo/') }
58
-
59
- example { pattern.params('/foo') .should be == {"foo" => "foo"} }
60
- example { pattern.params('/f%20o') .should be == {"foo" => "f o"} }
61
- example { pattern.params('').should be_nil }
62
-
63
- it { should expand(foo: 'bar') .to('/bar') }
64
- it { should expand(foo: 'b r') .to('/b%20r') }
65
- it { should expand(foo: 'foo/bar') .to('/foo%2Fbar') }
66
-
67
- it { should_not expand(foo: 'foo', bar: 'bar') }
68
- it { should_not expand(bar: 'bar') }
69
- it { should_not expand }
70
-
71
- it { should generate_template('/{foo}') }
72
- end
73
-
74
- pattern '/föö' do
75
- it { should match("/f%C3%B6%C3%B6") }
76
- it { should expand.to("/f%C3%B6%C3%B6") }
77
- it { should_not expand(a: 1) }
78
- end
79
-
80
- pattern "/:foo/:bar" do
81
- it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' }
82
- it { should match('/foo.bar/bar.foo') .capturing foo: 'foo.bar', bar: 'bar.foo' }
83
- it { should match('/user@example.com/name') .capturing foo: 'user@example.com', bar: 'name' }
84
- it { should match('/10.1/te.st') .capturing foo: '10.1', bar: 'te.st' }
85
- it { should match('/10.1.2/te.st') .capturing foo: '10.1.2', bar: 'te.st' }
86
-
87
- it { should_not match('/foo%2Fbar') }
88
- it { should_not match('/foo%2fbar') }
89
-
90
- example { pattern.params('/bar/foo').should be == {"foo" => "bar", "bar" => "foo"} }
91
- example { pattern.params('').should be_nil }
92
-
93
- it { should expand(foo: 'foo', bar: 'bar').to('/foo/bar') }
94
- it { should_not expand(foo: 'foo') }
95
- it { should_not expand(bar: 'bar') }
96
-
97
- it { should generate_template('/{foo}/{bar}') }
98
- end
99
-
100
- pattern '/hello/:person' do
101
- it { should match('/hello/Frank').capturing person: 'Frank' }
102
- it { should expand(person: 'Frank') .to '/hello/Frank' }
103
- it { should expand(person: 'Frank?') .to '/hello/Frank%3F' }
104
-
105
- it { should generate_template('/hello/{person}') }
106
- end
107
-
108
- pattern '/?:foo?/?:bar?' do
109
- it { should match('/?hello?/?world?').capturing foo: 'hello', bar: 'world' }
110
- it { should_not match('/hello/world/') }
111
- it { should expand(foo: 'hello', bar: 'world').to('/%3Fhello%3F/%3Fworld%3F') }
112
- it { should generate_template('/?{foo}?/?{bar}?') }
113
- end
114
-
115
- pattern '/:foo_bar' do
116
- it { should match('/hello').capturing foo_bar: 'hello' }
117
- it { should expand(foo_bar: 'hello').to('/hello') }
118
- it { should generate_template('/{foo_bar}') }
119
- end
120
-
121
- pattern '/*foo' do
122
- it { should match('/') .capturing foo: '' }
123
- it { should match('/foo') .capturing foo: 'foo' }
124
- it { should match('/foo/bar') .capturing foo: 'foo/bar' }
125
-
126
- it { should expand .to('/') }
127
- it { should expand(foo: nil) .to('/') }
128
- it { should expand(foo: '') .to('/') }
129
- it { should expand(foo: 'foo') .to('/foo') }
130
- it { should expand(foo: 'foo/bar') .to('/foo/bar') }
131
- it { should expand(foo: 'foo.bar') .to('/foo.bar') }
132
-
133
- it { should generate_template('/{+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}') }
141
- end
142
-
143
- pattern '/:foo/*bar' do
144
- it { should match("/foo/bar/baz") .capturing foo: 'foo', bar: 'bar/baz' }
145
- it { should match("/foo%2Fbar/baz") .capturing foo: 'foo%2Fbar', bar: 'baz' }
146
- it { should match("/foo/") .capturing foo: 'foo', bar: '' }
147
- it { should match('/h%20w/h%20a%20y') .capturing foo: 'h%20w', bar: 'h%20a%20y' }
148
- it { should_not match('/foo') }
149
-
150
- it { should expand(foo: 'foo') .to('/foo/') }
151
- it { should expand(foo: 'foo', bar: 'bar') .to('/foo/bar') }
152
- it { should expand(foo: 'foo', bar: 'foo/bar') .to('/foo/foo/bar') }
153
- it { should expand(foo: 'foo/bar', bar: 'bar') .to('/foo%2Fbar/bar') }
154
-
155
- it { should generate_template('/{foo}/{+bar}') }
156
- end
157
-
158
- pattern '/test$/' do
159
- it { should match('/test$/') }
160
- it { should expand.to('/test$/') }
161
- end
162
-
163
- pattern '/te+st/' do
164
- it { should match('/te+st/') }
165
- it { should_not match('/test/') }
166
- it { should_not match('/teest/') }
167
- it { should expand.to('/te+st/') }
168
- end
169
-
170
- pattern "/path with spaces" do
171
- it { should match('/path%20with%20spaces') }
172
- it { should match('/path%2Bwith%2Bspaces') }
173
- it { should match('/path+with+spaces') }
174
- it { should expand.to('/path%20with%20spaces') }
175
-
176
- it { should generate_template('/path%20with%20spaces') }
177
- end
178
-
179
- pattern '/foo&bar' do
180
- it { should match('/foo&bar') }
181
- end
182
-
183
- pattern '/*a/:foo/*b/*c' do
184
- it { should match('/bar/foo/bling/baz/boom').capturing a: 'bar', foo: 'foo', b: 'bling', c: 'baz/boom' }
185
- example { pattern.params('/bar/foo/bling/baz/boom').should be == { "a" => 'bar', "foo" => 'foo', "b" => 'bling', "c" => 'baz/boom' } }
186
- it { should expand(a: 'bar', foo: 'foo', b: 'bling', c: 'baz/boom').to('/bar/foo/bling/baz/boom') }
187
- it { should generate_template('/{+a}/{foo}/{+b}/{+c}') }
188
- end
189
-
190
- pattern '/test.bar' do
191
- it { should match('/test.bar') }
192
- it { should_not match('/test0bar') }
193
- end
194
-
195
- pattern '/:file.:ext' do
196
- it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
197
- it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' }
198
- it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' }
199
-
200
- it { should match('/pony%E6%AD%A3%2Ejpg') .capturing file: 'pony%E6%AD%A3', ext: 'jpg' }
201
- it { should match('/pony%e6%ad%a3%2ejpg') .capturing file: 'pony%e6%ad%a3', ext: 'jpg' }
202
- it { should match('/pony正%2Ejpg') .capturing file: 'pony正', ext: 'jpg' }
203
- it { should match('/pony正%2ejpg') .capturing file: 'pony正', ext: 'jpg' }
204
- it { should match('/pony正..jpg') .capturing file: 'pony正.', ext: 'jpg' }
205
-
206
- it { should_not match('/.jpg') }
207
- it { should expand(file: 'pony', ext: 'jpg').to('/pony.jpg') }
208
- end
209
-
210
- pattern '/:a(x)' do
211
- it { should match('/a') .capturing a: 'a' }
212
- it { should match('/xa') .capturing a: 'xa' }
213
- it { should match('/axa') .capturing a: 'axa' }
214
- it { should match('/ax') .capturing a: 'a' }
215
- it { should match('/axax') .capturing a: 'axa' }
216
- it { should match('/axaxx') .capturing a: 'axax' }
217
- it { should expand(a: 'x').to('/xx') }
218
- it { should expand(a: 'a').to('/ax') }
219
-
220
- it { should generate_template('/{a}x') }
221
- it { should generate_template('/{a}') }
222
- end
223
-
224
- pattern '/:user(@:host)' do
225
- it { should match('/foo@bar') .capturing user: 'foo', host: 'bar' }
226
- it { should match('/foo.foo@bar') .capturing user: 'foo.foo', host: 'bar' }
227
- it { should match('/foo@bar.bar') .capturing user: 'foo', host: 'bar.bar' }
228
-
229
- it { should expand(user: 'foo') .to('/foo') }
230
- it { should expand(user: 'foo', host: 'bar') .to('/foo@bar') }
231
-
232
- it { should generate_template('/{user}') }
233
- it { should generate_template('/{user}@{host}') }
234
- end
235
-
236
- pattern '/:file(.:ext)' do
237
- it { should match('/pony') .capturing file: 'pony', ext: nil }
238
- it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
239
- it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' }
240
- it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' }
241
- it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: 'jpg' }
242
- it { should match('/pony.') .capturing file: 'pony.' }
243
- it { should_not match('/.jpg') }
244
-
245
- it { should expand(file: 'pony') .to('/pony') }
246
- it { should expand(file: 'pony', ext: 'jpg') .to('/pony.jpg') }
247
-
248
- it { should generate_template('/{file}') }
249
- it { should generate_template('/{file}.{ext}') }
250
- end
251
-
252
- pattern '/:id/test.bar' do
253
- it { should match('/3/test.bar') .capturing id: '3' }
254
- it { should match('/2/test.bar') .capturing id: '2' }
255
- it { should match('/2E/test.bar') .capturing id: '2E' }
256
- it { should match('/2e/test.bar') .capturing id: '2e' }
257
- it { should match('/%2E/test.bar') .capturing id: '%2E' }
258
- end
259
-
260
- pattern '/10/:id' do
261
- it { should match('/10/test') .capturing id: 'test' }
262
- it { should match('/10/te.st') .capturing id: 'te.st' }
263
- end
264
-
265
- pattern '/10.1/:id' do
266
- it { should match('/10.1/test') .capturing id: 'test' }
267
- it { should match('/10.1/te.st') .capturing id: 'te.st' }
268
- end
269
-
270
- pattern '/:foo.:bar/:id' do
271
- it { should match('/10.1/te.st') .capturing foo: "10", bar: "1", id: "te.st" }
272
- it { should match('/10.1.2/te.st') .capturing foo: "10.1", bar: "2", id: "te.st" }
273
- end
274
-
275
- pattern '/:a/:b(.)(:c)' do
276
- it { should match('/a/b') .capturing a: 'a', b: 'b', c: nil }
277
- it { should match('/a/b.c') .capturing a: 'a', b: 'b', c: 'c' }
278
- it { should match('/a.b/c') .capturing a: 'a.b', b: 'c', c: nil }
279
- it { should match('/a.b/c.d') .capturing a: 'a.b', b: 'c', c: 'd' }
280
- it { should_not match('/a.b/c.d/e') }
281
-
282
- it { should expand(a: ?a, b: ?b) .to('/a/b.') }
283
- it { should expand(a: ?a, b: ?b, c: ?c) .to('/a/b.c') }
284
-
285
- it { should generate_template('/{a}/{b}') }
286
- it { should generate_template('/{a}/{b}.') }
287
- it { should generate_template('/{a}/{b}.{c}') }
288
- end
289
-
290
- pattern '/:a(foo:b)' do
291
- it { should match('/barfoobar') .capturing a: 'bar', b: 'bar' }
292
- it { should match('/barfoobarfoobar') .capturing a: 'barfoobar', b: 'bar' }
293
- it { should match('/bar') .capturing a: 'bar', b: nil }
294
- it { should_not match('/') }
295
-
296
- it { should expand(a: ?a) .to('/a') }
297
- it { should expand(a: ?a, b: ?b) .to('/afoob') }
298
-
299
- it { should generate_template('/{a}foo{b}') }
300
- it { should generate_template('/{a}') }
301
- it { should_not generate_template('/{a}foo') }
302
- end
303
-
304
- pattern '/fo(o)' do
305
- it { should match('/fo') }
306
- it { should match('/foo') }
307
- it { should_not match('') }
308
- it { should_not match('/') }
309
- it { should_not match('/f') }
310
- it { should_not match('/fooo') }
311
-
312
- it { should expand.to('/foo') }
313
- end
314
-
315
- pattern '/foo?' do
316
- it { should match('/foo?') }
317
- it { should_not match('/foo\?') }
318
- it { should_not match('/fo') }
319
- it { should_not match('/foo') }
320
- it { should_not match('') }
321
- it { should_not match('/') }
322
- it { should_not match('/f') }
323
- it { should_not match('/fooo') }
324
-
325
- it { should expand.to('/foo%3F') }
326
- end
327
-
328
- pattern '/:fOO' do
329
- it { should match('/a').capturing fOO: 'a' }
330
- end
331
-
332
- pattern '/:_X' do
333
- it { should match('/a').capturing _X: 'a' }
334
- end
335
-
336
- pattern '/:f00' do
337
- it { should match('/a').capturing f00: 'a' }
338
- end
339
-
340
- pattern '/:foo(/:bar)/:baz' do
341
- it { should match('/foo/bar/baz').capturing foo: 'foo', bar: 'bar', baz: 'baz' }
342
- it { should expand(foo: ?a, baz: ?b) .to('/a/b') }
343
- it { should expand(foo: ?a, baz: ?b, bar: ?x) .to('/a/x/b') }
344
- end
345
-
346
- pattern '/:foo', capture: /\d+/ do
347
- it { should match('/1') .capturing foo: '1' }
348
- it { should match('/123') .capturing foo: '123' }
349
-
350
- it { should_not match('/') }
351
- it { should_not match('/foo') }
352
- end
353
-
354
- pattern '/:foo', capture: /\d+/ do
355
- it { should match('/1') .capturing foo: '1' }
356
- it { should match('/123') .capturing foo: '123' }
357
-
358
- it { should_not match('/') }
359
- it { should_not match('/foo') }
360
- end
361
-
362
- pattern '/:foo', capture: '1' do
363
- it { should match('/1').capturing foo: '1' }
364
-
365
- it { should_not match('/') }
366
- it { should_not match('/foo') }
367
- it { should_not match('/123') }
368
- end
369
-
370
- pattern '/:foo', capture: 'a.b' do
371
- it { should match('/a.b') .capturing foo: 'a.b' }
372
- it { should match('/a%2Eb') .capturing foo: 'a%2Eb' }
373
- it { should match('/a%2eb') .capturing foo: 'a%2eb' }
374
-
375
- it { should_not match('/ab') }
376
- it { should_not match('/afb') }
377
- it { should_not match('/a1b') }
378
- it { should_not match('/a.bc') }
379
- end
380
-
381
- pattern '/:foo(/:bar)', capture: :alpha do
382
- it { should match('/abc') .capturing foo: 'abc', bar: nil }
383
- it { should match('/a/b') .capturing foo: 'a', bar: 'b' }
384
- it { should match('/a') .capturing foo: 'a', bar: nil }
385
-
386
- it { should_not match('/1/2') }
387
- it { should_not match('/a/2') }
388
- it { should_not match('/1/b') }
389
- it { should_not match('/1') }
390
- it { should_not match('/1/') }
391
- it { should_not match('/a/') }
392
- it { should_not match('//a') }
393
- end
394
-
395
- pattern '/:foo', capture: ['foo', 'bar', /\d+/] do
396
- it { should match('/1') .capturing foo: '1' }
397
- it { should match('/123') .capturing foo: '123' }
398
- it { should match('/foo') .capturing foo: 'foo' }
399
- it { should match('/bar') .capturing foo: 'bar' }
400
-
401
- it { should_not match('/') }
402
- it { should_not match('/baz') }
403
- it { should_not match('/foo1') }
404
- end
405
-
406
- pattern '/:foo:bar:baz', capture: { foo: :alpha, bar: /\d+/ } do
407
- it { should match('/ab123xy-1') .capturing foo: 'ab', bar: '123', baz: 'xy-1' }
408
- it { should match('/ab123') .capturing foo: 'ab', bar: '12', baz: '3' }
409
- it { should_not match('/123abcxy-1') }
410
- it { should_not match('/abcxy-1') }
411
- it { should_not match('/abc1') }
412
- end
413
-
414
- pattern '/:foo', capture: { foo: ['foo', 'bar', /\d+/] } do
415
- it { should match('/1') .capturing foo: '1' }
416
- it { should match('/123') .capturing foo: '123' }
417
- it { should match('/foo') .capturing foo: 'foo' }
418
- it { should match('/bar') .capturing foo: 'bar' }
419
-
420
- it { should_not match('/') }
421
- it { should_not match('/baz') }
422
- it { should_not match('/foo1') }
423
- end
424
-
425
- pattern '/:file(.:ext)', capture: { ext: ['jpg', 'png'] } do
426
- it { should match('/pony') .capturing file: 'pony', ext: nil }
427
- it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
428
- it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' }
429
- it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' }
430
- it { should match('/pony.png') .capturing file: 'pony', ext: 'png' }
431
- it { should match('/pony%2Epng') .capturing file: 'pony', ext: 'png' }
432
- it { should match('/pony%2epng') .capturing file: 'pony', ext: 'png' }
433
- it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: 'jpg' }
434
- it { should match('/pony.jpg.png') .capturing file: 'pony.jpg', ext: 'png' }
435
- it { should match('/pony.gif') .capturing file: 'pony.gif', ext: nil }
436
- it { should match('/pony.') .capturing file: 'pony.', ext: nil }
437
- it { should_not match('.jpg') }
438
- end
439
-
440
- pattern '/:file(:ext)', capture: { ext: ['.jpg', '.png', '.tar.gz'] } do
441
- it { should match('/pony') .capturing file: 'pony', ext: nil }
442
- it { should match('/pony.jpg') .capturing file: 'pony', ext: '.jpg' }
443
- it { should match('/pony.png') .capturing file: 'pony', ext: '.png' }
444
- it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: '.jpg' }
445
- it { should match('/pony.jpg.png') .capturing file: 'pony.jpg', ext: '.png' }
446
- it { should match('/pony.tar.gz') .capturing file: 'pony', ext: '.tar.gz' }
447
- it { should match('/pony.gif') .capturing file: 'pony.gif', ext: nil }
448
- it { should match('/pony.') .capturing file: 'pony.', ext: nil }
449
- it { should_not match('/.jpg') }
450
- end
451
-
452
- pattern '/:a(@:b)', capture: { b: /\d+/ } do
453
- it { should match('/a') .capturing a: 'a', b: nil }
454
- it { should match('/a@1') .capturing a: 'a', b: '1' }
455
- it { should match('/a@b') .capturing a: 'a@b', b: nil }
456
- it { should match('/a@1@2') .capturing a: 'a@1', b: '2' }
457
- end
458
-
459
- pattern '/:a(b)', greedy: false do
460
- it { should match('/ab').capturing a: 'a' }
461
- end
462
-
463
- pattern '/:file(.:ext)', greedy: false do
464
- it { should match('/pony') .capturing file: 'pony', ext: nil }
465
- it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
466
- it { should match('/pony.png.jpg') .capturing file: 'pony', ext: 'png.jpg' }
467
- end
468
-
469
- pattern '/:controller(/:action(/:id(.:format)))' do
470
- it { should match('/content').capturing controller: 'content' }
471
- end
472
-
473
- pattern '/fo(o)', uri_decode: false do
474
- it { should match('/foo') }
475
- it { should match('/fo') }
476
- it { should_not match('/fo(o)') }
477
- end
478
-
479
- pattern '/foo/bar', uri_decode: false do
480
- it { should match('/foo/bar') }
481
- it { should_not match('/foo%2Fbar') }
482
- it { should_not match('/foo%2fbar') }
483
- end
484
-
485
- pattern "/path with spaces", uri_decode: false do
486
- it { should match('/path with spaces') }
487
- it { should_not match('/path%20with%20spaces') }
488
- it { should_not match('/path%2Bwith%2Bspaces') }
489
- it { should_not match('/path+with+spaces') }
490
- end
491
-
492
- pattern "/path with spaces", space_matches_plus: false do
493
- it { should match('/path%20with%20spaces') }
494
- it { should_not match('/path%2Bwith%2Bspaces') }
495
- it { should_not match('/path+with+spaces') }
496
- end
497
-
498
- context 'invalid syntax' do
499
- example 'unexpected closing parenthesis' do
500
- expect { Mustermann::Rails.new('foo)bar') }.
501
- to raise_error(Mustermann::ParseError, 'unexpected ) while parsing "foo)bar"')
502
- end
503
-
504
- example 'missing closing parenthesis' do
505
- expect { Mustermann::Rails.new('foo(bar') }.
506
- to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo(bar"')
507
- end
508
- end
509
-
510
- context 'invalid capture names' do
511
- example 'empty name' do
512
- expect { Mustermann::Rails.new('/:/') }.
513
- to raise_error(Mustermann::CompileError, "capture name can't be empty: \"/:/\"")
514
- end
515
-
516
- example 'named splat' do
517
- expect { Mustermann::Rails.new('/:splat/') }.
518
- to raise_error(Mustermann::CompileError, "capture name can't be splat: \"/:splat/\"")
519
- end
520
-
521
- example 'named captures' do
522
- expect { Mustermann::Rails.new('/:captures/') }.
523
- to raise_error(Mustermann::CompileError, "capture name can't be captures: \"/:captures/\"")
524
- end
525
-
526
- example 'with capital letter' do
527
- expect { Mustermann::Rails.new('/:Foo/') }.
528
- to raise_error(Mustermann::CompileError, "capture name must start with underscore or lower case letter: \"/:Foo/\"")
529
- end
530
-
531
- example 'with integer' do
532
- expect { Mustermann::Rails.new('/:1a/') }.
533
- to raise_error(Mustermann::CompileError, "capture name must start with underscore or lower case letter: \"/:1a/\"")
534
- end
535
-
536
- example 'same name twice' do
537
- expect { Mustermann::Rails.new('/:foo(/:bar)/:bar') }.
538
- to raise_error(Mustermann::CompileError, "can't use the same capture name twice: \"/:foo(/:bar)/:bar\"")
539
- end
540
- end
541
-
542
- context 'Regexp compatibility' do
543
- describe :=== do
544
- example('non-matching') { Mustermann::Rails.new("/") .should_not be === '/foo' }
545
- example('matching') { Mustermann::Rails.new("/:foo") .should be === '/foo' }
546
- end
547
-
548
- describe :=~ do
549
- example('non-matching') { Mustermann::Rails.new("/") .should_not be =~ '/foo' }
550
- example('matching') { Mustermann::Rails.new("/:foo") .should be =~ '/foo' }
551
-
552
- context 'String#=~' do
553
- example('non-matching') { "/foo".should_not be =~ Mustermann::Rails.new("/") }
554
- example('matching') { "/foo".should be =~ Mustermann::Rails.new("/:foo") }
555
- end
556
- end
557
-
558
- describe :to_regexp do
559
- example('empty pattern') { Mustermann::Rails.new('').to_regexp.should be == /\A(?-mix:)\Z/ }
560
-
561
- context 'Regexp.try_convert' do
562
- example('empty pattern') { Regexp.try_convert(Mustermann::Rails.new('')).should be == /\A(?-mix:)\Z/ }
563
- end
564
- end
565
- end
566
-
567
- context 'Proc compatibility' do
568
- describe :to_proc do
569
- example { Mustermann::Rails.new("/").to_proc.should be_a(Proc) }
570
- example('non-matching') { Mustermann::Rails.new("/") .to_proc.call('/foo').should be == false }
571
- example('matching') { Mustermann::Rails.new("/:foo") .to_proc.call('/foo').should be == true }
572
- end
573
- end
574
-
575
- context "peeking" do
576
- subject(:pattern) { Mustermann::Rails.new(":name") }
577
-
578
- describe :peek_size do
579
- example { pattern.peek_size("foo bar/blah") .should be == "foo bar".size }
580
- example { pattern.peek_size("foo%20bar/blah") .should be == "foo%20bar".size }
581
- example { pattern.peek_size("/foo bar") .should be_nil }
582
- end
583
-
584
- describe :peek_match do
585
- example { pattern.peek_match("foo bar/blah") .to_s .should be == "foo bar" }
586
- example { pattern.peek_match("foo%20bar/blah") .to_s .should be == "foo%20bar" }
587
- example { pattern.peek_match("/foo bar") .should be_nil }
588
- end
589
-
590
- describe :peek_params do
591
- example { pattern.peek_params("foo bar/blah") .should be == [{"name" => "foo bar"}, "foo bar".size] }
592
- example { pattern.peek_params("foo%20bar/blah") .should be == [{"name" => "foo bar"}, "foo%20bar".size] }
593
- example { pattern.peek_params("/foo bar") .should be_nil }
594
- end
595
- end
596
-
597
- context 'version compatibility' do
598
- context '2.3' do
599
- pattern '(foo)', version: '2.3' do
600
- it { should_not match("") }
601
- it { should_not match("foo") }
602
- it { should match("(foo)") }
603
- end
604
-
605
- pattern '\\:name', version: '2.3' do
606
- it { should match('%5cfoo').capturing(name: 'foo') }
607
- end
608
- end
609
-
610
- context '3.0' do
611
- pattern '(foo)', version: '3.0' do
612
- it { should match("") }
613
- it { should match("foo") }
614
- end
615
-
616
- pattern '\\:name', version: '3.0' do
617
- it { should match(':name') }
618
- it { should_not match(':foo') }
619
- end
620
- end
621
-
622
- context '3.2' do
623
- pattern '\\:name', version: '3.2' do
624
- it { should match('%5cfoo').capturing(name: 'foo') }
625
- end
626
- end
627
-
628
- context '4.0' do
629
- pattern '\\:name', version: '4.0' do
630
- it { should match('foo').capturing(name: 'foo') }
631
- end
632
- end
633
-
634
- context '4.2' do
635
- pattern '\\:name', version: '4.2' do
636
- it { should match(':name') }
637
- it { should_not match(':foo') }
638
- end
639
- end
640
-
641
- context '5.0' do
642
- pattern 'foo|bar', version: '5.0' do
643
- it { should match('foo') }
644
- it { should match('bar') }
645
- end
646
- end
647
- end
648
- end