wicked_pdf 1.1.0 → 2.8.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.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/.github/issue_template.md +15 -0
  3. data/.github/workflows/ci.yml +56 -0
  4. data/.rubocop.yml +62 -0
  5. data/.rubocop_todo.yml +81 -39
  6. data/CHANGELOG.md +194 -45
  7. data/README.md +136 -28
  8. data/Rakefile +12 -9
  9. data/gemfiles/5.0.gemfile +3 -1
  10. data/gemfiles/5.1.gemfile +8 -0
  11. data/gemfiles/5.2.gemfile +9 -0
  12. data/gemfiles/6.0.gemfile +10 -0
  13. data/gemfiles/6.1.gemfile +11 -0
  14. data/gemfiles/7.0.gemfile +11 -0
  15. data/generators/wicked_pdf/templates/wicked_pdf.rb +14 -5
  16. data/lib/generators/wicked_pdf_generator.rb +5 -9
  17. data/lib/wicked_pdf/binary.rb +65 -0
  18. data/lib/wicked_pdf/middleware.rb +1 -1
  19. data/lib/wicked_pdf/option_parser.rb +230 -0
  20. data/lib/wicked_pdf/pdf_helper.rb +35 -42
  21. data/lib/wicked_pdf/progress.rb +33 -0
  22. data/lib/wicked_pdf/railtie.rb +6 -44
  23. data/lib/wicked_pdf/tempfile.rb +33 -3
  24. data/lib/wicked_pdf/version.rb +1 -1
  25. data/lib/wicked_pdf/wicked_pdf_helper/assets.rb +200 -17
  26. data/lib/wicked_pdf/wicked_pdf_helper.rb +2 -1
  27. data/lib/wicked_pdf.rb +64 -275
  28. data/test/fixtures/database.yml +4 -0
  29. data/test/fixtures/manifest.js +3 -0
  30. data/test/functional/pdf_helper_test.rb +71 -0
  31. data/test/functional/wicked_pdf_helper_assets_test.rb +61 -0
  32. data/test/test_helper.rb +13 -8
  33. data/test/unit/wicked_pdf_binary_test.rb +26 -0
  34. data/test/unit/wicked_pdf_option_parser_test.rb +133 -0
  35. data/test/unit/wicked_pdf_test.rb +25 -146
  36. data/test/unit/wkhtmltopdf_location_test.rb +48 -0
  37. data/wicked_pdf.gemspec +20 -13
  38. metadata +79 -36
  39. data/.travis.yml +0 -57
  40. data/gemfiles/2.3.gemfile +0 -10
  41. data/gemfiles/3.0.gemfile +0 -12
  42. data/gemfiles/3.1.gemfile +0 -13
  43. data/gemfiles/3.2.gemfile +0 -12
  44. data/gemfiles/4.0.gemfile +0 -6
  45. data/gemfiles/4.1.gemfile +0 -6
  46. data/gemfiles/4.2.gemfile +0 -6
  47. data/gemfiles/rails_edge.gemfile +0 -6
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link wicked.js
3
+ //= link wicked.css
@@ -5,10 +5,32 @@ module ActionController
5
5
  def render_to_string(opts = {})
6
6
  opts.to_s
7
7
  end
8
+
9
+ def self.alias_method_chain(_target, _feature); end
10
+ end
11
+ end
12
+
13
+ module ActionControllerMock
14
+ class Base
15
+ def render(_)
16
+ [:base]
17
+ end
18
+
19
+ def render_to_string; end
20
+
21
+ def self.after_action(_); end
8
22
  end
9
23
  end
10
24
 
11
25
  class PdfHelperTest < ActionController::TestCase
26
+ module SomePatch
27
+ def render(_)
28
+ super.tap do |s|
29
+ s << :patched
30
+ end
31
+ end
32
+ end
33
+
12
34
  def setup
13
35
  @ac = ActionController::Base.new
14
36
  end
@@ -22,4 +44,53 @@ class PdfHelperTest < ActionController::TestCase
22
44
  :header => { :html => { :template => 'hf.html.erb' } })
23
45
  assert_match %r{^file:\/\/\/.*wicked_header_pdf.*\.html}, options[:header][:html][:url]
24
46
  end
