ZenTest 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +21 -0
- data/Manifest.txt +8 -24
- data/Rakefile +32 -8
- data/bin/autotest +4 -1
- data/bin/multiruby +20 -6
- data/bin/ruby_fork +6 -0
- data/bin/ruby_fork_client +6 -0
- data/example_dot_autotest.rb +148 -0
- data/lib/autotest.rb +201 -254
- data/lib/rails_autotest.rb +48 -110
- data/lib/ruby_fork.rb +178 -0
- data/lib/test/rails.rb +2 -2
- data/lib/test/rails/controller_test_case.rb +1 -1
- data/lib/test/rails/helper_test_case.rb +60 -0
- data/lib/test/rails/pp_html_document.rb +74 -0
- data/lib/test/rails/rake_tasks.rb +13 -12
- data/lib/test/rails/view_test_case.rb +2 -2
- data/lib/test/zentest_assertions.rb +39 -0
- data/lib/unit_diff.rb +6 -3
- data/lib/zentest.rb +1 -1
- data/test/test_autotest.rb +160 -208
- data/test/test_rails_autotest.rb +115 -138
- data/test/test_ruby_fork.rb +172 -0
- data/test/test_unit_diff.rb +69 -1
- data/test/test_zentest_assertions.rb +66 -0
- metadata +13 -27
- data/test/data/normal/lib/.#photo.rb +0 -0
- data/test/data/normal/lib/blah.rb +0 -0
- data/test/data/normal/lib/photo.rb +0 -0
- data/test/data/normal/test/#test_photo.rb# +0 -0
- data/test/data/normal/test/test_camelcase.rb +0 -0
- data/test/data/normal/test/test_photo.rb +0 -0
- data/test/data/normal/test/test_route.rb +0 -0
- data/test/data/normal/test/test_user.rb +0 -0
- data/test/data/rails/app/controllers/admin/theme_controller.rb +0 -0
- data/test/data/rails/app/controllers/route_controller.rb +0 -0
- data/test/data/rails/app/models/flickr_photo.rb +0 -0
- data/test/data/rails/app/models/route.rb +0 -0
- data/test/data/rails/app/views/route/index.rhtml +0 -0
- data/test/data/rails/config/environment.rb +0 -0
- data/test/data/rails/config/routes.rb +0 -0
- data/test/data/rails/test/controllers/route_controller_test.rb +0 -0
- data/test/data/rails/test/fixtures/routes.yml +0 -0
- data/test/data/rails/test/functional/admin/themes_controller_test.rb +0 -0
- data/test/data/rails/test/functional/dummy_controller_test.rb +0 -0
- data/test/data/rails/test/functional/route_controller_test.rb +0 -0
- data/test/data/rails/test/unit/flickr_photo_test.rb +0 -0
- data/test/data/rails/test/unit/photo_test.rb +0 -0
- data/test/data/rails/test/unit/route_test.rb +0 -0
- data/test/data/rails/test/views/route_view_test.rb +0 -0
data/lib/rails_autotest.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
1
|
require 'autotest'
|
2
2
|
|
3
|
-
##
|
4
|
-
# RailsAutotest is an Autotest subclass designed for use with Rails projects.
|
5
|
-
#
|
6
|
-
# To use RailsAutotest pass the -rails flag to autotest.
|
7
|
-
|
8
3
|
class RailsAutotest < Autotest
|
9
4
|
|
10
5
|
def initialize # :nodoc:
|
@@ -12,112 +7,55 @@ class RailsAutotest < Autotest
|
|
12
7
|
@exceptions = %r%^\./(?:db|doc|log|public|script|vendor/rails)%
|
13
8
|
end
|
14
9
|
|
15
|
-
def
|
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
|
-
functional_tests << functional_test_file
|
55
|
-
when %r%^app/controllers/application.rb$% then
|
56
|
-
controller_test_file = "test/controllers/dummy_controller_test.rb"
|
57
|
-
controller_tests << controller_test_file
|
58
|
-
functional_test_file = "test/functional/dummy_controller_test.rb"
|
59
|
-
functional_tests << functional_test_file
|
60
|
-
when %r%^app/controllers/(.*)\.rb$% then
|
61
|
-
controller_test_file = "test/controllers/#{$1}_test.rb"
|
62
|
-
controller_tests << controller_test_file
|
63
|
-
functional_test_file = "test/functional/#{$1}_test.rb"
|
64
|
-
functional_tests << functional_test_file
|
65
|
-
when %r%^app/views/layouts/% then
|
66
|
-
view_test_file = "test/views/layouts_view_test.rb"
|
67
|
-
view_tests << view_test_file
|
68
|
-
when %r%^app/views/(.*)/% then
|
69
|
-
view_test_file = "test/views/#{$1}_view_test.rb"
|
70
|
-
view_tests << view_test_file
|
71
|
-
functional_test_file = "test/functional/#{$1}_controller_test.rb"
|
72
|
-
functional_tests << functional_test_file
|
73
|
-
when %r%^config/routes.rb$% then
|
74
|
-
functional_test_files = @files.keys.select do |f|
|
75
|
-
f =~ %r%^test/functional/.*_test\.rb$%
|
76
|
-
end
|
77
|
-
controller_test_files = @files.keys.select do |f|
|
78
|
-
f =~ %r%^test/controllers/.*_test\.rb$%
|
79
|
-
end
|
80
|
-
view_test_files = @files.keys.select do |f|
|
81
|
-
f =~ %r%^test/views/.*_test\.rb$%
|
82
|
-
end
|
83
|
-
controller_tests.push(*controller_test_files.sort)
|
84
|
-
view_tests.push(*view_test_files.sort)
|
85
|
-
functional_tests.push(*functional_test_files.sort)
|
86
|
-
when %r%^test/test_helper.rb$%,
|
87
|
-
%r%^config/boot.rb%,
|
88
|
-
%r%^config/database.yml%,
|
89
|
-
%r%^config/environment.rb%,
|
90
|
-
%r%^config/environments/test.rb% then
|
91
|
-
model_test_files = @files.keys.select do |f|
|
92
|
-
f =~ %r%^test/unit/.*_test\.rb$%
|
93
|
-
end
|
94
|
-
controller_test_files = @files.keys.select do |f|
|
95
|
-
f =~ %r%^test/controllers/.*_test\.rb$%
|
96
|
-
end
|
97
|
-
view_test_files = @files.keys.select do |f|
|
98
|
-
f =~ %r%^test/views/.*_test\.rb$%
|
99
|
-
end
|
100
|
-
functional_test_files = @files.keys.select do |f|
|
101
|
-
f =~ %r%^test/functional/.*_test\.rb$%
|
102
|
-
end
|
103
|
-
model_tests.push(*model_test_files.sort)
|
104
|
-
controller_tests.push(*controller_test_files.sort)
|
105
|
-
view_tests.push(*view_test_files.sort)
|
106
|
-
functional_tests.push(*functional_test_files.sort)
|
107
|
-
when %r%^vendor/%, /^Rakefile$/ then
|
108
|
-
# ignore standard rails files
|
109
|
-
else
|
110
|
-
STDERR.puts "Dunno! #{filename}" if $v or $TESTING
|
10
|
+
def tests_for_file(filename)
|
11
|
+
|
12
|
+
case filename
|
13
|
+
when %r%^test/fixtures/(.*)s.yml% then
|
14
|
+
["test/unit/#{$1}_test.rb",
|
15
|
+
"test/controllers/#{$1}_controller_test.rb",
|
16
|
+
"test/views/#{$1}_view_test.rb",
|
17
|
+
"test/functional/#{$1}_controller_test.rb"]
|
18
|
+
when %r%^test/unit/.*rb$% then
|
19
|
+
[filename]
|
20
|
+
when %r%^test/controllers/.*\.rb$% then
|
21
|
+
[filename]
|
22
|
+
when %r%^test/views/.*\.rb$% then
|
23
|
+
[filename]
|
24
|
+
when %r%^test/functional/.*\.rb$% then
|
25
|
+
[filename]
|
26
|
+
when %r%^app/models/(.*)\.rb$% then
|
27
|
+
["test/unit/#{$1}_test.rb"]
|
28
|
+
when %r%^app/helpers/application_helper.rb% then
|
29
|
+
@files.keys.select { |f|
|
30
|
+
f =~ %r%^test/(views|functional)/.*_test\.rb$%
|
31
|
+
}
|
32
|
+
when %r%^app/helpers/(.*)_helper.rb% then
|
33
|
+
["test/views/#{$1}_view_test.rb",
|
34
|
+
"test/functional/#{$1}_controller_test.rb"]
|
35
|
+
when %r%^app/controllers/application.rb$% then
|
36
|
+
["test/controllers/dummy_controller_test.rb",
|
37
|
+
"test/functional/dummy_controller_test.rb"]
|
38
|
+
when %r%^app/controllers/(.*)\.rb$% then
|
39
|
+
["test/controllers/#{$1}_test.rb",
|
40
|
+
"test/functional/#{$1}_test.rb"]
|
41
|
+
when %r%^app/views/layouts/% then
|
42
|
+
["test/views/layouts_view_test.rb"]
|
43
|
+
when %r%^app/views/(.*)/% then
|
44
|
+
["test/views/#{$1}_view_test.rb",
|
45
|
+
"test/functional/#{$1}_controller_test.rb"]
|
46
|
+
when %r%^config/routes.rb$% then
|
47
|
+
@files.keys.select do |f|
|
48
|
+
f =~ %r%^test/(controllers|views|functional)/.*_test\.rb$%
|
111
49
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
50
|
+
when %r%^test/test_helper.rb%,
|
51
|
+
%r%^config/((boot|environment(s/test)?).rb|database.yml)% then
|
52
|
+
@files.keys.select do |f|
|
53
|
+
f =~ %r%^test/(unit|controllers|views|functional)/.*_test\.rb$%
|
54
|
+
end
|
55
|
+
else
|
56
|
+
@output.puts "Dunno! #{filename}" if $TESTING
|
57
|
+
[]
|
58
|
+
end.uniq.select { |f| @files.has_key? f }
|
120
59
|
end
|
121
|
-
|
122
60
|
end
|
123
61
|
|
data/lib/ruby_fork.rb
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
module RubyFork
|
5
|
+
|
6
|
+
PORT = 9084
|
7
|
+
|
8
|
+
DEFAULT_SETTINGS = {
|
9
|
+
:requires => [],
|
10
|
+
:code => [],
|
11
|
+
:extra_paths => [],
|
12
|
+
:port => PORT,
|
13
|
+
}
|
14
|
+
|
15
|
+
def self.add_env_args(opts, settings)
|
16
|
+
opts.separator ''
|
17
|
+
opts.separator 'Process environment options:'
|
18
|
+
|
19
|
+
opts.separator ''
|
20
|
+
opts.on('-e CODE', 'Execute CODE in parent process.',
|
21
|
+
'May be specified multiple times.') do |code|
|
22
|
+
settings[:code] << code
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.separator ''
|
26
|
+
opts.on('-I DIRECTORY', 'Adds DIRECTORY to $LOAD_PATH.',
|
27
|
+
'May be specified multiple times.') do |dir|
|
28
|
+
settings[:extra_paths] << dir
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.separator ''
|
32
|
+
opts.on('-r LIBRARY', 'Require LIBRARY in the parent process.',
|
33
|
+
'May be specified multiple times.') do |lib|
|
34
|
+
settings[:requires] << lib
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.daemonize(io = File.open('/dev/null', 'r+'))
|
39
|
+
fork and exit!
|
40
|
+
Process.setsid
|
41
|
+
fork and exit!
|
42
|
+
|
43
|
+
STDIN.reopen io
|
44
|
+
STDOUT.reopen io
|
45
|
+
#STDERR.reopen io
|
46
|
+
|
47
|
+
yield if block_given?
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.parse_client_args(args)
|
51
|
+
settings = Marshal.load Marshal.dump(DEFAULT_SETTINGS)
|
52
|
+
|
53
|
+
opts = OptionParser.new do |opts|
|
54
|
+
opts.banner = "Usage: #{$0} [options]"
|
55
|
+
|
56
|
+
opts.separator ''
|
57
|
+
opts.on('-p', '--port PORT',
|
58
|
+
'Listen for connections on PORT.',
|
59
|
+
"Default: #{settings[:port]}") do |port|
|
60
|
+
settings[:port] = port.to_i
|
61
|
+
end
|
62
|
+
|
63
|
+
opts.separator ''
|
64
|
+
opts.on('-h', '--help', 'You\'re looking at it.') do
|
65
|
+
$stderr.puts opts
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
|
69
|
+
add_env_args opts, settings
|
70
|
+
end
|
71
|
+
|
72
|
+
opts.parse! args
|
73
|
+
|
74
|
+
return settings
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.parse_server_args(args)
|
78
|
+
settings = Marshal.load Marshal.dump(DEFAULT_SETTINGS)
|
79
|
+
settings[:daemonize] = false
|
80
|
+
|
81
|
+
opts = OptionParser.new do |opts|
|
82
|
+
opts.banner = "Usage: #{$0} [options]"
|
83
|
+
|
84
|
+
opts.separator ''
|
85
|
+
opts.on('-d', '--daemonize',
|
86
|
+
'Run as a daemon.',
|
87
|
+
"Default: #{settings[:daemonize]}") do |val|
|
88
|
+
settings[:daemonize] = val
|
89
|
+
end
|
90
|
+
|
91
|
+
opts.separator ''
|
92
|
+
opts.on('-p', '--port PORT',
|
93
|
+
'Listen for connections on PORT.',
|
94
|
+
"Default: #{settings[:port]}") do |port|
|
95
|
+
settings[:port] = port.to_i
|
96
|
+
end
|
97
|
+
|
98
|
+
opts.separator ''
|
99
|
+
opts.on('-h', '--help', 'You\'re looking at it.') do
|
100
|
+
$stderr.puts opts
|
101
|
+
exit 1
|
102
|
+
end
|
103
|
+
|
104
|
+
add_env_args opts, settings
|
105
|
+
end
|
106
|
+
|
107
|
+
opts.parse! args
|
108
|
+
|
109
|
+
return settings
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.start_client(args = ARGV)
|
113
|
+
trap 'INT' do exit 1 end # Exit gracefully
|
114
|
+
|
115
|
+
settings = parse_client_args args
|
116
|
+
|
117
|
+
args = Marshal.dump [settings, ARGV]
|
118
|
+
|
119
|
+
socket = TCPSocket.new 'localhost', settings[:port]
|
120
|
+
|
121
|
+
socket.puts args.length
|
122
|
+
socket.write args
|
123
|
+
socket.close_write
|
124
|
+
|
125
|
+
until socket.eof?
|
126
|
+
$stdout.puts socket.gets
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.start_server(args = ARGV)
|
131
|
+
settings = parse_server_args args
|
132
|
+
setup_environment settings
|
133
|
+
|
134
|
+
daemonize if settings[:daemonize]
|
135
|
+
|
136
|
+
server = TCPServer.new 'localhost', settings[:port]
|
137
|
+
|
138
|
+
$stderr.puts "#{$0} Running as PID #{$$} on #{settings[:port]}" unless
|
139
|
+
settings[:daemonize]
|
140
|
+
|
141
|
+
loop do
|
142
|
+
Thread.new server.accept do |socket|
|
143
|
+
begin
|
144
|
+
args_length = socket.gets.to_i
|
145
|
+
args = socket.read args_length
|
146
|
+
settings, argv = Marshal.load args
|
147
|
+
|
148
|
+
fork do
|
149
|
+
daemonize socket do
|
150
|
+
ARGV.replace argv
|
151
|
+
setup_environment settings
|
152
|
+
socket.close
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
socket.close # close my copy.
|
157
|
+
rescue => e
|
158
|
+
socket.close if socket
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
rescue Exception => e
|
163
|
+
puts "Failed to catch #{e.class}:#{e.message}"
|
164
|
+
puts "\t#{e.backtrace.join "\n\t"}"
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.setup_environment(settings)
|
168
|
+
settings[:extra_paths].map! { |dir| dir.split ':' }
|
169
|
+
settings[:extra_paths].flatten!
|
170
|
+
settings[:extra_paths].each { |dir| $:.unshift dir }
|
171
|
+
|
172
|
+
settings[:requires].each { |file| require file }
|
173
|
+
|
174
|
+
settings[:code].each { |code| eval code }
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
data/lib/test/rails.rb
CHANGED
@@ -37,8 +37,7 @@ $TESTING = true
|
|
37
37
|
# require 'test/rails'
|
38
38
|
#
|
39
39
|
# Next, change the class from "Unit" to "Rails" right after you
|
40
|
-
# require +test_help+.
|
41
|
-
# upon Test::Unit::TestCase.
|
40
|
+
# require +test_help+.
|
42
41
|
#
|
43
42
|
# Your 'test/test_helper.rb' will end up looking like this:
|
44
43
|
#
|
@@ -262,6 +261,7 @@ require 'test/zentest_assertions'
|
|
262
261
|
require 'test/rails/test_case'
|
263
262
|
require 'test/rails/functional_test_case'
|
264
263
|
require 'test/rails/controller_test_case'
|
264
|
+
require 'test/rails/helper_test_case'
|
265
265
|
require 'test/rails/ivar_proxy'
|
266
266
|
require 'test/rails/view_test_case'
|
267
267
|
|
@@ -199,7 +199,7 @@ class Test::Rails::ControllerTestCase < Test::Rails::FunctionalTestCase
|
|
199
199
|
# +params+.
|
200
200
|
|
201
201
|
def xml_http_request(request_method, action, parameters = nil)
|
202
|
-
@request.env['REQUEST_METHOD'] = request_method
|
202
|
+
@request.env['REQUEST_METHOD'] = request_method.to_s
|
203
203
|
|
204
204
|
@request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
|
205
205
|
@request.env['HTTP_ACCEPT'] = 'text/javascript, text/html, application/xml, text/xml, */*'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
##
|
2
|
+
# Stub controller for testing helpers.
|
3
|
+
|
4
|
+
class HelperTestCaseController < ApplicationController
|
5
|
+
|
6
|
+
attr_accessor :request
|
7
|
+
|
8
|
+
attr_accessor :url
|
9
|
+
|
10
|
+
##
|
11
|
+
# Re-raise errors
|
12
|
+
|
13
|
+
def rescue_action(e)
|
14
|
+
raise e
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# HelperTestCase allows helpers to be easily tested.
|
21
|
+
#
|
22
|
+
# Original concept by Ryan Davis, original implementation by Geoff Grosenbach.
|
23
|
+
|
24
|
+
class Test::Rails::HelperTestCase < Test::Rails::FunctionalTestCase
|
25
|
+
|
26
|
+
# Are other helpers needed?
|
27
|
+
|
28
|
+
include ActionView::Helpers::ActiveRecordHelper
|
29
|
+
include ActionView::Helpers::TagHelper
|
30
|
+
include ActionView::Helpers::FormTagHelper
|
31
|
+
include ActionView::Helpers::FormOptionsHelper
|
32
|
+
include ActionView::Helpers::FormHelper
|
33
|
+
include ActionView::Helpers::UrlHelper
|
34
|
+
include ActionView::Helpers::AssetTagHelper
|
35
|
+
include ActionView::Helpers::PrototypeHelper rescue nil # Rails 1.0 only
|
36
|
+
|
37
|
+
##
|
38
|
+
# Automatically includes the helper module into the test sublcass.
|
39
|
+
|
40
|
+
def self.inherited(helper_testcase)
|
41
|
+
super
|
42
|
+
helper_name = helper_testcase.name.sub 'Test', ''
|
43
|
+
helper_module = Object.const_get helper_name
|
44
|
+
helper_testcase.send :include, helper_module
|
45
|
+
rescue NameError
|
46
|
+
raise "Unable to find helper #{helper_name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def setup
|
50
|
+
return if self.class.name =~ /TestCase$/
|
51
|
+
@controller_class_name = 'HelperTestCaseController'
|
52
|
+
super
|
53
|
+
@controller.request = @request
|
54
|
+
@controller.url = ActionController::UrlRewriter.new @request, {} # url_for
|
55
|
+
|
56
|
+
ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class HTML::Document
|
2
|
+
def pretty_print(q)
|
3
|
+
q.object_address_group self do
|
4
|
+
q.breakable
|
5
|
+
q.seplist @root.children_without_newlines do |v| q.pp v end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class HTML::Node
|
11
|
+
def children_without_newlines
|
12
|
+
@children.reject do |c|
|
13
|
+
HTML::Text == c.class and c.content_without_whitespace == "\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def pretty_print(q)
|
18
|
+
q.group 1, '[NODE ', ']' do
|
19
|
+
q.breakable
|
20
|
+
q.seplist children_without_newlines do |v| q.pp v end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class HTML::Tag
|
26
|
+
def pretty_print(q)
|
27
|
+
case @closing
|
28
|
+
when :close then
|
29
|
+
q.text "[close #{@name}]"
|
30
|
+
when :self then
|
31
|
+
pretty_print_tag 'empty', q
|
32
|
+
when nil then
|
33
|
+
pretty_print_tag 'open ', q
|
34
|
+
else
|
35
|
+
raise "Unknown closing #{@closing.inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def pretty_print_tag(type, q)
|
40
|
+
q.group 1, "(#{type} #{@name.inspect}", ')' do
|
41
|
+
unless @attributes.empty? then
|
42
|
+
q.breakable
|
43
|
+
q.pp @attributes
|
44
|
+
end
|
45
|
+
unless children_without_newlines.empty? then
|
46
|
+
q.breakable
|
47
|
+
q.group 1, '[', ']' do
|
48
|
+
q.seplist children_without_newlines do |v|
|
49
|
+
q.pp v
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class HTML::Text
|
58
|
+
def content_without_whitespace
|
59
|
+
@content.gsub(/^[ ]+/, '').sub(/[ ]+\Z/, '')
|
60
|
+
end
|
61
|
+
|
62
|
+
def pretty_print(q)
|
63
|
+
q.pp content_without_whitespace
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class HTML::CDATA
|
68
|
+
def pretty_print(q)
|
69
|
+
q.group 1, '[', ']' do
|
70
|
+
q.pp @content
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|