adamh-html_render 0.0.1 → 0.0.2
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/Manifest +2 -0
- data/Rakefile +1 -1
- data/html_render.gemspec +8 -6
- data/lib/html_render/images.rb +2 -1
- data/lib/html_render/render_test/rails.rb +99 -0
- data/lib/html_render/render_test.rb +194 -0
- data/lib/html_render/renderers.rb +7 -2
- data/lib/html_render.rb +1 -0
- metadata +7 -3
data/Manifest
CHANGED
data/Rakefile
CHANGED
data/html_render.gemspec
CHANGED
@@ -1,27 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
1
3
|
Gem::Specification.new do |s|
|
2
4
|
s.name = %q{html_render}
|
3
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.2"
|
4
6
|
|
5
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
6
8
|
s.authors = ["Adam Hooper"]
|
7
|
-
s.date = %q{2009-
|
9
|
+
s.date = %q{2009-04-01}
|
8
10
|
s.description = %q{Make images from HTML strings}
|
9
11
|
s.email = %q{adam@adamhooper.com}
|
10
|
-
s.extra_rdoc_files = ["README.rdoc", "lib/html_render.rb", "lib/html_render/render_batches.rb", "lib/html_render/renderers.rb", "lib/html_render/images.rb"]
|
11
|
-
s.files = ["README.rdoc", "Rakefile", "html_render.gemspec", "lib/html_render.rb", "lib/html_render/render_batches.rb", "lib/html_render/renderers.rb", "lib/html_render/images.rb", "Manifest"]
|
12
|
+
s.extra_rdoc_files = ["README.rdoc", "lib/html_render.rb", "lib/html_render/render_batches.rb", "lib/html_render/renderers.rb", "lib/html_render/images.rb", "lib/html_render/render_test.rb", "lib/html_render/render_test/rails.rb"]
|
13
|
+
s.files = ["README.rdoc", "Rakefile", "html_render.gemspec", "lib/html_render.rb", "lib/html_render/render_batches.rb", "lib/html_render/renderers.rb", "lib/html_render/images.rb", "lib/html_render/render_test.rb", "lib/html_render/render_test/rails.rb", "Manifest"]
|
12
14
|
s.has_rdoc = true
|
13
15
|
s.homepage = %q{http://adamhooper.com/eng}
|
14
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Html_render", "--main", "README.rdoc"]
|
15
17
|
s.require_paths = ["lib"]
|
16
18
|
s.rubyforge_project = %q{html_render}
|
17
|
-
s.rubygems_version = %q{1.
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
18
20
|
s.summary = %q{Make images from HTML strings}
|
19
21
|
|
20
22
|
if s.respond_to? :specification_version then
|
21
23
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
22
24
|
s.specification_version = 2
|
23
25
|
|
24
|
-
if
|
26
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
25
27
|
s.add_runtime_dependency(%q<httpclient>, [">= 2.1.4"])
|
26
28
|
s.add_runtime_dependency(%q<rmagick>, [">= 2.9.1"])
|
27
29
|
s.add_development_dependency(%q<echoe>, [">= 0"])
|
data/lib/html_render/images.rb
CHANGED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'action_controller/test_process'
|
2
|
+
require 'action_view/test_case'
|
3
|
+
|
4
|
+
require 'html_render/render_test'
|
5
|
+
|
6
|
+
module HTMLRender; end
|
7
|
+
module HTMLRender::RenderTest; end
|
8
|
+
|
9
|
+
module HTMLRender::RenderTest::Rails
|
10
|
+
class RenderTest < HTMLRender::RenderTest::DirectoryRenderTest
|
11
|
+
def initialize(*args, &block)
|
12
|
+
super(*args, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def run(*args, &block)
|
16
|
+
write_html_to_run_directory
|
17
|
+
super(*args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def html
|
21
|
+
@html ||= wrap_html { view.render(render_options) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def render_options
|
25
|
+
{
|
26
|
+
template_type => template_path,
|
27
|
+
:locals => locals
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def template_type
|
32
|
+
:partial
|
33
|
+
end
|
34
|
+
|
35
|
+
def assigns
|
36
|
+
{}
|
37
|
+
end
|
38
|
+
|
39
|
+
def locals
|
40
|
+
{}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Wraps the rendered HTML to create a fully-valid XHTML 1.0 page which
|
44
|
+
# may be rendered.
|
45
|
+
#
|
46
|
+
# Override the +css+ or +javascript+ methods to include CSS or
|
47
|
+
# JavaScript in the output. (Most Rails project testing frameworks will
|
48
|
+
# rely upon a subclass of this RenderTest with css returning the
|
49
|
+
# project's entire CSS library.)
|
50
|
+
def wrap_html
|
51
|
+
<<-EOT
|
52
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
53
|
+
<html xmlns='http://www.w3.org/1999/xhtml'>
|
54
|
+
<head>
|
55
|
+
<title>Test</title>
|
56
|
+
<style type="text/css">
|
57
|
+
#{css}
|
58
|
+
</style>
|
59
|
+
<script type="text/javascript">
|
60
|
+
#{javascript}
|
61
|
+
</script>
|
62
|
+
</head>
|
63
|
+
<body>
|
64
|
+
#{yield}
|
65
|
+
</body>
|
66
|
+
</html>
|
67
|
+
EOT
|
68
|
+
end
|
69
|
+
|
70
|
+
def css
|
71
|
+
""
|
72
|
+
end
|
73
|
+
|
74
|
+
def javascript
|
75
|
+
""
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def controller
|
81
|
+
returning(ActionView::TestCase::TestController.new) do |controller|
|
82
|
+
# Set @url so url_for() doesn't crash
|
83
|
+
request = controller.instance_variable_get(:@request)
|
84
|
+
controller.instance_variable_set(:@url, ActionController::UrlRewriter.new(request, {}))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def view
|
89
|
+
ActionView::Base.new(ActionController::Base.view_paths, assigns, controller)
|
90
|
+
end
|
91
|
+
|
92
|
+
def write_html_to_run_directory
|
93
|
+
last_run_html_file = File.join(run_path, 'html.html')
|
94
|
+
File.open(last_run_html_file, 'w') do |f|
|
95
|
+
f.write(html)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require 'html_render/images'
|
2
|
+
require 'html_render/render_batches'
|
3
|
+
|
4
|
+
module HTMLRender; end
|
5
|
+
module HTMLRender::RenderTest
|
6
|
+
# Result of a RenderTest::run() call
|
7
|
+
class Result
|
8
|
+
# The portion of a result specific to an individual server
|
9
|
+
class ServerResult
|
10
|
+
attr_reader :server, :expected, :actual
|
11
|
+
|
12
|
+
# Initializes the ServerResult.
|
13
|
+
#
|
14
|
+
# Params:
|
15
|
+
# server: name of the server
|
16
|
+
# expected: Image we expected
|
17
|
+
# actual: Image we got
|
18
|
+
def initialize(server, expected, actual)
|
19
|
+
@server = server
|
20
|
+
@expected = expected
|
21
|
+
@actual = actual
|
22
|
+
end
|
23
|
+
|
24
|
+
def pass?
|
25
|
+
actual == expected
|
26
|
+
end
|
27
|
+
|
28
|
+
def difference
|
29
|
+
expected.difference(actual)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def servers
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
|
+
|
37
|
+
def details
|
38
|
+
returning({}) do |h|
|
39
|
+
servers.each do |server|
|
40
|
+
h[server] = details_for(server)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the ServerResult corresponding to the given Server
|
46
|
+
def details_for(server)
|
47
|
+
raise NotImplementedError
|
48
|
+
end
|
49
|
+
|
50
|
+
def pass?
|
51
|
+
@pass ||= servers.select{|s| !details_for(s).pass?}.empty?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class DirectoryResult < Result
|
56
|
+
attr_reader :path
|
57
|
+
attr_reader :valid_path
|
58
|
+
attr_reader :canonical_path
|
59
|
+
|
60
|
+
def initialize(path, valid_path, canonical_path)
|
61
|
+
@path = path
|
62
|
+
@valid_path = valid_path
|
63
|
+
@canonical_path = canonical_path
|
64
|
+
end
|
65
|
+
|
66
|
+
def servers
|
67
|
+
@servers ||= Dir.glob(File.join(path, '*.png')).collect{ |s| s.split(/\//).last[0..-5] }.sort
|
68
|
+
end
|
69
|
+
|
70
|
+
def details_for(server)
|
71
|
+
@details_for ||= {}
|
72
|
+
@details_for[server] ||= ServerResult.new(
|
73
|
+
server,
|
74
|
+
expected_png_for(server),
|
75
|
+
actual_png_for(server)
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
# Returns the PNG we actually got for the given server name
|
82
|
+
def actual_png_for(server)
|
83
|
+
@actual_png_for ||= {}
|
84
|
+
@actual_png_for[server] ||= begin
|
85
|
+
filename = filename_of_actual_png_for(server)
|
86
|
+
File.open(filename) do |f|
|
87
|
+
HTMLRender::Images::PNGImage.new(f.read)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the PNG expected of the given server name, or nil
|
93
|
+
def expected_png_for(server)
|
94
|
+
@expected_png_for ||= {}
|
95
|
+
@expected_png_for[server] ||= begin
|
96
|
+
filename = filename_of_expected_png_for(server)
|
97
|
+
if filename
|
98
|
+
File.open(filename) do |f|
|
99
|
+
HTMLRender::Images::PNGImage.new(f.read)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def filename_of_actual_png_for(server)
|
106
|
+
# Assume it exists--otherwise, "servers" wouldn't return it
|
107
|
+
File.join(path, "#{server}.png")
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns the path to the expected PNG for the given server name, or nil
|
111
|
+
def filename_of_expected_png_for(server)
|
112
|
+
specific = File.join(valid_path, "#{server}.png")
|
113
|
+
|
114
|
+
@filename_of_expected_png_for ||= {}
|
115
|
+
@filename_of_expected_png_for[server] ||= case
|
116
|
+
when File.exist?(specific) then specific
|
117
|
+
when File.exist?(canonical_path) then canonical_path
|
118
|
+
else nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Tests, across browsers, that some HTML renders correctly.
|
124
|
+
#
|
125
|
+
# A DirectoryRenderTest works within a particular directory in the
|
126
|
+
# filesystem, and it expects the following files:
|
127
|
+
#
|
128
|
+
# - html.html
|
129
|
+
# - canonical.png (what we want it to look like)
|
130
|
+
# - valid/SERVER.png for each SYSTEM (i.e., "ff3", "winxp-ie6", etc.)
|
131
|
+
# - runs/20080331014523/SERVER.png (at the time "run" was called)
|
132
|
+
#
|
133
|
+
# Calling run() with a hash of servers (see
|
134
|
+
# HtmlRender::RenderBatches::HTTPRenderBatch) will batch-render for each
|
135
|
+
# server, potentially throwing a
|
136
|
+
# HtmlRender::Renderers::HTTPRenderer::ServerError if the render fails.
|
137
|
+
# It will return an HtmlRender::RenderTest::Result.
|
138
|
+
class DirectoryRenderTest
|
139
|
+
attr_reader :test_path, :run_path
|
140
|
+
|
141
|
+
def initialize(test_path, run_path, &block)
|
142
|
+
@test_path = test_path
|
143
|
+
@run_path = run_path
|
144
|
+
|
145
|
+
yield(self) if block_given?
|
146
|
+
end
|
147
|
+
|
148
|
+
def html
|
149
|
+
@html ||= File.open(html_path) do |f|
|
150
|
+
f.read
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def run(servers_hash)
|
155
|
+
clear_run_directory
|
156
|
+
|
157
|
+
begin
|
158
|
+
batch = HTMLRender::RenderBatches::HTTPRenderBatch.new(servers_hash)
|
159
|
+
batch.render_html_to_directory(html, run_path)
|
160
|
+
rescue Exception => e
|
161
|
+
clear_run_directory
|
162
|
+
raise e
|
163
|
+
end
|
164
|
+
|
165
|
+
last_result
|
166
|
+
end
|
167
|
+
|
168
|
+
# Returns the results of the last test. If the "valid" results changed
|
169
|
+
# since the last time run() was called, then last_result.pass? may
|
170
|
+
# return a different value than before (since it will compare the
|
171
|
+
# previously-generated actual .png's with the newer expected .png's).
|
172
|
+
def last_result
|
173
|
+
DirectoryResult.new(run_path, valid_path, canonical_path)
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
def clear_run_directory
|
179
|
+
FileUtils.rm(Dir.glob(File.join(run_path, '*.png')))
|
180
|
+
end
|
181
|
+
|
182
|
+
def html_path
|
183
|
+
File.join(test_path, 'html.html')
|
184
|
+
end
|
185
|
+
|
186
|
+
def canonical_path
|
187
|
+
File.join(test_path, 'canonical.png')
|
188
|
+
end
|
189
|
+
|
190
|
+
def valid_path
|
191
|
+
File.join(test_path, 'valid')
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -15,6 +15,8 @@ module HTMLRender::Renderers
|
|
15
15
|
# One should POST the HTML to the given URL, and the server should
|
16
16
|
# respond with a PNG image.
|
17
17
|
class HTTPRenderer < Base
|
18
|
+
class ServerError < Exception; end
|
19
|
+
|
18
20
|
attr_accessor :url
|
19
21
|
|
20
22
|
def initialize(url)
|
@@ -24,9 +26,12 @@ module HTMLRender::Renderers
|
|
24
26
|
def render(html)
|
25
27
|
client = HTTPClient.new
|
26
28
|
|
27
|
-
|
29
|
+
begin
|
30
|
+
response = client.post(url, html)
|
31
|
+
end
|
32
|
+
|
28
33
|
if response.status != 200
|
29
|
-
raise
|
34
|
+
raise ServerError.new("Unexpected HTTP server response from #{url}: #{response.inspect}")
|
30
35
|
end
|
31
36
|
|
32
37
|
HTMLRender::Images::PNGImage.new(response.content)
|
data/lib/html_render.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adamh-html_render
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Hooper
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-04-01 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
version:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: echoe
|
37
|
-
type: :
|
37
|
+
type: :development
|
38
38
|
version_requirement:
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
@@ -54,6 +54,8 @@ extra_rdoc_files:
|
|
54
54
|
- lib/html_render/render_batches.rb
|
55
55
|
- lib/html_render/renderers.rb
|
56
56
|
- lib/html_render/images.rb
|
57
|
+
- lib/html_render/render_test.rb
|
58
|
+
- lib/html_render/render_test/rails.rb
|
57
59
|
files:
|
58
60
|
- README.rdoc
|
59
61
|
- Rakefile
|
@@ -62,6 +64,8 @@ files:
|
|
62
64
|
- lib/html_render/render_batches.rb
|
63
65
|
- lib/html_render/renderers.rb
|
64
66
|
- lib/html_render/images.rb
|
67
|
+
- lib/html_render/render_test.rb
|
68
|
+
- lib/html_render/render_test/rails.rb
|
65
69
|
- Manifest
|
66
70
|
has_rdoc: true
|
67
71
|
homepage: http://adamhooper.com/eng
|