nitro 0.20.0 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +752 -543
- data/INSTALL +38 -38
- data/README +264 -225
- data/Rakefile +48 -49
- data/bin/nitro +3 -3
- data/bin/nitrogen +6 -6
- data/doc/AUTHORS +10 -10
- data/doc/CHANGELOG.1 +1939 -1939
- data/doc/CHANGELOG.2 +954 -954
- data/doc/LICENSE +3 -3
- data/doc/MIGRATION +28 -0
- data/doc/RELEASES +814 -643
- data/doc/config.txt +5 -5
- data/install.rb +7 -17
- data/lib/nitro.rb +38 -9
- data/lib/nitro/adapter/cgi.rb +311 -312
- data/lib/nitro/adapter/fastcgi.rb +18 -25
- data/lib/nitro/adapter/webrick.rb +128 -137
- data/lib/nitro/adapter/wee.rb +51 -0
- data/lib/nitro/caching.rb +20 -20
- data/lib/nitro/caching/actions.rb +43 -43
- data/lib/nitro/caching/fragments.rb +46 -46
- data/lib/nitro/caching/invalidation.rb +11 -11
- data/lib/nitro/caching/output.rb +65 -65
- data/lib/nitro/caching/stores.rb +67 -67
- data/lib/nitro/compiler.rb +262 -0
- data/lib/nitro/compiler/elements.rb +0 -0
- data/lib/nitro/compiler/errors.rb +65 -0
- data/lib/nitro/compiler/localization.rb +25 -0
- data/lib/nitro/compiler/markup.rb +19 -0
- data/lib/nitro/compiler/shaders.rb +206 -0
- data/lib/nitro/compiler/squeeze.rb +20 -0
- data/lib/nitro/compiler/xslt.rb +61 -0
- data/lib/nitro/context.rb +87 -88
- data/lib/nitro/controller.rb +151 -158
- data/lib/nitro/cookie.rb +34 -34
- data/lib/nitro/dispatcher.rb +195 -186
- data/lib/nitro/element.rb +132 -126
- data/lib/nitro/element/java_script.rb +6 -6
- data/lib/nitro/flash.rb +66 -66
- data/lib/nitro/mail.rb +192 -192
- data/lib/nitro/mixin/buffer.rb +66 -0
- data/lib/nitro/mixin/debug.rb +16 -16
- data/lib/nitro/mixin/form.rb +88 -0
- data/lib/nitro/mixin/helper.rb +2 -2
- data/lib/nitro/mixin/javascript.rb +108 -108
- data/lib/nitro/mixin/markup.rb +144 -0
- data/lib/nitro/mixin/pager.rb +202 -202
- data/lib/nitro/mixin/rss.rb +67 -0
- data/lib/nitro/mixin/table.rb +63 -0
- data/lib/nitro/mixin/xhtml.rb +75 -0
- data/lib/nitro/mixin/xml.rb +124 -0
- data/lib/nitro/render.rb +183 -359
- data/lib/nitro/request.rb +140 -140
- data/lib/nitro/response.rb +27 -27
- data/lib/nitro/routing.rb +21 -21
- data/lib/nitro/scaffold.rb +124 -118
- data/lib/nitro/server.rb +117 -80
- data/lib/nitro/server/runner.rb +341 -0
- data/lib/nitro/service.rb +12 -12
- data/lib/nitro/service/xmlrpc.rb +22 -22
- data/lib/nitro/session.rb +122 -120
- data/lib/nitro/session/drb.rb +9 -9
- data/lib/nitro/session/drbserver.rb +34 -34
- data/lib/nitro/template.rb +171 -155
- data/lib/nitro/testing/assertions.rb +90 -90
- data/lib/nitro/testing/context.rb +16 -16
- data/lib/nitro/testing/testcase.rb +34 -34
- data/proto/conf/lhttpd.conf +9 -9
- data/proto/public/error.xhtml +75 -75
- data/proto/public/index.xhtml +18 -18
- data/proto/public/js/behaviour.js +65 -65
- data/proto/public/js/controls.js +1 -1
- data/proto/public/js/prototype.js +3 -3
- data/proto/public/settings.xhtml +61 -61
- data/proto/run.rb +1 -5
- data/test/nitro/adapter/raw_post1.bin +0 -0
- data/test/nitro/adapter/tc_cgi.rb +57 -57
- data/test/nitro/adapter/tc_webrick.rb +4 -4
- data/test/nitro/mixin/tc_pager.rb +25 -25
- data/test/nitro/mixin/tc_rss.rb +24 -0
- data/test/nitro/mixin/tc_table.rb +31 -0
- data/test/nitro/mixin/tc_xhtml.rb +13 -0
- data/test/nitro/tc_caching.rb +10 -10
- data/test/nitro/tc_context.rb +8 -8
- data/test/nitro/tc_controller.rb +48 -48
- data/test/nitro/tc_cookie.rb +6 -6
- data/test/nitro/tc_dispatcher.rb +64 -64
- data/test/nitro/tc_element.rb +27 -27
- data/test/nitro/tc_flash.rb +31 -31
- data/test/nitro/tc_mail.rb +63 -63
- data/test/nitro/tc_server.rb +26 -26
- data/test/nitro/tc_session.rb +9 -9
- data/test/nitro/tc_template.rb +19 -19
- data/test/public/blog/list.xhtml +1 -1
- metadata +31 -37
- data/lib/nitro/buffering.rb +0 -45
- data/lib/nitro/builder/form.rb +0 -104
- data/lib/nitro/builder/rss.rb +0 -104
- data/lib/nitro/builder/table.rb +0 -80
- data/lib/nitro/builder/xhtml.rb +0 -132
- data/lib/nitro/builder/xml.rb +0 -131
- data/lib/nitro/conf.rb +0 -36
- data/lib/nitro/environment.rb +0 -21
- data/lib/nitro/errors.rb +0 -69
- data/lib/nitro/localization.rb +0 -153
- data/lib/nitro/markup.rb +0 -147
- data/lib/nitro/output.rb +0 -24
- data/lib/nitro/runner.rb +0 -348
- data/lib/nitro/shaders.rb +0 -206
- data/test/nitro/builder/tc_rss.rb +0 -23
- data/test/nitro/builder/tc_table.rb +0 -30
- data/test/nitro/builder/tc_xhtml.rb +0 -39
- data/test/nitro/builder/tc_xml.rb +0 -56
- data/test/nitro/tc_localization.rb +0 -49
data/lib/nitro/template.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'glue/flexob'
|
2
|
+
require 'glue/configuration'
|
2
3
|
|
3
4
|
module Nitro
|
4
5
|
|
@@ -9,131 +10,131 @@ module Nitro
|
|
9
10
|
|
10
11
|
module TemplateMixin
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
13
|
+
# Convert a template to actual Ruby code, ready to be
|
14
|
+
# evaluated.
|
15
|
+
#
|
16
|
+
# [+template+]
|
17
|
+
# The template as a String.
|
18
|
+
#
|
19
|
+
# [+buffer+]
|
20
|
+
# The variable to act as a buffer where the ruby code
|
21
|
+
# for this template will be generated. Passed as a|
|
22
|
+
# String.
|
23
|
+
#
|
24
|
+
# [+base_dir+]
|
25
|
+
# The base directory where the templates reside.
|
26
|
+
|
27
|
+
def compile_template(template, buffer = '@out', base_dir = Dir.pwd)
|
28
|
+
text = template.dup
|
29
|
+
|
30
|
+
# Strip the xml header! (interracts with the following gsub!)
|
31
|
+
text.gsub!(/<\?xml.*\?>/, "")
|
32
|
+
|
33
|
+
# Statically include sub-template files.
|
34
|
+
# The target file is included at compile time.
|
35
|
+
#
|
36
|
+
# gmosx: must be xformed before the <?r pi.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
# <?include href="root/myfile.sx" ?>
|
40
|
+
|
41
|
+
text.gsub!(/<\?include href=["|'](.*?)["|'](.*)\?>/) do |match|
|
42
|
+
text = File.read("#{base_dir}/#$1")
|
43
|
+
text.gsub!(/<\?xml.*\?>/, '')
|
44
|
+
text.gsub!(/<\/?root(.*?)>/m, ' ');
|
45
|
+
text
|
46
|
+
end
|
47
|
+
|
48
|
+
# Transform include instructions <include href="xxx" />
|
49
|
+
# must be transformed before the processinc instructions.
|
50
|
+
# Useful to include fragments cached on disk
|
51
|
+
#
|
52
|
+
# gmosx, FIXME: NOT TESTED! test and add caching.
|
53
|
+
# add load_statically_included fixes.
|
54
|
+
|
55
|
+
text.gsub!(/<include href=["|'](.*?)["|'](.*)(.?)\/>/) do |match|
|
56
|
+
"<?r File.read( '\#\{@dispatcher.root\}/#$1' ?>"
|
57
|
+
end
|
58
|
+
|
59
|
+
# xform render/inject instructions <render href="xxx" />
|
60
|
+
# must be transformed before the processinc instructions.
|
61
|
+
|
62
|
+
text.gsub!(/<inject href=["|'](.*?)["|'](.*)(.?)\/>/) do |match|
|
63
|
+
"<?r render '/#$1' ?>"
|
64
|
+
end
|
65
|
+
|
66
|
+
text.gsub!(/<render href=["|'](.*?)["|'](.*)(.?)\/>/) do |match|
|
67
|
+
"<?r render '/#$1' ?>"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Remove <root> elements. typically removed by xslt but lets
|
71
|
+
# play it safe. The <root> element is typically added to
|
72
|
+
# template files to make them XHTML valid.
|
73
|
+
|
74
|
+
text.gsub!(/<(\/)?root>/, '')
|
75
|
+
|
76
|
+
# Transform the processing instructions, use <?r as
|
77
|
+
# a marker.
|
78
|
+
|
79
|
+
text.gsub!(/\?>/, "; #{buffer} << %^")
|
80
|
+
text.gsub!(/<\?r(\s?)/, "^; ")
|
81
|
+
|
82
|
+
# Transform alternative code tags.
|
83
|
+
# (very useful in xsl stylesheets)
|
84
|
+
|
85
|
+
text.gsub!(/<\/ruby>/, "; #{buffer} << %^")
|
86
|
+
text.gsub!(/<ruby>/, "^; ")
|
87
|
+
|
88
|
+
# Also handle erb/asp/jsp style tags. Those tags
|
89
|
+
# *cannot* be used with an xslt stylesheet.
|
90
|
+
|
91
|
+
text.gsub!(/%>/, "; #{buffer} << %^")
|
92
|
+
text.gsub!(/<%/, "^; ")
|
93
|
+
|
94
|
+
# Alterative versions of interpolation.
|
95
|
+
# (very useful in xsl stylesheets)
|
96
|
+
# Example: #\my_val\
|
97
|
+
|
98
|
+
text.gsub!(/\#\\(.*?)\\/, '#{\1}')
|
99
|
+
|
100
|
+
# Alternative for entities.
|
101
|
+
# (useful in xsl stylesheets)
|
102
|
+
# Examples: %nbsp;, %rquo;
|
103
|
+
|
104
|
+
text.gsub!(/%(\S*?);/, '&\1;')
|
105
|
+
|
106
|
+
# Compile time ruby code. This code is evaluated when
|
107
|
+
# compiling the template and the result injected directly
|
108
|
+
# into the result. Usefull for example to prevaluate
|
109
|
+
# localization. Just use the #[] marker instead of #{}.
|
110
|
+
|
111
|
+
text.gsub!(/\#\[(.*?)\]/) do |match|
|
112
|
+
eval($1)
|
113
|
+
end
|
114
|
+
|
115
|
+
text = "#{buffer} << %^" + text + "^"
|
116
|
+
|
117
|
+
return text
|
118
|
+
end
|
119
|
+
|
120
|
+
# Render the template.
|
121
|
+
#
|
122
|
+
# [+ruby+]
|
123
|
+
# A String containing the compiled template
|
124
|
+
# code.
|
125
|
+
#
|
126
|
+
# [+binding+]
|
127
|
+
# The evaluation binding for the rendering.
|
128
|
+
|
129
|
+
def render_template(ruby, the_binding = nil)
|
130
|
+
eval(ruby, the_binding)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Compile and render the template.
|
134
|
+
|
135
|
+
def process_template(template, buffer = '@out', the_binding = nil)
|
136
|
+
render_template(compile_template(template, buffer), the_binding)
|
137
|
+
end
|
137
138
|
|
138
139
|
end
|
139
140
|
|
@@ -141,12 +142,27 @@ end
|
|
141
142
|
# as singleton methods.
|
142
143
|
|
143
144
|
class Template
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
145
|
+
|
146
|
+
# The default root directory where template files reside.
|
147
|
+
|
148
|
+
setting :root, :default => 'public', :doc => 'The default root directory where template files reside'
|
149
|
+
|
150
|
+
# The default template name.
|
151
|
+
|
152
|
+
setting :default, :default => 'index', :doc => 'The default template name'
|
153
|
+
|
154
|
+
# The default template file extension.
|
155
|
+
|
156
|
+
setting :extension, :default => 'xhtml', :doc => 'The default template file extension'
|
157
|
+
|
158
|
+
class << self
|
159
|
+
include TemplateMixin
|
160
|
+
alias_method :compile, :compile_template
|
161
|
+
alias_method :transform, :compile_template
|
162
|
+
alias_method :render, :render_template
|
163
|
+
alias_method :process, :process_template
|
164
|
+
end
|
165
|
+
|
150
166
|
end
|
151
167
|
|
152
168
|
# A Template that reads from files and also
|
@@ -155,30 +171,30 @@ end
|
|
155
171
|
# expansion environment.
|
156
172
|
|
157
173
|
class FileTemplate < Flexob
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
174
|
+
include TemplateMixin
|
175
|
+
|
176
|
+
@@compiled_template_cache = {}
|
177
|
+
|
178
|
+
attr_accessor :template_filename
|
179
|
+
|
180
|
+
def initialize(filename = nil)
|
181
|
+
super
|
182
|
+
@template_filename = filename
|
183
|
+
end
|
184
|
+
|
185
|
+
def process
|
186
|
+
__out__ = ''
|
187
|
+
|
188
|
+
unless compiled = @@compiled_template_cache[@template_filename]
|
189
|
+
template = File.read(@template_filename)
|
190
|
+
compiled = compile_template(template, '__out__')
|
191
|
+
@@compiled_template_cache[@template_filename] = compiled
|
192
|
+
end
|
193
|
+
|
194
|
+
render_template(compiled, binding)
|
195
|
+
|
196
|
+
return __out__
|
197
|
+
end
|
182
198
|
end
|
183
199
|
|
184
200
|
end
|
@@ -4,96 +4,96 @@ require 'rexml/document'
|
|
4
4
|
|
5
5
|
module Test::Unit::Assertions
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
7
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
8
|
+
# :section: General assertions.
|
9
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
10
|
+
|
11
|
+
def assert_status_ok(msg = nil)
|
12
|
+
msg = format_msg("Status not ok", msg)
|
13
|
+
assert_block(msg) { @context.status_ok? }
|
14
|
+
end
|
15
|
+
|
16
|
+
def assert_output_match(re, msg = nil)
|
17
|
+
msg = format_msg("Rendered output does not match '#{re}'", msg)
|
18
|
+
assert_block(msg) { @context.out =~ Regexp.new(re) }
|
19
|
+
end
|
20
|
+
alias_method :assert_output_contains, :assert_output_match
|
21
|
+
|
22
|
+
def assert_output_no_match(re, msg = nil)
|
23
|
+
msg = format_msg("Rendered output matches '#{re}'", msg)
|
24
|
+
assert_block(msg) { @context.out =~ Regexp.new(re) }
|
25
|
+
end
|
26
|
+
alias_method :assert_output_contains_no, :assert_output_no_match
|
27
|
+
|
28
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
29
|
+
# :section: Session related assertions.
|
30
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
31
|
+
|
32
|
+
def assert_session_has(key, msg = nil)
|
33
|
+
msg = format_msg("Object '#{key}' not found in session", msg)
|
34
|
+
assert_block(msg) { @context.session[key] }
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_session_has_no(key, msg = nil)
|
38
|
+
msg = format_msg("Unexpected object '#{key}' found in session", msg)
|
39
|
+
assert_block(msg) { !@context.session[key] }
|
40
|
+
end
|
41
|
+
alias_method :assert_session_has_not, :assert_session_has_no
|
42
|
+
|
43
|
+
def assert_session_equal(key, value, msg = nil)
|
44
|
+
msg = format_msg("The value of session object '#{key}' is '#{@context.session[key]}' but was expected '#{value}'", msg)
|
45
|
+
assert_block(msg) { @context.session[key] == value }
|
46
|
+
end
|
47
|
+
|
48
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
49
|
+
# :section: Cookies related assertions.
|
50
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
51
|
+
|
52
|
+
def assert_has_cookie(name, msg = nil)
|
53
|
+
msg = format_msg("Cookie '#{name}' not found", msg)
|
54
|
+
assert_block(msg) { @context.response_cookie(name) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def assert_has_no_cookie(name, msg = nil)
|
58
|
+
msg = format_msg("Unexpected cookie '#{name}' found", msg)
|
59
|
+
assert_block(msg) { !@context.response_cookie(name) }
|
60
|
+
end
|
61
|
+
|
62
|
+
def assert_cookie_equal(name, value, msg = nil)
|
63
|
+
unless cookie = @context.response_cookie(name)
|
64
|
+
msg = format_msg("Cookie '#{name}' not found", msg)
|
65
|
+
assert_block(msg) { false }
|
66
|
+
end
|
67
|
+
msg = format_msg("The value of cookie '#{name}' is '#{cookie.value}' but was expected '#{value}'", msg)
|
68
|
+
assert_block(msg) { cookie.value == value }
|
69
|
+
end
|
70
|
+
|
71
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
72
|
+
# :section: Template related assertions.
|
73
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
74
|
+
|
75
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
76
|
+
# :section: Redirection assertions.
|
77
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
78
|
+
|
79
|
+
def assert_redirect(msg = nil)
|
80
|
+
msg = format_msg("No redirection (status = #{@context.status})", msg)
|
81
|
+
assert_block(msg) { @context.redirect? }
|
82
|
+
end
|
83
|
+
|
84
|
+
def assert_no_redirect(msg = nil)
|
85
|
+
msg = format_msg("Unexpected redirection (location = '#{@context.response_headers['location']}')", msg)
|
86
|
+
assert_block(msg) { !@context.redirect? }
|
87
|
+
end
|
88
|
+
|
89
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
90
|
+
# :section: Utility methods
|
91
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
92
|
+
|
93
|
+
def format_msg(message, extra) # :nodoc:
|
94
|
+
extra += ', ' if extra
|
95
|
+
return "#{extra}#{message}"
|
96
|
+
end
|
97
97
|
|
98
98
|
end
|
99
99
|
|