radius-ts 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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