47
+
48
+ test 'should not interfere with already prepended patches' do
49
+ # Emulate railtie
50
+ if Rails::VERSION::MAJOR >= 5
51
+ # this spec tests the following:
52
+ # if another gem prepends a render method to ActionController::Base
53
+ # before wicked_pdf does, does calling render trigger an infinite loop?
54
+ # this spec fails with 6392bea1fe3a41682dfd7c20fd9c179b5a758f59 because PdfHelper
55
+ # aliases the render method prepended by the other gem to render_without_pdf, then
56
+ # base_evals its own definition of render, which calls render_with_pdf -> render_without_pdf.
57
+ # If the other gem uses the prepend inhertinance pattern (calling super instead of aliasing),
58
+ # when it calls super it calls the base_eval'd version of render instead of going up the
59
+ # inheritance chain, causing an infinite loop.
60
+
61
+ # This fiddling with consts is required to get around the fact that PdfHelper checks
62
+ # that it is being prepended to ActionController::Base
63
+ OriginalBase = ActionController::Base
64
+ ActionController.send(:remove_const, :Base)
65
+ ActionController.const_set(:Base, ActionControllerMock::Base)
66
+
67
+ # Emulate another gem being loaded before wicked
68
+ ActionController::Base.prepend(SomePatch)
69
+ ActionController::Base.prepend(::WickedPdf::PdfHelper)
70
+
71
+ begin
72
+ # test that wicked's render method is actually called
73
+ ac = ActionController::Base.new
74
+ ac.expects(:render_with_wicked_pdf)
75
+ ac.render(:cats)
76
+
77
+ # test that calling render does not trigger infinite loop
78
+ ac = ActionController::Base.new
79
+ assert_equal %i[base patched], ac.render(:cats)
80
+ rescue SystemStackError
81
+ assert_equal true, false # force spec failure
82
+ ensure
83
+ ActionController.send(:remove_const, :Base)
84
+ ActionController.const_set(:Base, OriginalBase)
85
+ end
86
+ end
87
+ end
88
+
89
+ test 'should call after_action instead of after_filter when able' do
90
+ ActionController::Base.expects(:after_filter).with(:clean_temp_files).never
91
+ ActionController::Base.expects(:after_action).with(:clean_temp_files).once
92
+ ActionController::Base.class_eval do
93
+ include ::WickedPdf::PdfHelper
94
+ end
95
+ end
25
96
  end
@@ -4,6 +4,15 @@ require 'action_view/test_case'
4
4
  class WickedPdfHelperAssetsTest < ActionView::TestCase
5
5
  include WickedPdf::WickedPdfHelper::Assets
6
6
 
7
+ setup do
8
+ @saved_config = WickedPdf.config
9
+ WickedPdf.config = {}
10
+ end
11
+
12
+ teardown do
13
+ WickedPdf.config = @saved_config
14
+ end
15
+
7
16
  if Rails::VERSION::MAJOR > 3 || (Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR > 0)
8
17
  test 'wicked_pdf_asset_base64 returns a base64 encoded asset' do
9
18
  assert_match %r{data:text\/css;base64,.+}, wicked_pdf_asset_base64('wicked.css')
@@ -15,6 +24,58 @@ class WickedPdfHelperAssetsTest < ActionView::TestCase
15
24
  wicked_pdf_stylesheet_link_tag('wicked')
16
25
  end
17
26
 
27
+ test 'wicked_pdf_stylesheet_link_tag should raise if the stylesheet is not available and config is set' do
28
+ Rails.configuration.assets.expects(:compile => true)
29
+ WickedPdf.config[:raise_on_missing_assets] = true
30
+ assert_raise WickedPdf::WickedPdfHelper::Assets::MissingLocalAsset do
31
+ wicked_pdf_stylesheet_link_tag('non_existent')
32
+ end
33
+ end
34
+
35
+ test 'wicked_pdf_stylesheet_link_tag should return empty if the stylesheet is not available' do
36
+ Rails.configuration.assets.expects(:compile => true)
37
+ assert_equal "<style type='text/css'></style>",
38
+ wicked_pdf_stylesheet_link_tag('non_existent')
39
+ end
40
+
41
+ test 'wicked_pdf_stylesheet_link_tag should raise if the absolute path stylesheet is not available and config is set' do
42
+ Rails.configuration.assets.expects(:compile => true)
43
+ WickedPdf.config[:raise_on_missing_assets] = true
44
+ expects(:precompiled_or_absolute_asset? => true).twice
45
+ assert_raise WickedPdf::WickedPdfHelper::Assets::MissingLocalAsset do
46
+ wicked_pdf_stylesheet_link_tag('/non_existent')
47
+ end
48
+ end
49
+
50
+ test 'wicked_pdf_stylesheet_link_tag should return empty if the absolute path stylesheet is not available' do
51
+ Rails.configuration.assets.expects(:compile => true).twice
52
+ assert_equal "<style type='text/css'></style>",
53
+ wicked_pdf_stylesheet_link_tag('/non_existent')
54
+ end
55
+
56
+ test 'wicked_pdf_stylesheet_link_tag should inline the stylesheets passed in when assets are remote' do
57
+ stub_request(:get, 'https://www.example.com/wicked.css').to_return(:status => 200, :body => '/* Wicked styles */')
58
+ expects(:precompiled_or_absolute_asset? => true).twice
59
+ assert_equal "<style type='text/css'>/* Wicked styles */</style>",
60
+ wicked_pdf_stylesheet_link_tag('https://www.example.com/wicked.css')
61
+ end
62
+
63
+ test 'wicked_pdf_stylesheet_link_tag should raise if remote assets are not available and config is set' do
64
+ WickedPdf.config[:raise_on_missing_assets] = true
65
+ stub_request(:get, 'https://www.example.com/wicked.css').to_return(:status => 404, :body => 'File not found')
66
+ expects(:precompiled_or_absolute_asset? => true).twice
67
+ assert_raise WickedPdf::WickedPdfHelper::Assets::MissingRemoteAsset do
68
+ wicked_pdf_stylesheet_link_tag('https://www.example.com/wicked.css')
69
+ end
70
+ end
71
+
72
+ test 'wicked_pdf_stylesheet_link_tag should return empty if remote assets are not available' do
73
+ stub_request(:get, 'https://www.example.com/wicked.css').to_return(:status => 404, :body => 'File not found')
74
+ expects(:precompiled_or_absolute_asset? => true).twice
75
+ assert_equal "<style type='text/css'></style>",
76
+ wicked_pdf_stylesheet_link_tag('https://www.example.com/wicked.css')
77
+ end
78
+
18
79
  test 'wicked_pdf_image_tag should return the same as image_tag when passed a full path' do
