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 CHANGED
@@ -5,4 +5,6 @@ lib/html_render.rb
5
5
  lib/html_render/render_batches.rb
6
6
  lib/html_render/renderers.rb
7
7
  lib/html_render/images.rb
8
+ lib/html_render/render_test.rb
9
+ lib/html_render/render_test/rails.rb
8
10
  Manifest
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('html_render', '0.0.1') do |p|
5
+ Echoe.new('html_render', '0.0.2') do |p|
6
6
  p.description = 'Make images from HTML strings'
7
7
  p.url = 'http://adamhooper.com/eng'
8
8
  p.author = 'Adam Hooper'
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.1"
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-03-06}
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.2.0}
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 current_version >= 3 then
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"])
@@ -23,7 +23,8 @@ module HTMLRender::Images
23
23
  end
24
24
 
25
25
  def <=>(other)
26
- (png <=> other.png) == 0
26
+ self.class.name <=> other.class.name unless PNGImage === other
27
+ png <=> other.png
27
28
  end
28
29
 
29
30
  def difference(other)
@@ -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
- response = client.post(url, html)
29
+ begin
30
+ response = client.post(url, html)
31
+ end
32
+
28
33
  if response.status != 200
29
- raise Exception.new("Unexpected HTTP server response from #{url}: #{response.inspect}")
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
@@ -1,3 +1,4 @@
1
1
  require 'html_render/images'
2
2
  require 'html_render/renderers'
3
3
  require 'html_render/render_batches'
4
+ require 'html_render/render_test'
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.1
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-03-06 00:00:00 -08:00
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: :runtime
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