radius 0.5.1 → 0.6.1
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.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +8 -0
- data/Manifest.txt +21 -0
- data/{QUICKSTART → QUICKSTART.rdoc} +11 -12
- data/{pkg/radius-0.5.0/README → README.rdoc} +38 -17
- data/Rakefile +31 -86
- data/lib/radius.rb +10 -497
- data/lib/radius/context.rb +139 -0
- data/lib/radius/delegating_open_struct.rb +31 -0
- data/lib/radius/error.rb +43 -0
- data/lib/radius/parse_tag.rb +24 -0
- data/lib/radius/parser.rb +65 -0
- data/lib/radius/parser/scan.rb +700 -0
- data/lib/radius/parser/scan.rl +123 -0
- data/lib/radius/tag_binding.rb +71 -0
- data/lib/radius/tag_definitions.rb +78 -0
- data/lib/radius/utility.rb +30 -0
- data/lib/radius/version.rb +14 -0
- data/tasks/scan.rake +27 -0
- data/test/context_test.rb +61 -0
- data/test/{radius_test.rb → parser_test.rb} +51 -82
- data/test/quickstart_test.rb +153 -0
- data/test/test_helper.rb +28 -0
- metadata +109 -61
- metadata.gz.sig +0 -0
- data/README +0 -97
- data/ROADMAP +0 -12
- data/pkg/radius-0.5.0.gem +0 -0
- data/pkg/radius-0.5.0.tgz +0 -0
- data/pkg/radius-0.5.0.zip +0 -0
- data/pkg/radius-0.5.0/CHANGELOG +0 -25
- data/pkg/radius-0.5.0/QUICKSTART +0 -323
- data/pkg/radius-0.5.0/ROADMAP +0 -12
- data/pkg/radius-0.5.0/Rakefile +0 -86
- data/pkg/radius-0.5.0/lib/radius.rb +0 -497
- data/pkg/radius-0.5.0/test/radius_test.rb +0 -321
@@ -0,0 +1,123 @@
|
|
1
|
+
%%{
|
2
|
+
machine parser;
|
3
|
+
|
4
|
+
|
5
|
+
action _prefix { mark_pfx = p }
|
6
|
+
action prefix {
|
7
|
+
if data[mark_pfx..p-1] != @prefix
|
8
|
+
@nodes.last << data[mark_pfx-1..p]
|
9
|
+
fbreak;
|
10
|
+
end
|
11
|
+
}
|
12
|
+
action _starttag { mark_stg = p }
|
13
|
+
action starttag { @starttag = data[mark_stg..p-1] }
|
14
|
+
action _attr { mark_attr = p }
|
15
|
+
action attr {
|
16
|
+
@attrs[@nat] = @vat
|
17
|
+
}
|
18
|
+
|
19
|
+
action prematch {
|
20
|
+
@prematch_end = p
|
21
|
+
@prematch = data[0..p] if p > 0
|
22
|
+
}
|
23
|
+
|
24
|
+
action _nameattr { mark_nat = p }
|
25
|
+
action nameattr { @nat = data[mark_nat..p-1] }
|
26
|
+
action _valattr { mark_vat = p }
|
27
|
+
action valattr { @vat = data[mark_vat..p-1] }
|
28
|
+
|
29
|
+
action opentag { @flavor = :open }
|
30
|
+
action selftag { @flavor = :self }
|
31
|
+
action closetag { @flavor = :close }
|
32
|
+
|
33
|
+
action stopparse {
|
34
|
+
@cursor = p;
|
35
|
+
fbreak;
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
Closeout := empty;
|
40
|
+
|
41
|
+
# words
|
42
|
+
PrefixChar = [\-A-Za-z0-9._?] ;
|
43
|
+
NameChar = [\-A-Za-z0-9._:?] ;
|
44
|
+
TagName = NameChar+ >_starttag %starttag;
|
45
|
+
Prefix = PrefixChar+ >_prefix %prefix;
|
46
|
+
|
47
|
+
Name = Prefix ":" TagName;
|
48
|
+
|
49
|
+
NameAttr = NameChar+ >_nameattr %nameattr;
|
50
|
+
Q1Char = ( "\\\'" | [^'] ) ;
|
51
|
+
Q1Attr = Q1Char* >_valattr %valattr;
|
52
|
+
Q2Char = ( "\\\"" | [^"] ) ;
|
53
|
+
Q2Attr = Q2Char* >_valattr %valattr;
|
54
|
+
|
55
|
+
Attr = NameAttr space* "=" space* ('"' Q2Attr '"' | "'" Q1Attr "'") space* >_attr %attr;
|
56
|
+
Attrs = (space+ Attr* | empty);
|
57
|
+
|
58
|
+
CloseTrailer = "/>" %selftag;
|
59
|
+
OpenTrailer = ">" %opentag;
|
60
|
+
|
61
|
+
Trailer = (OpenTrailer | CloseTrailer);
|
62
|
+
|
63
|
+
OpenOrSelfTag = Name Attrs? Trailer;
|
64
|
+
CloseTag = "/" Name space* ">" %closetag;
|
65
|
+
|
66
|
+
SomeTag = '<' (OpenOrSelfTag | CloseTag);
|
67
|
+
|
68
|
+
main := |*
|
69
|
+
SomeTag => {
|
70
|
+
tag = {:prefix=>@prefix, :name=>@starttag, :flavor => @flavor, :attrs => @attrs}
|
71
|
+
@prefix = nil
|
72
|
+
@name = nil
|
73
|
+
@flavor = :tasteless
|
74
|
+
@attrs = {}
|
75
|
+
@nodes << tag << ''
|
76
|
+
fbreak;
|
77
|
+
};
|
78
|
+
any => {
|
79
|
+
@nodes.last << data[p]
|
80
|
+
@tagstart = p
|
81
|
+
};
|
82
|
+
*|;
|
83
|
+
}%%
|
84
|
+
|
85
|
+
module Radius
|
86
|
+
class Scanner
|
87
|
+
def self.operate(prefix, data)
|
88
|
+
buf = ""
|
89
|
+
csel = ""
|
90
|
+
@prematch = ''
|
91
|
+
@starttag = nil
|
92
|
+
@attrs = {}
|
93
|
+
@flavor = :tasteless
|
94
|
+
@cursor = 0
|
95
|
+
@tagstart = 0
|
96
|
+
@nodes = ['']
|
97
|
+
remainder = data.dup
|
98
|
+
|
99
|
+
until remainder.length == 0
|
100
|
+
p = perform_parse(prefix, remainder)
|
101
|
+
remainder = remainder[p..-1]
|
102
|
+
end
|
103
|
+
|
104
|
+
return @nodes
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
def self.perform_parse(prefix, data)
|
109
|
+
stack = []
|
110
|
+
p = 0
|
111
|
+
ts = 0
|
112
|
+
te = 0
|
113
|
+
act = 0
|
114
|
+
eof = data.length
|
115
|
+
|
116
|
+
@prefix = prefix
|
117
|
+
%% write data;
|
118
|
+
%% write init;
|
119
|
+
%% write exec;
|
120
|
+
return p
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Radius
|
2
|
+
#
|
3
|
+
# A tag binding is passed into each tag definition and contains helper methods for working
|
4
|
+
# with tags. Use it to gain access to the attributes that were passed to the tag, to
|
5
|
+
# render the tag contents, and to do other tasks.
|
6
|
+
#
|
7
|
+
class TagBinding
|
8
|
+
# The Context that the TagBinding is associated with. Used internally. Try not to use
|
9
|
+
# this object directly.
|
10
|
+
attr_reader :context
|
11
|
+
|
12
|
+
# The locals object for the current tag.
|
13
|
+
attr_reader :locals
|
14
|
+
|
15
|
+
# The name of the tag (as used in a template string).
|
16
|
+
attr_reader :name
|
17
|
+
|
18
|
+
# The attributes of the tag. Also aliased as TagBinding#attr.
|
19
|
+
attr_reader :attributes
|
20
|
+
alias :attr :attributes
|
21
|
+
|
22
|
+
# The render block. When called expands the contents of the tag. Use TagBinding#expand
|
23
|
+
# instead.
|
24
|
+
attr_reader :block
|
25
|
+
|
26
|
+
# Creates a new TagBinding object.
|
27
|
+
def initialize(context, locals, name, attributes, block)
|
28
|
+
@context, @locals, @name, @attributes, @block = context, locals, name, attributes, block
|
29
|
+
end
|
30
|
+
|
31
|
+
# Evaluates the current tag and returns the rendered contents.
|
32
|
+
def expand
|
33
|
+
double? ? block.call : ''
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns true if the current tag is a single tag.
|
37
|
+
def single?
|
38
|
+
block.nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns true if the current tag is a container tag.
|
42
|
+
def double?
|
43
|
+
not single?
|
44
|
+
end
|
45
|
+
|
46
|
+
# The globals object from which all locals objects ultimately inherit their values.
|
47
|
+
def globals
|
48
|
+
@context.globals
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns a list of the way tags are nested around the current tag as a string.
|
52
|
+
def nesting
|
53
|
+
@context.current_nesting
|
54
|
+
end
|
55
|
+
|
56
|
+
# Fires off Context#tag_missing for the current tag.
|
57
|
+
def missing!
|
58
|
+
@context.tag_missing(name, attributes, &block)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Renders the tag using the current context .
|
62
|
+
def render(tag, attributes = {}, &block)
|
63
|
+
@context.render_tag(tag, attributes, &block)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Shortcut for accessing tag.attr[key]
|
67
|
+
def [](key)
|
68
|
+
attr[key]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Radius
|
2
|
+
module TagDefinitions # :nodoc:
|
3
|
+
class TagFactory # :nodoc:
|
4
|
+
def initialize(context)
|
5
|
+
@context = context
|
6
|
+
end
|
7
|
+
|
8
|
+
def define_tag(name, options, &block)
|
9
|
+
options = prepare_options(name, options)
|
10
|
+
validate_params(name, options, &block)
|
11
|
+
construct_tag_set(name, options, &block)
|
12
|
+
expose_methods_as_tags(name, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
# Adds the tag definition to the context. Override in subclasses to add additional tags
|
18
|
+
# (child tags) when the tag is created.
|
19
|
+
def construct_tag_set(name, options, &block)
|
20
|
+
if block
|
21
|
+
@context.definitions[name.to_s] = block
|
22
|
+
else
|
23
|
+
lp = last_part(name)
|
24
|
+
@context.define_tag(name) do |tag|
|
25
|
+
if tag.single?
|
26
|
+
options[:for]
|
27
|
+
else
|
28
|
+
tag.locals.send("#{ lp }=", options[:for]) unless options[:for].nil?
|
29
|
+
tag.expand
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Normalizes options pased to tag definition. Override in decendants to preform
|
36
|
+
# additional normalization.
|
37
|
+
def prepare_options(name, options)
|
38
|
+
options = Utility.symbolize_keys(options)
|
39
|
+
options[:expose] = expand_array_option(options[:expose])
|
40
|
+
object = options[:for]
|
41
|
+
options[:attributes] = object.respond_to?(:attributes) unless options.has_key? :attributes
|
42
|
+
options[:expose] += object.attributes.keys if options[:attributes]
|
43
|
+
options
|
44
|
+
end
|
45
|
+
|
46
|
+
# Validates parameters passed to tag definition. Override in decendants to add custom
|
47
|
+
# validations.
|
48
|
+
def validate_params(name, options, &block)
|
49
|
+
unless options.has_key? :for
|
50
|
+
raise ArgumentError.new("tag definition must contain a :for option or a block") unless block
|
51
|
+
raise ArgumentError.new("tag definition must contain a :for option when used with the :expose option") unless options[:expose].empty?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Exposes the methods of an object as child tags.
|
56
|
+
def expose_methods_as_tags(name, options)
|
57
|
+
options[:expose].each do |method|
|
58
|
+
tag_name = "#{name}:#{method}"
|
59
|
+
lp = last_part(name)
|
60
|
+
@context.define_tag(tag_name) do |tag|
|
61
|
+
object = tag.locals.send(lp)
|
62
|
+
object.send(method)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def expand_array_option(value)
|
70
|
+
[*value].compact.map { |m| m.to_s.intern }
|
71
|
+
end
|
72
|
+
|
73
|
+
def last_part(name)
|
74
|
+
name.split(':').last
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Radius
|
2
|
+
module Utility # :nodoc:
|
3
|
+
def self.symbolize_keys(hash)
|
4
|
+
new_hash = {}
|
5
|
+
hash.keys.each do |k|
|
6
|
+
new_hash[k.to_s.intern] = hash[k]
|
7
|
+
end
|
8
|
+
new_hash
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.impartial_hash_delete(hash, key)
|
12
|
+
string = key.to_s
|
13
|
+
symbol = string.intern
|
14
|
+
value1 = hash.delete(symbol)
|
15
|
+
value2 = hash.delete(string)
|
16
|
+
value1 || value2
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.constantize(camelized_string)
|
20
|
+
raise "invalid constant name `#{camelized_string}'" unless camelized_string.split('::').all? { |part| part =~ /^[A-Za-z]+$/ }
|
21
|
+
Object.module_eval(camelized_string)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.camelize(underscored_string)
|
25
|
+
string = ''
|
26
|
+
underscored_string.split('_').each { |part| string << part.capitalize }
|
27
|
+
string
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/tasks/scan.rake
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
namespace :scan do
|
2
|
+
desc 'Generate the parser'
|
3
|
+
task 'build' => ['lib/radius/parser/scan.rb']
|
4
|
+
|
5
|
+
desc 'Generate a PDF state graph from the parser'
|
6
|
+
task 'graph' => ['doc/scan.pdf']
|
7
|
+
|
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|
|
10
|
+
cd 'lib/radius/parser' do
|
11
|
+
sh "ragel -R scan.rl"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'pdf of the ragel scanner'
|
16
|
+
file 'doc/scan.pdf' => 'lib/radius/parser/scan.dot' do |t|
|
17
|
+
cd 'lib/radius/parser' do
|
18
|
+
sh "dot -Tpdf -o ../../../doc/scan.pdf scan.dot"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
file 'lib/radius/parser/scan.dot' => ['lib/radius/parser/scan.rl'] do |t|
|
23
|
+
cd 'lib/radius/parser' do
|
24
|
+
sh "ragel -Vp scan.rl > scan.dot"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class RadiusContextTest < Test::Unit::TestCase
|
4
|
+
include RadiusTestHelper
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@context = new_context
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_initialize
|
11
|
+
@context = Radius::Context.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_initialize_with_block
|
15
|
+
@context = Radius::Context.new do |c|
|
16
|
+
assert_kind_of Radius::Context, c
|
17
|
+
c.define_tag('test') { 'just a test' }
|
18
|
+
end
|
19
|
+
assert_not_equal Hash.new, @context.definitions
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_with
|
23
|
+
got = @context.with do |c|
|
24
|
+
assert_equal @context, c
|
25
|
+
end
|
26
|
+
assert_equal @context, got
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_render_tag
|
30
|
+
define_tag "hello" do |tag|
|
31
|
+
"Hello #{tag.attr['name'] || 'World'}!"
|
32
|
+
end
|
33
|
+
assert_render_tag_output 'Hello World!', 'hello'
|
34
|
+
assert_render_tag_output 'Hello John!', 'hello', 'name' => 'John'
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_render_tag__undefined_tag
|
38
|
+
e = assert_raises(Radius::UndefinedTagError) { @context.render_tag('undefined_tag') }
|
39
|
+
assert_equal "undefined tag `undefined_tag'", e.message
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_tag_missing
|
43
|
+
class << @context
|
44
|
+
def tag_missing(tag, attr, &block)
|
45
|
+
"undefined tag `#{tag}' with attributes #{attr.inspect}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
text = ''
|
50
|
+
expected = %{undefined tag `undefined_tag' with attributes {"cool"=>"beans"}}
|
51
|
+
assert_nothing_raised { text = @context.render_tag('undefined_tag', 'cool' => 'beans') }
|
52
|
+
assert_equal expected, text
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def assert_render_tag_output(output, *render_tag_params)
|
58
|
+
assert_equal output, @context.render_tag(*render_tag_params)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -1,83 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'radius'
|
3
|
-
|
4
|
-
module RadiusTestHelper
|
5
|
-
class TestContext < Radius::Context; end
|
6
|
-
|
7
|
-
def new_context
|
8
|
-
Radius::Context.new do |c|
|
9
|
-
c.define_tag("reverse" ) { |tag| tag.expand.reverse }
|
10
|
-
c.define_tag("capitalize") { |tag| tag.expand.upcase }
|
11
|
-
c.define_tag("attr" ) { |tag| tag.attr.inspect }
|
12
|
-
c.define_tag("echo" ) { |tag| tag.attr['value'] }
|
13
|
-
c.define_tag("wrap" ) { |tag| "[#{tag.expand}]" }
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def define_tag(name, options = {}, &block)
|
18
|
-
@context.define_tag name, options, &block
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class RadiusContextTest < Test::Unit::TestCase
|
23
|
-
include RadiusTestHelper
|
24
|
-
|
25
|
-
def setup
|
26
|
-
@context = new_context
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_initialize
|
30
|
-
@context = Radius::Context.new
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_initialize_with_block
|
34
|
-
@context = Radius::Context.new do |c|
|
35
|
-
assert_kind_of Radius::Context, c
|
36
|
-
c.define_tag('test') { 'just a test' }
|
37
|
-
end
|
38
|
-
assert_not_equal Hash.new, @context.definitions
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_with
|
42
|
-
got = @context.with do |c|
|
43
|
-
assert_equal @context, c
|
44
|
-
end
|
45
|
-
assert_equal @context, got
|
46
|
-
end
|
47
|
-
|
48
|
-
def test_render_tag
|
49
|
-
define_tag "hello" do |tag|
|
50
|
-
"Hello #{tag.attr['name'] || 'World'}!"
|
51
|
-
end
|
52
|
-
assert_render_tag_output 'Hello World!', 'hello'
|
53
|
-
assert_render_tag_output 'Hello John!', 'hello', 'name' => 'John'
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_render_tag__undefined_tag
|
57
|
-
e = assert_raises(Radius::UndefinedTagError) { @context.render_tag('undefined_tag') }
|
58
|
-
assert_equal "undefined tag `undefined_tag'", e.message
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_tag_missing
|
62
|
-
class << @context
|
63
|
-
def tag_missing(tag, attr, &block)
|
64
|
-
"undefined tag `#{tag}' with attributes #{attr.inspect}"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
text = ''
|
69
|
-
expected = %{undefined tag `undefined_tag' with attributes {"cool"=>"beans"}}
|
70
|
-
assert_nothing_raised { text = @context.render_tag('undefined_tag', 'cool' => 'beans') }
|
71
|
-
assert_equal expected, text
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
|
76
|
-
def assert_render_tag_output(output, *render_tag_params)
|
77
|
-
assert_equal output, @context.render_tag(*render_tag_params)
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
81
2
|
|
82
3
|
class RadiusParserTest < Test::Unit::TestCase
|
83
4
|
include RadiusTestHelper
|
@@ -145,6 +66,11 @@ class RadiusParserTest < Test::Unit::TestCase
|
|
145
66
|
assert_parsed_is_unchanged "<r:attr#{middle}>"
|
146
67
|
end
|
147
68
|
end
|
69
|
+
|
70
|
+
def test_tags_inside_html_tags
|
71
|
+
assert_parse_output %{<div class="xzibit">tags in yo tags</div>},
|
72
|
+
%{<div class="<r:reverse>tibizx</r:reverse>">tags in yo tags</div>}
|
73
|
+
end
|
148
74
|
|
149
75
|
def test_parse_result_is_always_a_string
|
150
76
|
define_tag("twelve") { 12 }
|
@@ -191,12 +117,23 @@ class RadiusParserTest < Test::Unit::TestCase
|
|
191
117
|
e = assert_raises(Radius::UndefinedTagError) { @parser.parse("<r:test />") }
|
192
118
|
assert_equal "undefined tag `test'", e.message
|
193
119
|
end
|
194
|
-
|
120
|
+
|
121
|
+
def test_parse_chirpy_bird
|
122
|
+
# :> chirp chirp
|
123
|
+
assert_parse_output "<:", "<:"
|
124
|
+
end
|
125
|
+
|
195
126
|
def test_parse_tag__binding_render_tag
|
196
127
|
define_tag('test') { |tag| "Hello #{tag.attr['name']}!" }
|
197
128
|
define_tag('hello') { |tag| tag.render('test', tag.attr) }
|
198
129
|
assert_parse_output 'Hello John!', '<r:hello name="John" />'
|
199
130
|
end
|
131
|
+
|
132
|
+
def test_accessing_tag_attributes_through_tag_indexer
|
133
|
+
define_tag('test') { |tag| "Hello #{tag['name']}!" }
|
134
|
+
assert_parse_output 'Hello John!', '<r:test name="John" />'
|
135
|
+
end
|
136
|
+
|
200
137
|
def test_parse_tag__binding_render_tag_with_block
|
201
138
|
define_tag('test') { |tag| "Hello #{tag.expand}!" }
|
202
139
|
define_tag('hello') { |tag| tag.render('test') { tag.expand } }
|
@@ -248,6 +185,23 @@ class RadiusParserTest < Test::Unit::TestCase
|
|
248
185
|
assert_parse_output %{Three Stooges: "Larry", "Moe", "Curly"}, %{Three Stooges: <r:each between=", ">"<r:item />"</r:each>}
|
249
186
|
end
|
250
187
|
|
188
|
+
def test_parse_speed
|
189
|
+
define_tag "set" do |tag|
|
190
|
+
tag.globals.var = tag.attr['value']
|
191
|
+
''
|
192
|
+
end
|
193
|
+
define_tag "var" do |tag|
|
194
|
+
tag.globals.var
|
195
|
+
end
|
196
|
+
parts = %w{decima nobis augue at facer processus commodo legentis odio lectorum dolore nulla esse lius qui nonummy ullamcorper erat ii notare}
|
197
|
+
multiplier = parts.map{|p| "#{p}=\"#{rand}\""}.join(' ')
|
198
|
+
assert_nothing_raised do
|
199
|
+
Timeout.timeout(10) do
|
200
|
+
assert_parse_output " false", %{<r:set value="false" #{multiplier} /> <r:var />}
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
251
205
|
def test_tag_option_for
|
252
206
|
define_tag 'fun', :for => 'just for kicks'
|
253
207
|
assert_parse_output 'just for kicks', '<r:fun />'
|
@@ -277,7 +231,22 @@ class RadiusParserTest < Test::Unit::TestCase
|
|
277
231
|
|
278
232
|
def test_parse_fail_on_missing_end_tag
|
279
233
|
assert_raises(Radius::MissingEndTagError) { @parser.parse("<r:reverse>") }
|
280
|
-
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_parse_fail_on_wrong_end_tag
|
237
|
+
assert_raises(Radius::WrongEndTagError) { @parser.parse("<r:reverse><r:capitalize></r:reverse>") }
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_parse_with_default_tag_prefix
|
241
|
+
define_tag("hello") { |tag| "Hello world!" }
|
242
|
+
@parser = Radius::Parser.new(@context)
|
243
|
+
assert_equal "<p>Hello world!</p>", @parser.parse('<p><radius:hello /></p>')
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_parse_with_other_radius_like_tags
|
247
|
+
define_tag('hello') { "hello" }
|
248
|
+
@parser = Radius::Parser.new(@context, :tag_prefix => "ralph")
|
249
|
+
assert_equal "<r:ralph:hello />", @parser.parse("<r:ralph:hello />")
|
281
250
|
end
|
282
251
|
|
283
252
|
protected
|