19
80
  Rails.configuration.assets.expects(:compile => true)
20
81
  assert_equal image_tag("file:///#{Rails.root.join('public', 'pdf')}"),
data/test/test_helper.rb CHANGED
@@ -5,17 +5,14 @@ require File.expand_path('../dummy/config/environment.rb', __FILE__)
5
5
 
6
6
  require 'test/unit'
7
7
  require 'mocha'
8
-
9
- if Rails::VERSION::MAJOR == 2
10
- require 'test_help'
11
- else
12
- require 'rails/test_help'
13
- require 'mocha/test_unit'
14
- end
8
+ require 'rails/test_help'
9
+ require 'mocha/test_unit'
10
+ require 'webmock/minitest'
15
11
 
16
12
  require 'wicked_pdf'
17
13
 
18
14
  Rails.backtrace_cleaner.remove_silencers!
15
+ WickedPdf.silence_deprecations = true
19
16
 
20
17
  if (assets_dir = Rails.root.join('app/assets')) && File.directory?(assets_dir)
21
18
  # Copy CSS file
@@ -24,7 +21,15 @@ if (assets_dir = Rails.root.join('app/assets')) && File.directory?(assets_dir)
24
21
  File.open(destination, 'w') { |f| f.write(source) }
25
22
 
26
23
  # Copy JS file
27
- destination = assets_dir.join('javascripts/wicked.js')
24
+ js_dir = assets_dir.join('javascripts')
25
+ Dir.mkdir(js_dir) unless File.directory?(js_dir)
26
+ destination = js_dir.join('wicked.js')
28
27
  source = File.read('test/fixtures/wicked.js')
29
28
  File.open(destination, 'w') { |f| f.write(source) }
