radius-ts 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  module Radius
2
2
  module Version
3
3
  Major = '1'
4
- Minor = '0'
4
+ Minor = '1'
5
5
  Tiny = '0'
6
6
 
7
7
  class << self
@@ -1,27 +1,56 @@
1
1
  namespace :scan do
2
- desc 'Generate the parser'
3
- task 'build' => ['lib/radius/parser/scan.rb']
2
+ desc 'Generate the parsers'
3
+ task 'build' => [
4
+ 'lib/radius/parser/scanner.rb',
5
+ 'lib/radius/parser/squiggle_scanner.rb'
6
+ ]
4
7
 
5
- desc 'Generate a PDF state graph from the parser'
6
- task 'graph' => ['doc/scan.pdf']
8
+ desc 'Generate a PDF state graph from the parsers'
9
+ task 'graph' => ['doc/scanner.pdf', 'doc/squiggle_scanner.rb']
7
10
 
8
- desc 'turn the scan.rl file into a ruby file'
9
- file 'lib/radius/parser/scan.rb' => ['lib/radius/parser/scan.rl'] do |t|
11
+ desc 'turn the scanner.rl file into a ruby file'
12
+ file 'lib/radius/parser/scanner.rb' => 'lib/radius/parser/scanner.rl' do |t|
10
13
  cd 'lib/radius/parser' do
11
- sh "ragel -R -F1 scan.rl"
14
+ sh "ragel -R -F1 scanner.rl"
15
+ end
16
+ end
17
+
18
+ desc 'turn the squiggle_scanner.rl file into a ruby file'
19
+ file 'lib/radius/parser/squiggle_scanner.rb' =>
20
+ ['lib/radius/parser/squiggle_scanner.rl'] \
21
+ do |t|
22
+ cd 'lib/radius/parser' do
23
+ sh "ragel -R -F1 squiggle_scanner.rl"
12
24
  end
13
25
  end
14
26
 
15
27
  desc 'pdf of the ragel scanner'
16
- file 'doc/scan.pdf' => 'lib/radius/parser/scan.dot' do |t|
28
+ file 'doc/scanner.pdf' => 'lib/radius/parser/scanner.dot' do |t|
29
+ cd 'lib/radius/parser' do
30
+ sh "dot -Tpdf -o ../../../doc/scanner.pdf scanner.dot"
31
+ end
32
+ end
33
+
34
+ desc 'pdf of the ragel squiggle scanner'
35
+ file 'doc/squiggle_scanner.pdf' =>
36
+ ['lib/radius/parser/squiggle_scanner.dot'] \
37
+ do |t|
38
+ cd 'lib/radius/parser' do
39
+ sh "dot -Tpdf -o ../../../doc/squiggle_scanner.pdf squiggle_scanner.dot"
40
+ end
41
+ end
42
+
43
+ file 'lib/radius/parser/scanner.dot' => 'lib/radius/parser/scanner.rl' do |t|
17
44
  cd 'lib/radius/parser' do
18
- sh "dot -Tpdf -o ../../../doc/scan.pdf scan.dot"
45
+ sh "ragel -Vp scanner.rl > scanner.dot"
19
46
  end
20
47
  end
21
48
 
22
- file 'lib/radius/parser/scan.dot' => ['lib/radius/parser/scan.rl'] do |t|
49
+ file 'lib/radius/parser/squiggle_scanner.dot' =>
50
+ ['lib/radius/parser/squiggle_scanner.rl'] \
51
+ do |t|
23
52
  cd 'lib/radius/parser' do
24
- sh "ragel -Vp scan.rl > scan.dot"
53
+ sh "ragel -Vp squiggle_scanner.rl > squiggle_scanner.dot"
25
54
  end
26
55
  end
