ZenTest 3.2.0 → 3.3.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.
- 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
|
+
|