29
+
30
+ config_dir = assets_dir.join('config')
31
+ Dir.mkdir(config_dir) unless File.directory?(config_dir)
32
+ source = File.read('test/fixtures/manifest.js')
33
+ destination = config_dir.join('manifest.js')
34
+ File.open(destination, 'w') { |f| f.write(source) }
30
35
  end
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ class WickedPdfBinaryTest < ActiveSupport::TestCase
4
+ test 'should extract old wkhtmltopdf version' do
5
+ version_info_sample = "Name:\n wkhtmltopdf 0.9.9\n\nLicense:\n Copyright (C) 2008,2009 Wkhtmltopdf Authors.\n\n\n\n License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n This is free software: you are free to change and redistribute it. There is NO\n WARRANTY, to the extent permitted by law.\n\nAuthors:\n Written by Jakob Truelsen. Patches by Mrio Silva, Benoit Garret and Emmanuel\n Bouthenot.\n"
6
+ assert_equal WickedPdf::DEFAULT_BINARY_VERSION, binary.parse_version_string(version_info_sample)
7
+ end
8
+
9
+ test 'should extract new wkhtmltopdf version' do
10
+ version_info_sample = "Name:\n wkhtmltopdf 0.11.0 rc2\n\nLicense:\n Copyright (C) 2010 wkhtmltopdf/wkhtmltoimage Authors.\n\n\n\n License LGPLv3+: GNU Lesser General Public License version 3 or later\n <http://gnu.org/licenses/lgpl.html>. This is free software: you are free to\n change and redistribute it. There is NO WARRANTY, to the extent permitted by\n law.\n\nAuthors:\n Written by Jan Habermann, Christian Sciberras and Jakob Truelsen. Patches by\n Mehdi Abbad, Lyes Amazouz, Pascal Bach, Emmanuel Bouthenot, Benoit Garret and\n Mario Silva."
11
+ assert_equal Gem::Version.new('0.11.0'), binary.parse_version_string(version_info_sample)
12
+ end
13
+
14
+ test 'should extract wkhtmltopdf version with nondigit symbols' do
15
+ version_info_sample = "Name:\n wkhtmltopdf 0.10.4b\n\nLicense:\n Copyright (C) 2008,2009 Wkhtmltopdf Authors.\n\n\n\n License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n This is free software: you are free to change and redistribute it. There is NO\n WARRANTY, to the extent permitted by law.\n\nAuthors:\n Written by Jakob Truelsen. Patches by Mrio Silva, Benoit Garret and Emmanuel\n Bouthenot.\n"
16
+ assert_equal Gem::Version.new('0.10.4b'), binary.parse_version_string(version_info_sample)
17
+ end
18
+
19
+ test 'should fallback to default version on parse error' do
20
+ assert_equal WickedPdf::DEFAULT_BINARY_VERSION, binary.parse_version_string('')
21
+ end
22
+
23
+ def binary(path = nil)
24
+ WickedPdf::Binary.new(path)
25
+ end
26
+ end
@@ -0,0 +1,133 @@
1
+ require 'test_helper'
2
+
3
+ class WickedPdfOptionParserTest < ActiveSupport::TestCase
4
+ test 'should parse header and footer options' do
5
+ %i[header footer].each do |hf|
6
+ %i[center font_name left right].each do |o|
7
+ assert_equal "--#{hf}-#{o.to_s.tr('_', '-')} header_footer",
8
+ parse_options(hf => { o => 'header_footer' }).strip
9
+ end
10
+
11
+ %i[font_size spacing].each do |o|
12
+ assert_equal "--#{hf}-#{o.to_s.tr('_', '-')} 12",
13
+ parse_options(hf => { o => '12' }).strip
14
+ end
15
+
16
+ assert_equal "--#{hf}-line",
17
+ parse_options(hf => { :line => true }).strip
18
+ assert_equal "--#{hf}-html http://www.abc.com",
19
+ parse_options(hf => { :html => { :url => 'http://www.abc.com' } }).strip
20
+ end
21
+ end
22
+
23
+ test 'should parse toc options' do
24
+ toc_option = option_parser.valid_option('toc')
25
+
26
+ %i[font_name header_text].each do |o|
27
+ assert_equal "#{toc_option} --toc-#{o.to_s.tr('_', '-')} toc",
28
+ parse_options(:toc => { o => 'toc' }).strip
29
+ end
30
+
31
+ %i[
32
+ depth header_fs l1_font_size l2_font_size l3_font_size l4_font_size
33
+ l5_font_size l6_font_size l7_font_size l1_indentation l2_indentation
34
+ l3_indentation l4_indentation l5_indentation l6_indentation l7_indentation
35
+ ].each do |o|
36
+ assert_equal "#{toc_option} --toc-#{o.to_s.tr('_', '-')} 5",
37
+ parse_options(:toc => { o => 5 }).strip
38
+ end
39
+
40
+ %i[no_dots disable_links disable_back_links].each do |o|
41
+ assert_equal "#{toc_option} --toc-#{o.to_s.tr('_', '-')}",
42
+ parse_options(:toc => { o => true }).strip
43
+ end
44
+ end
45
+
46
+ test 'should parse outline options' do
47
+ assert_equal '--outline', parse_options(:outline => { :outline => true }).strip
48
+ assert_equal '--outline-depth 5', parse_options(:outline => { :outline_depth => 5 }).strip
49
+ end
50
+
51
+ test 'should parse no_images option' do
52
+ assert_equal '--no-images', parse_options(:no_images => true).strip
53
+ assert_equal '--images', parse_options(:images => true).strip
54
+ end
55
+
56
+ test 'should parse margins options' do
57
+ %i[top bottom left right].each do |o|
58
+ assert_equal "--margin-#{o} 12", parse_options(:margin => { o => '12' }).strip
59
+ end
60
+ end
61
+
62
+ test 'should parse cover' do
63
+ cover_option = option_parser.valid_option('cover')
64
+
65
+ pathname = Rails.root.join('app', 'views', 'pdf', 'file.html')
66
+ assert_equal "#{cover_option} http://example.org", parse_options(:cover => 'http://example.org').strip, 'URL'
67
+ assert_equal "#{cover_option} #{pathname}", parse_options(:cover => pathname).strip, 'Pathname'
68
+ assert_match(/#{cover_option} .+wicked_cover_pdf.+\.html/, parse_options(:cover => '<html><body>HELLO</body></html>').strip, 'HTML')
69
+ end
70
+
71
+ test 'should parse other options' do
72
+ %i[
73
+ orientation page_size proxy username password dpi
74
+ encoding user_style_sheet
75
+ ].each do |o|
76
+ assert_equal "--#{o.to_s.tr('_', '-')} opts", parse_options(o => 'opts').strip
77
+ end
78
+
79
+ %i[allow].each do |o|
80
+ assert_equal "--#{o.to_s.tr('_', '-')} opts", parse_options(o => 'opts').strip
81
+ assert_equal "--#{o.to_s.tr('_', '-')} opts1 --#{o.to_s.tr('_', '-')} opts2", parse_options(o => %w[opts1 opts2]).strip
82
+ end
83
+
84
+ %i[cookie post].each do |o|
85
+ assert_equal "--#{o.to_s.tr('_', '-')} name value", parse_options(o => 'name value').strip
86
+
87
+ nv_formatter = proc { |number| "--#{o.to_s.tr('_', '-')} par#{number} val#{number}" }
88
+ assert_equal "#{nv_formatter.call(1)} #{nv_formatter.call(2)}", parse_options(o => ['par1 val1', 'par2 val2']).strip
89
+ end
90
+
91
+ %i[redirect_delay zoom page_offset].each do |o|
92
+ assert_equal "--#{o.to_s.tr('_', '-')} 5", parse_options(o => 5).strip
93
+ end
94
+
95
+ %i[
96
+ book default_header disable_javascript grayscale lowquality
97
+ enable_plugins disable_internal_links disable_external_links
98
+ print_media_type disable_smart_shrinking use_xserver no_background disable_local_file_access
99
+ ].each do |o|
100
+ assert_equal "--#{o.to_s.tr('_', '-')}", parse_options(o => true).strip
101
+ end
102
+ end
103
+
104
+ test 'should not use double dash options for version without dashes' do
105
+ op = option_parser(WickedPdf::OptionParser::BINARY_VERSION_WITHOUT_DASHES)
106
+
107
+ %w[toc cover].each do |name|
108
+ assert_equal op.valid_option(name), name
109
+ end
110
+ end
111
+
112
+ test 'should use double dash options for version with dashes' do
113
+ op = option_parser(Gem::Version.new('0.11.0'))
114
+
115
+ %w[toc cover].each do |name|
116
+ assert_equal op.valid_option(name), "--#{name}"
117
+ end
118
+ end
119
+
120
+ test '-- options should not be given after object' do
121
+ options = { :header => { :center => 3 }, :cover => 'http://example.org', :disable_javascript => true }
122
+ cover_option = option_parser.valid_option('cover')
123
+ assert_equal parse_options(options), "--disable-javascript --header-center 3 #{cover_option} http://example.org"
124
+ end
125
+
126
+ def parse_options(options, version = WickedPdf::DEFAULT_BINARY_VERSION)
127
+ option_parser(version).parse(options).join(' ')
128
+ end
129
+
130
+ def option_parser(version = WickedPdf::DEFAULT_BINARY_VERSION)
131
+ WickedPdf::OptionParser.new(version)
132
+ end
133
+ end
@@ -1,25 +1,27 @@
1
1
  require 'test_helper'
2
-
3
2
  WickedPdf.config = { :exe_path => ENV['WKHTMLTOPDF_BIN'] || '/usr/local/bin/wkhtmltopdf' }
4
3
  HTML_DOCUMENT = '<html><body>Hello World</body></html>'.freeze
5
4
 
6
- # Provide a public accessor to the normally-private parse_options function.
7
- # Also, smash the returned array of options into a single string for
8
- # convenience in testing below.
9
- class WickedPdf
10
- attr_accessor :binary_version
11
- def get_parsed_options(opts)
12
- parse_options(opts).join(' ')
5
+ class WickedPdfTest < ActiveSupport::TestCase
6
+ def setup
7
+ @wp = WickedPdf.new
13
8
  end
14
9
 
15
- def get_valid_option(name)
16
- valid_option(name)
10
+ test 'should update config through .configure class method' do
11
+ WickedPdf.configure do |c|
12
+ c.test = 'foobar'
13
+ end
14
+
15
+ assert WickedPdf.config == { :exe_path => ENV['WKHTMLTOPDF_BIN'] || '/usr/local/bin/wkhtmltopdf', :test => 'foobar' }
17
16
  end
18
- end
19
17
 
20
- class WickedPdfTest < ActiveSupport::TestCase
21
- def setup
22
- @wp = WickedPdf.new
18
+ test 'should clear config through .clear_config class method' do
19
+ backup_config = WickedPdf.config
20
+
21
+ WickedPdf.clear_config
22
+ assert WickedPdf.config == {}
23
+
24
+ WickedPdf.config = backup_config
23
25
  end
24
26
 
25
27
  test 'should generate PDF from html document' do
@@ -84,138 +86,15 @@ class WickedPdfTest < ActiveSupport::TestCase
84
86
  end
85
87
  end
86
88
 
87
- test 'should parse header and footer options' do
88
- [:header, :footer].each do |hf|
89
- [:center, :font_name, :left, :right].each do |o|
90
- assert_equal "--#{hf}-#{o.to_s.tr('_', '-')} header_footer",
91
- @wp.get_parsed_options(hf => { o => 'header_footer' }).strip
92
- end
93
-
94
- [:font_size, :spacing].each do |o|
95
- assert_equal "--#{hf}-#{o.to_s.tr('_', '-')} 12",
96
- @wp.get_parsed_options(hf => { o => '12' }).strip
97
- end
98
-
99
- assert_equal "--#{hf}-line",
100
- @wp.get_parsed_options(hf => { :line => true }).strip
101
- assert_equal "--#{hf}-html http://www.abc.com",
102
- @wp.get_parsed_options(hf => { :html => { :url => 'http://www.abc.com' } }).strip
103
- end
104
- end
105
-
106
- test 'should parse toc options' do
107
- toc_option = @wp.get_valid_option('toc')
108
-
109
- [:font_name, :header_text].each do |o|
110
- assert_equal "#{toc_option} --toc-#{o.to_s.tr('_', '-')} toc",
111
- @wp.get_parsed_options(:toc => { o => 'toc' }).strip
112
- end
113
-
114
- [
115
- :depth, :header_fs, :l1_font_size, :l2_font_size, :l3_font_size, :l4_font_size,
116
- :l5_font_size, :l6_font_size, :l7_font_size, :l1_indentation, :l2_indentation,
117
- :l3_indentation, :l4_indentation, :l5_indentation, :l6_indentation, :l7_indentation
118
- ].each do |o|
119
- assert_equal "#{toc_option} --toc-#{o.to_s.tr('_', '-')} 5",
120
- @wp.get_parsed_options(:toc => { o => 5 }).strip
121
- end
122
-
123
- [:no_dots, :disable_links, :disable_back_links].each do |o|
124
- assert_equal "#{toc_option} --toc-#{o.to_s.tr('_', '-')}",
125
- @wp.get_parsed_options(:toc => { o => true }).strip
126
- end
127
- end
128
-
129
- test 'should parse outline options' do
130
- assert_equal '--outline', @wp.get_parsed_options(:outline => { :outline => true }).strip
131
- assert_equal '--outline-depth 5', @wp.get_parsed_options(:outline => { :outline_depth => 5 }).strip
132
- end
133
-
134
- test 'should parse margins options' do
135
- [:top, :bottom, :left, :right].each do |o|
136
- assert_equal "--margin-#{o} 12", @wp.get_parsed_options(:margin => { o => '12' }).strip
137
- end
138
- end
139
-
140
- test 'should parse cover' do
141
- cover_option = @wp.get_valid_option('cover')
142
-
143
- pathname = Rails.root.join('app', 'views', 'pdf', 'file.html')
144
- assert_equal "#{cover_option} http://example.org", @wp.get_parsed_options(:cover => 'http://example.org').strip, 'URL'
145
- assert_equal "#{cover_option} #{pathname}", @wp.get_parsed_options(:cover => pathname).strip, 'Pathname'
146
- assert_match %r{#{cover_option} .+wicked_cover_pdf.+\.html}, @wp.get_parsed_options(:cover => '<html><body>HELLO</body></html>').strip, 'HTML'
147
- end
148
-
149
- test 'should parse other options' do
150
- [
151
- :orientation, :page_size, :proxy, :username, :password, :dpi,
152
- :encoding, :user_style_sheet
153
- ].each do |o|
154
- assert_equal "--#{o.to_s.tr('_', '-')} opts", @wp.get_parsed_options(o => 'opts').strip
155
- end
156
-
157
- [:cookie, :post].each do |o|
158
- assert_equal "--#{o.to_s.tr('_', '-')} name value", @wp.get_parsed_options(o => 'name value').strip
159
-
160
- nv_formatter = proc { |number| "--#{o.to_s.tr('_', '-')} par#{number} val#{number}" }
161
- assert_equal "#{nv_formatter.call(1)} #{nv_formatter.call(2)}", @wp.get_parsed_options(o => ['par1 val1', 'par2 val2']).strip
162
- end
163
-
164
- [:redirect_delay, :zoom, :page_offset].each do |o|
165
- assert_equal "--#{o.to_s.tr('_', '-')} 5", @wp.get_parsed_options(o => 5).strip
166
- end
167
-
168
- [
169
- :book, :default_header, :disable_javascript, :grayscale, :lowquality,
170
- :enable_plugins, :disable_internal_links, :disable_external_links,
171
- :print_media_type, :disable_smart_shrinking, :use_xserver, :no_background
172
- ].each do |o|
173
- assert_equal "--#{o.to_s.tr('_', '-')}", @wp.get_parsed_options(o => true).strip
89
+ test 'should output progress when creating pdfs on compatible hosts' do
90
+ wp = WickedPdf.new
91
+ output = []
92
+ options = { :progress => proc { |o| output << o } }
93
+ wp.pdf_from_string HTML_DOCUMENT, options
94
+ if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
95
+ assert_empty output
96
+ else
97
+ assert(output.collect { |l| !l.match(/Loading/).nil? }.include?(true)) # should output something like "Loading pages (1/5)"
174
98
  end
175
99
  end
176
-
177
- test 'should extract old wkhtmltopdf version' do
178
- version_info_sample = "Name:\n wkhtmltopdf 0.9.9\n\nLicense:\n Copyright (C) 2008,2009 Wkhtmltopdf Authors.\n\n\n\n License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n This is free software: you are free to change and redistribute it. There is NO\n WARRANTY, to the extent permitted by law.\n\nAuthors:\n Written by Jakob Truelsen. Patches by Mrio Silva, Benoit Garret and Emmanuel\n Bouthenot.\n"
179
- assert_equal WickedPdf::DEFAULT_BINARY_VERSION, @wp.send(:parse_version, version_info_sample)
180
- end
181
-
182
- test 'should extract new wkhtmltopdf version' do
183
- version_info_sample = "Name:\n wkhtmltopdf 0.11.0 rc2\n\nLicense:\n Copyright (C) 2010 wkhtmltopdf/wkhtmltoimage Authors.\n\n\n\n License LGPLv3+: GNU Lesser General Public License version 3 or later\n <http://gnu.org/licenses/lgpl.html>. This is free software: you are free to\n change and redistribute it. There is NO WARRANTY, to the extent permitted by\n law.\n\nAuthors:\n Written by Jan Habermann, Christian Sciberras and Jakob Truelsen. Patches by\n Mehdi Abbad, Lyes Amazouz, Pascal Bach, Emmanuel Bouthenot, Benoit Garret and\n Mario Silva."
184
- assert_equal Gem::Version.new('0.11.0'), @wp.send(:parse_version, version_info_sample)
185
- end
186
-
187
- test 'should extract wkhtmltopdf version with nondigit symbols' do
188
- version_info_sample = "Name:\n wkhtmltopdf 0.10.4b\n\nLicense:\n Copyright (C) 2008,2009 Wkhtmltopdf Authors.\n\n\n\n License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n This is free software: you are free to change and redistribute it. There is NO\n WARRANTY, to the extent permitted by law.\n\nAuthors:\n Written by Jakob Truelsen. Patches by Mrio Silva, Benoit Garret and Emmanuel\n Bouthenot.\n"
189
- assert_equal Gem::Version.new('0.10.4b'), @wp.send(:parse_version, version_info_sample)
190
- end
191
-
192
- test 'should fallback to default version on parse error' do
193
- assert_equal WickedPdf::DEFAULT_BINARY_VERSION, @wp.send(:parse_version, '')
194
- end
195
-
196
- test 'should set version on initialize' do
197
- assert_not_equal @wp.send(:binary_version), ''
198
- end
199
-
200
- test 'should not use double dash options for version without dashes' do
201
- @wp.binary_version = WickedPdf::BINARY_VERSION_WITHOUT_DASHES
202
-
203
- %w(toc cover).each do |name|
204
- assert_equal @wp.get_valid_option(name), name
205
- end
206
- end
207
-
208
- test 'should use double dash options for version with dashes' do
209
- @wp.binary_version = Gem::Version.new('0.11.0')
210
-
211
- %w(toc cover).each do |name|
212
- assert_equal @wp.get_valid_option(name), "--#{name}"
213
- end
214
- end
215
-
216
- test '-- options should not be given after object' do
217
- options = { :header => { :center => 3 }, :cover => 'http://example.org', :disable_javascript => true }
218
- cover_option = @wp.get_valid_option('cover')
219
- assert_equal @wp.get_parsed_options(options), "--disable-javascript --header-center 3 #{cover_option} http://example.org"
220
- end
221
100
  end
@@ -0,0 +1,48 @@
1
+ class WkhtmltopdfLocationTest < ActiveSupport::TestCase
2
+ setup do
3
+ @saved_config = WickedPdf.config
4
+ WickedPdf.config = {}
5
+ end
6
+
7
+ teardown do
8
+ WickedPdf.config = @saved_config
9
+ end
10
+
11
+ test 'should correctly locate wkhtmltopdf without bundler' do
12
+ bundler_module = Bundler
13
+ Object.send(:remove_const, :Bundler)
14
+
15
+ assert_nothing_raised do
16
+ WickedPdf.new
17
+ end
18
+
19
+ Object.const_set(:Bundler, bundler_module)
20
+ end
21
+
22
+ test 'should correctly locate wkhtmltopdf with bundler' do
23
+ assert_nothing_raised do
24
+ WickedPdf.new
25
+ end
26
+ end
27
+
28
+ class LocationNonWritableTest < ActiveSupport::TestCase
29
+ setup do
30
+ @saved_config = WickedPdf.config
31
+ WickedPdf.config = {}
32
+
33
+ @old_home = ENV['HOME']
34
+ ENV['HOME'] = '/not/a/writable/directory'
35
+ end
36
+
37
+ teardown do
38
+ WickedPdf.config = @saved_config
39
+ ENV['HOME'] = @old_home
40
+ end
41
+
42
+ test 'should correctly locate wkhtmltopdf with bundler while HOME is set to a non-writable directory' do
43
+ assert_nothing_raised do
44
+ WickedPdf.new
45
+ end
46
+ end
47
+ end
48
+ end
data/wicked_pdf.gemspec CHANGED
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'wicked_pdf/version'
@@ -7,28 +6,36 @@ require 'English'
7
6
  Gem::Specification.new do |spec|
8
7
  spec.name = 'wicked_pdf'
9
8
  spec.version = WickedPdf::VERSION
10
- spec.authors = ['Miles Z. Sterrett']
11
- spec.email = 'miles.sterrett@gmail.com'
9
+ spec.authors = ['Miles Z. Sterrett', 'David Jones']
10
+ spec.email = ['miles.sterrett@gmail.com', 'unixmonkey1@gmail.com']
12
11
  spec.summary = 'PDF generator (from HTML) gem for Ruby on Rails'
13
12
  spec.homepage = 'https://github.com/mileszs/wicked_pdf'
14
13
  spec.license = 'MIT'
15
14
  spec.date = Time.now.strftime('%Y-%m-%d')
16
- spec.description = <<desc
17
- Wicked PDF uses the shell utility wkhtmltopdf to serve a PDF file to a user from HTML.
18
- In other words, rather than dealing with a PDF generation DSL of some sort,
19
- you simply write an HTML view as you would normally, and let Wicked take care of the hard stuff.
20
- desc
15
+ spec.description = <<DESC.gsub(/^\s+/, '')
16
+ Wicked PDF uses the shell utility wkhtmltopdf to serve a PDF file to a user from HTML.
17
+ In other words, rather than dealing with a PDF generation DSL of some sort,
18
+ you simply write an HTML view as you would normally, and let Wicked take care of the hard stuff.
19
+ DESC
20
+ spec.metadata = {
21
+ 'changelog_uri' => 'https://github.com/mileszs/wicked_pdf/blob/master/CHANGELOG.md'
22
+ }
21
23
 
24
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.2')
22
25
  spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
23
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
26
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
27
  spec.require_paths = ['lib']
26
28
 
29
+ spec.requirements << 'wkhtmltopdf'
30
+
31
+ spec.add_dependency 'activesupport'
32
+
33
+ spec.add_development_dependency 'bundler'
34
+ spec.add_development_dependency 'mocha', '= 1.3'
27
35
  spec.add_development_dependency 'rails'
28
- spec.add_development_dependency 'bundler', '~> 1.3'
29
36
  spec.add_development_dependency 'rake'
30
- spec.add_development_dependency 'rubocop' if RUBY_VERSION >= '2.0.0'
31
- spec.add_development_dependency 'sqlite3'
32
- spec.add_development_dependency 'mocha'
37
+ spec.add_development_dependency 'rubocop', '~> 1.46'
38
+ spec.add_development_dependency 'sqlite3', '~> 1.3'
33
39
  spec.add_development_dependency 'test-unit'
40
+ spec.add_development_dependency 'webmock', '~> 3.19'
34
41
  end