27
- end
56
+ end
@@ -0,0 +1,276 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+ require 'radius/parser/squiggle_scanner'
3
+
4
+ class RadiusSquiggleTest < Test::Unit::TestCase
5
+ include RadiusTestHelper
6
+
7
+ def setup
8
+ @context = new_context
9
+ @parser = Radius::Parser.new(@context, :scanner => Radius::SquiggleScanner.new)
10
+ end
11
+
12
+ def test_sane_scanner_default
13
+ assert_kind_of Radius::Scanner, Radius::Parser.new.scanner
14
+ end
15
+
16
+ def test_initialize_with_params
17
+ @parser = Radius::Parser.new(:scanner => Radius::SquiggleScanner.new)
18
+ assert_kind_of Radius::SquiggleScanner, @parser.scanner
19
+ end
20
+
21
+ def test_parse_individual_tags_and_parameters
22
+ define_tag "add" do |tag|
23
+ tag.attr["param1"].to_i + tag.attr["param2"].to_i
24
+ end
25
+ assert_parse_output "{3}", %[{{ add param1="1" param2='2'/}}]
26
+ end
27
+
28
+ def test_parse_attributes
29
+ attributes = %[{"a"=>"1", "b"=>"2", "c"=>"3", "d"=>"'"}]
30
+ assert_parse_output attributes, %[{attr a="1" b='2'c="3"d="'" /}]
31
+ assert_parse_output attributes, %[{attr a="1" b='2'c="3"d="'"}{/attr}]
32
+ end
33
+
34
+ def test_parse_attributes_with_slashes_or_angle_brackets
35
+ slash = %[{"slash"=>"/"}]
36
+ angle = %[{"angle"=>">"}]
37
+ assert_parse_output slash, %[{attr slash="/"}{/attr}]
38
+ assert_parse_output slash, %[{attr slash="/"}{attr /}{/attr}]
39
+ assert_parse_output angle, %[{attr angle=">"}{/attr}]
40
+ end
41
+
42
+ def test_parse_quotes
43
+ assert_parse_output "test []", %[{echo value="test" /} {wrap attr="test"}{/wrap}]
44
+ end
45
+
46
+ def test_things_that_should_be_left_alone
47
+ [
48
+ %[ test="2"="4" ],
49
+ %[="2" ]
50
+ ].each do |middle|
51
+ assert_parsed_is_unchanged "{attr#{middle}/}"
52
+ assert_parsed_is_unchanged "{attr#{middle}}"
53
+ end
54
+ end
55
+
56
+ def test_tags_inside_html_tags
57
+ assert_parse_output %[<div class="xzibit">tags in yo tags</div>],
58
+ %[<div class="{reverse}tibizx{/reverse}">tags in yo tags</div>]
59
+ end
60
+
61
+ def test_parse_result_is_always_a_string
62
+ define_tag("twelve") { 12 }
63
+ assert_parse_output "12", "{ twelve /}"
64
+ end
65
+
66
+ def test_parse_double_tags
67
+ assert_parse_output "test".reverse, "{reverse}test{/reverse}"
68
+ assert_parse_output "tset TEST", "{reverse}test{/reverse} {capitalize}test{/capitalize}"
69
+ end
70
+
71
+ def test_parse_tag_nesting
72
+ define_tag("parent", :for => '')
73
+ define_tag("parent:child", :for => '')
74
+ define_tag("extra", :for => '')
75
+ define_tag("nesting") { |tag| tag.nesting }
76
+ define_tag("extra:nesting") { |tag| tag.nesting.gsub(':', ' > ') }
77
+ define_tag("parent:child:nesting") { |tag| tag.nesting.gsub(':', ' * ') }
78
+ assert_parse_output "nesting", "{nesting /}"
79
+ assert_parse_output "parent:nesting", "{parent:nesting /}"
80
+ assert_parse_output "extra > nesting", "{extra:nesting /}"
81
+ assert_parse_output "parent * child * nesting", "{parent:child:nesting /}"
82
+ assert_parse_output "parent > extra > nesting", "{parent:extra:nesting /}"
83
+ assert_parse_output "parent > child > extra > nesting", "{parent:child:extra:nesting /}"
84
+ assert_parse_output "parent * extra * child * nesting", "{parent:extra:child:nesting /}"
85
+ assert_parse_output "parent > extra > child > extra > nesting", "{parent:extra:child:extra:nesting /}"
86
+ assert_parse_output "parent > extra > child > extra > nesting", "{parent}{extra}{child}{extra}{nesting /}{/extra}{/child}{/extra}{/parent}"
87
+ assert_parse_output "extra * parent * child * nesting", "{extra:parent:child:nesting /}"
88
+ assert_parse_output "extra > parent > nesting", "{extra}{parent:nesting /}{/extra}"
89
+ assert_parse_output "extra * parent * child * nesting", "{extra:parent}{child:nesting /}{/extra:parent}"
90
+ assert_raises(Radius::UndefinedTagError) { @parser.parse("{child /}") }
91
+ end
92
+ def test_parse_tag_nesting_2
93
+ define_tag("parent", :for => '')
94
+ define_tag("parent:child", :for => '')
95
+ define_tag("content") { |tag| tag.nesting }
96
+ assert_parse_output 'parent:child:content', '{parent}{child:content /}{/parent}'
97
+ end
98
+
99
+ def test_parse_tag__binding_do_missing
100
+ define_tag 'test' do |tag|
101
+ tag.missing!
102
+ end
103
+ e = assert_raises(Radius::UndefinedTagError) { @parser.parse("{test /}") }
104
+ assert_equal "undefined tag `test'", e.message
105
+ end
106
+
107
+ def test_parse_chirpy_bird
108
+ # :> chirp chirp
109
+ assert_parse_output "<:", "<:"
110
+ end
111
+
112
+ def test_parse_tag__binding_render_tag
113
+ define_tag('test') { |tag| "Hello #{tag.attr['name']}!" }
114
+ define_tag('hello') { |tag| tag.render('test', tag.attr) }
115
+ assert_parse_output 'Hello John!', '{hello name="John" /}'
116
+ end
117
+
118
+ def test_accessing_tag_attributes_through_tag_indexer
119
+ define_tag('test') { |tag| "Hello #{tag['name']}!" }
120
+ assert_parse_output 'Hello John!', '{test name="John" /}'
121
+ end
122
+
123
+ def test_parse_tag__binding_render_tag_with_block
124
+ define_tag('test') { |tag| "Hello #{tag.expand}!" }
125
+ define_tag('hello') { |tag| tag.render('test') { tag.expand } }
126
+ assert_parse_output 'Hello John!', '{hello}John{/hello}'
127
+ end
128
+
129
+ def test_tag_locals
130
+ define_tag "outer" do |tag|
131
+ tag.locals.var = 'outer'
132
+ tag.expand
133
+ end
134
+ define_tag "outer:inner" do |tag|
135
+ tag.locals.var = 'inner'
136
+ tag.expand
137
+ end
138
+ define_tag "outer:var" do |tag|
139
+ tag.locals.var
140
+ end
141
+ assert_parse_output 'outer', "{outer}{var /}{/outer}"
142
+ assert_parse_output 'outer:inner:outer', "{outer}{var /}:{inner}{var /}{/inner}:{var /}{/outer}"
143
+ assert_parse_output 'outer:inner:outer:inner:outer', "{outer}{var /}:{inner}{var /}:{outer}{var /}{/outer}:{var /}{/inner}:{var /}{/outer}"
144
+ assert_parse_output 'outer', "{outer:var /}"
145
+ end
146
+
147
+ def test_tag_globals
148
+ define_tag "set" do |tag|
149
+ tag.globals.var = tag.attr['value']
150
+ ''
151
+ end
152
+ define_tag "var" do |tag|
153
+ tag.globals.var
154
+ end
155
+ assert_parse_output " true false", %[{var /} {set value="true" /} {var /} {set value="false" /} {var /}]
156
+ end
157
+
158
+ def test_parse_loops
159
+ @item = nil
160
+ define_tag "each" do |tag|
161
+ result = []
162
+ ["Larry", "Moe", "Curly"].each do |item|
163
+ tag.locals.item = item
164
+ result << tag.expand
165
+ end
166
+ result.join(tag.attr["between"] || "")
167
+ end
168
+ define_tag "each:item" do |tag|
169
+ tag.locals.item
170
+ end
171
+ assert_parse_output %[Three Stooges: "Larry", "Moe", "Curly"], %[Three Stooges: {each between=", "}"{item /}"{/each}]
172
+ end
173
+
174
+ def test_parse_speed
175
+ define_tag "set" do |tag|
176
+ tag.globals.var = tag.attr['value']
177
+ ''
178
+ end
179
+ define_tag "var" do |tag|
180
+ tag.globals.var
181
+ end
182
+ parts = %w{decima nobis augue at facer processus commodo legentis odio lectorum dolore nulla esse lius qui nonummy ullamcorper erat ii notare}
183
+ multiplier = parts.map{|p| "#{p}=\"#{rand}\""}.join(' ')
184
+ assert_nothing_raised do
185
+ Timeout.timeout(10) do
186
+ assert_parse_output " false", %[{set value="false" #{multiplier} /} {var /}]
187
+ end
188
+ end
189
+ end
190
+
191
+ def test_tag_option_for
192
+ define_tag 'fun', :for => 'just for kicks'
193
+ assert_parse_output 'just for kicks', '{fun /}'
194
+ end
195
+
196
+ def test_tag_expose_option
197
+ define_tag 'user', :for => users.first, :expose => ['name', :age]
198
+ assert_parse_output 'John', '{user:name /}'
199
+ assert_parse_output '25', '{user}{age /}{/user}'
200
+ e = assert_raises(Radius::UndefinedTagError) { @parser.parse "{user:email /}" }
201
+ assert_equal "undefined tag `email'", e.message
202
+ end
203
+
204
+ def test_tag_expose_attributes_option_on_by_default
205
+ define_tag 'user', :for => user_with_attributes
206
+ assert_parse_output 'John', '{user:name /}'
207
+ end
208
+ def test_tag_expose_attributes_set_to_false
209
+ define_tag 'user_without_attributes', :for => user_with_attributes, :attributes => false
210
+ assert_raises(Radius::UndefinedTagError) { @parser.parse "{user_without_attributes:name /}" }
211
+ end
212
+
213
+ def test_tag_options_must_contain_a_for_option_if_methods_are_exposed
214
+ e = assert_raises(ArgumentError) { define_tag('fun', :expose => :today) { 'test' } }
215
+ assert_equal "tag definition must contain a :for option when used with the :expose option", e.message
216
+ end
217
+
218
+ def test_parse_fail_on_missing_end_tag
219
+ assert_raises(Radius::MissingEndTagError) { @parser.parse("{reverse}") }
220
+ end
221
+
222
+ def test_parse_fail_on_wrong_end_tag
223
+ assert_raises(Radius::WrongEndTagError) { @parser.parse("{reverse}{capitalize}{/reverse}") }
224
+ end
225
+
226
+ def test_copyin_global_values
227
+ @context.globals.foo = 'bar'
228
+ assert_equal 'bar', Radius::Parser.new(@context).context.globals.foo
229
+ end
230
+
231
+ def test_does_not_pollute_copied_globals
232
+ @context.globals.foo = 'bar'
233
+ parser = Radius::Parser.new(@context)
234
+ parser.context.globals.foo = '[baz]'
235
+ assert_equal 'bar', @context.globals.foo
236
+ end
237
+
238
+ protected
239
+
240
+ def assert_parse_output(output, input, message = nil)
241
+ r = @parser.parse(input)
242
+ assert_equal(output, r, message)
243
+ end
244
+
245
+ def assert_parsed_is_unchanged(something)
246
+ assert_parse_output something, something
247
+ end
248
+
249
+ class User
250
+ attr_accessor :name, :age, :email, :friend
251
+ def initialize(name, age, email)
252
+ @name, @age, @email = name, age, email
253
+ end
254
+ def <=>(other)
255
+ name <=> other.name
256
+ end
257
+ end
258
+
259
+ class UserWithAttributes < User
260
+ def attributes
261
+ { :name => name, :age => age, :email => email }
262
+ end
263
+ end
264
+
265
+ def users
266
+ [
267
+ User.new('John', 25, 'test@johnwlong.com'),
268
+ User.new('James', 27, 'test@jameslong.com')
269
+ ]
270
+ end
271
+
272
+ def user_with_attributes
273
+ UserWithAttributes.new('John', 25, 'test@johnwlong.com')
274
+ end
275
+
276
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radius-ts
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John W. Long (me@johnwlong.com)
@@ -12,7 +12,7 @@ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
14
 
15
- date: 2010-02-06 00:00:00 -05:00
15
+ date: 2010-05-13 00:00:00 -04:00
16
16
  default_executable:
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
@@ -58,8 +58,9 @@ files:
58
58
  - lib/radius/error.rb
59
59
  - lib/radius/parse_tag.rb
60
60
  - lib/radius/parser.rb
61
- - lib/radius/parser/scan.rb
62
- - lib/radius/parser/scan.rl
61
+ - lib/radius/parser/scanner.rb
62
+ - lib/radius/parser/squiggle_scanner.rb
63
+ - lib/radius/parser/scanner.rl
63
64
  - lib/radius/tag_binding.rb
64
65
  - lib/radius/tag_definitions.rb
65
66
  - lib/radius/utility.rb
@@ -102,3 +103,4 @@ test_files:
102
103
  - test/multithreaded_test.rb
103
104
  - test/parser_test.rb
104
105
  - test/quickstart_test.rb
106
+ - test/squiggle_test.rb