inkcite 1.14.0 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/assets/init/config.yml +2 -0
  3. data/assets/social/facebook.png +0 -0
  4. data/assets/social/instagram.png +0 -0
  5. data/assets/social/pintrest.png +0 -0
  6. data/assets/social/twitter.png +0 -0
  7. data/inkcite.gemspec +2 -2
  8. data/lib/inkcite.rb +1 -0
  9. data/lib/inkcite/cli/base.rb +32 -6
  10. data/lib/inkcite/cli/preview.rb +24 -28
  11. data/lib/inkcite/cli/server.rb +22 -19
  12. data/lib/inkcite/cli/test.rb +1 -1
  13. data/lib/inkcite/email.rb +8 -4
  14. data/lib/inkcite/facade/animation.rb +4 -0
  15. data/lib/inkcite/facade/keyframe.rb +26 -3
  16. data/lib/inkcite/image/base.rb +38 -0
  17. data/lib/inkcite/image/guetzli_minifier.rb +62 -0
  18. data/lib/inkcite/image/image_minifier.rb +143 -0
  19. data/lib/inkcite/image/image_optim_minifier.rb +90 -0
  20. data/lib/inkcite/image/mozjpeg_minifier.rb +92 -0
  21. data/lib/inkcite/mailer.rb +201 -112
  22. data/lib/inkcite/minifier.rb +2 -146
  23. data/lib/inkcite/post_processor.rb +13 -0
  24. data/lib/inkcite/renderer.rb +19 -0
  25. data/lib/inkcite/renderer/background.rb +53 -14
  26. data/lib/inkcite/renderer/base.rb +29 -15
  27. data/lib/inkcite/renderer/button.rb +1 -1
  28. data/lib/inkcite/renderer/carousel.rb +245 -0
  29. data/lib/inkcite/renderer/container_base.rb +10 -0
  30. data/lib/inkcite/renderer/div.rb +1 -3
  31. data/lib/inkcite/renderer/fireworks.rb +54 -40
  32. data/lib/inkcite/renderer/footnote.rb +22 -2
  33. data/lib/inkcite/renderer/image.rb +11 -0
  34. data/lib/inkcite/renderer/image_base.rb +3 -6
  35. data/lib/inkcite/renderer/in_browser.rb +4 -0
  36. data/lib/inkcite/renderer/link.rb +39 -12
  37. data/lib/inkcite/renderer/mobile_image.rb +1 -1
  38. data/lib/inkcite/renderer/responsive.rb +9 -1
  39. data/lib/inkcite/renderer/social.rb +31 -3
  40. data/lib/inkcite/renderer/special_effect.rb +22 -13
  41. data/lib/inkcite/renderer/sup.rb +32 -0
  42. data/lib/inkcite/renderer/table_base.rb +3 -0
  43. data/lib/inkcite/renderer/topic.rb +76 -0
  44. data/lib/inkcite/renderer/trademark.rb +47 -0
  45. data/lib/inkcite/renderer/video_preview.rb +3 -2
  46. data/lib/inkcite/uploader.rb +2 -3
  47. data/lib/inkcite/util.rb +51 -0
  48. data/lib/inkcite/version.rb +1 -1
  49. data/lib/inkcite/view.rb +140 -54
  50. data/lib/inkcite/view/context.rb +1 -31
  51. data/lib/inkcite/view/media_query.rb +6 -0
  52. data/test/animation_spec.rb +7 -0
  53. data/test/parser_spec.rb +1 -1
  54. data/test/renderer/background_spec.rb +16 -12
  55. data/test/renderer/div_spec.rb +11 -0
  56. data/test/renderer/footnote_spec.rb +5 -1
  57. data/test/renderer/image_spec.rb +51 -28
  58. data/test/renderer/link_spec.rb +20 -8
  59. data/test/renderer/lorem_spec.rb +2 -2
  60. data/test/renderer/mobile_image_spec.rb +6 -0
  61. data/test/renderer/mobile_style_spec.rb +3 -3
  62. data/test/renderer/redacted_spec.rb +2 -2
  63. data/test/renderer/social_spec.rb +6 -6
  64. data/test/renderer/table_spec.rb +4 -0
  65. data/test/renderer/topic_spec.rb +28 -0
  66. data/test/renderer/trademark_spec.rb +40 -0
  67. data/test/renderer/video_preview_spec.rb +1 -1
  68. data/test/test_helper.rb +14 -0
  69. data/test/view_spec.rb +4 -0
  70. metadata +26 -12
  71. data/assets/init/image_optim.yml +0 -37
@@ -5,42 +5,12 @@ module Inkcite
5
5
  # engine without exposing all of the view's attributes.
6
6
  class Context
7
7
 
8
- delegate :browser?, :development?, :email?, :environment, :format, :production?, :preview?, :version, :to => :view
8
+ delegate :browser?, :development?, :email?, :environment, :format, :helper, :once?, :production?, :preview?, :version, :to => :view
9
9
 
10
10
  def initialize view
11
11
  @view = view
12
12
  end
13
13
 
14
- # Defines a new helper via ERB, which allows designers to keep helper
15
- # markup alongside the usage of it inside of partial. Helps keep
16
- # code clean and prevents helper.tsv pollution for one-offs
17
- def helper tag, open, close=nil
18
-
19
- tag = tag.to_sym
20
-
21
- # The config object holds the defined helpers
22
- config = @view.config
23
-
24
- # Warn the user if the helper is already defined.
25
- view.error("Helper '#{tag}' already defined", :open => open, :close => close) unless config[tag].nil?
26
-
27
- config[tag] = open.to_s
28
- config[:"/#{tag}"] = close.to_s
29
-
30
- end
31
-
32
- def once? key
33
-
34
- # Initialize the 'once' data hash which maps
35
- @view.data[:once] ||= {}
36
-
37
- # True if this is the first time we've encountered this key.
38
- first_time = @view.data[:once][key].nil?
39
- @view.data[:once][key] = true if first_time
40
-
41
- first_time
42
- end
43
-
44
14
  def method_missing(m, *args, &block)
45
15
  if m[-1] == QUESTION_MARK
46
16
  start_at = m[0] == UNDERSCORE ? 1 : 0
@@ -45,6 +45,12 @@ module Inkcite
45
45
 
46
46
  css = []
47
47
  css << "@media only screen and (max-width: #{Inkcite::Renderer::px(@max_width)}) {"
48
+
49
+ # Remove extraneous right-margin on Gmail by applying this to the
50
+ # body via a class selector.
51
+ # https://litmus.com/community/discussions/5913-new-gmail-app-not-respect-full-width
52
+ css << 'u + .body { min-width: 100vw; }'
53
+
48
54
  css += active_styles.collect(&:to_css)
49
55
  css << '}'
50
56
 
@@ -48,6 +48,13 @@ describe Inkcite::Animation do
48
48
  keyframe.to_css('').must_equal('25%, 40.9% { top:-15% }')
49
49
  end
50
50
 
51
+ it 'supports keyframe end percent' do
52
+ keyframe = Inkcite::Animation::Keyframe.new(38.3, @view)
53
+ keyframe.end_percent = 42.3
54
+ keyframe[:top] = '-15%'
55
+ keyframe.to_css('').must_equal('38.3%, 42.3% { top:-15% }')
56
+ end
57
+
51
58
  it 'reports when an animation is blank' do
52
59
  anim = Inkcite::Animation.new('snowflake7', @view)
53
60
  anim.blank?.must_equal(true)
@@ -70,7 +70,7 @@ describe Inkcite::Parser do
70
70
  Inkcite::Parser.each('{ok}') { |e| '{ok}' }
71
71
  false.must_equal(true) # Intentional, should never be thrown.
72
72
  rescue Exception => e
73
- e.message.must_equal("Infinite replacement detected: 1000 {ok}")
73
+ e.message.must_equal('Infinite replacement detected: 1000 {ok}')
74
74
  end
75
75
  end
76
76
 
@@ -6,53 +6,57 @@ describe Inkcite::Renderer::Background do
6
6
 
7
7
  it 'warns when an image is missing' do
8
8
  Inkcite::Renderer.render('{background src=missing.jpg}', @view)
9
- @view.errors.must_include('Missing image (line 0) [src=missing.jpg]')
9
+ assert_error @view, 'Missing image', 'src=missing.jpg'
10
10
  end
11
11
 
12
12
  it 'warns when an outlook-specific image is missing' do
13
13
  Inkcite::Renderer.render('{background outlook-src=also-missing.jpg}', @view)
14
- @view.errors.must_include('Missing image (line 0) [src=also-missing.jpg]')
14
+ assert_error @view, 'Missing image', 'src=also-missing.jpg'
15
15
  end
16
16
 
17
17
  it 'defaults to filling the available horizontal space' do
18
- Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
18
+ Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
19
19
  end
20
20
 
21
21
  it 'supports 100% width' do
22
- Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png width=100%}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
22
+ Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png width=100%}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
23
23
  end
24
24
 
25
25
  it 'supports fill width' do
26
- Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png width=fill}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
26
+ Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png width=fill}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
27
27
  end
28
28
 
29
29
  it 'supports an optional width in pixels' do
30
- Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png width=120}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=120><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="width:120px" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
30
+ Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png width=120}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=120><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="width:120px" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
31
31
  end
32
32
 
33
33
  it 'supports an optional height in pixels' do
34
- Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png bgcolor=#7bceeb height=92 width=120}{/background}', @view).must_equal('<table bgcolor=#7bceeb border=0 cellpadding=0 cellspacing=0 height=92 style="background:#7bceeb url(https://i.imgur.com/YJOX1PC.png)" width=120><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="height:92px;width:120px" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill color="#7bceeb" src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
34
+ Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png bgcolor=#7bceeb height=92 width=120}{/background}', @view).must_equal('<table bgcolor=#7bceeb border=0 cellpadding=0 cellspacing=0 style="background:#7bceeb url(https://i.imgur.com/YJOX1PC.png)" width=120><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="height:92px;width:120px" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill color="#7bceeb" src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td height=92></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
35
35
  end
36
36
 
37
37
  it 'supports an optional background color' do
38
- Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png bgcolor=#7bceeb width=120}{/background}', @view).must_equal('<table bgcolor=#7bceeb border=0 cellpadding=0 cellspacing=0 style="background:#7bceeb url(https://i.imgur.com/YJOX1PC.png)" width=120><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="width:120px" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill color="#7bceeb" src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
38
+ Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png bgcolor=#7bceeb width=120}{/background}', @view).must_equal('<table bgcolor=#7bceeb border=0 cellpadding=0 cellspacing=0 style="background:#7bceeb url(https://i.imgur.com/YJOX1PC.png)" width=120><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="width:120px" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill color="#7bceeb" src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
39
39
  end
40
40
 
41
41
  it 'supports the font attribute' do
42
- Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png font=large align=center}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div style="color:#ff0000;font-family:serif;font-size:24px;font-weight:bold;line-height:24px;text-align:center"></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
42
+ Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png font=large align=center}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td align=center style="color:#ff0000;font-family:serif;font-size:24px;font-weight:bold;line-height:24px"></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
43
43
  end
44
44
 
45
45
  it 'supports font-related attributes' do
46
- Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png font-size=18 line-height=27}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div style="font-size:18px;line-height:27px"></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
46
+ Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png font-size=18 line-height=27}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td style="font-size:18px;line-height:27px"></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
47
47
  end
48
48
 
49
49
  it 'supports a custom mobile background' do
50
- Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png mobile-src="https://i.imgur.com/YJOX1PC-mobile.png" mobile-background-position="top" mobile-background-size="cover"}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 class="m1" style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
50
+ Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png mobile-src="https://i.imgur.com/YJOX1PC-mobile.png" mobile-background-position="top" mobile-background-size="cover"}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 class="m1" style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
51
51
  @view.media_query.find_by_klass('m1').declaration_string.must_equal('background:url(https://i.imgur.com/YJOX1PC-mobile.png) top / cover no-repeat !important')
52
52
  end
53
53
 
54
+ it 'supports padding' do
55
+ Inkcite::Renderer.render('{background src=background.jpg padding=15}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(images/background.jpg)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="images/background.jpg" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td class="hide" width=15>&nbsp;</td><td><div class="hide" style="font-size:15px;height:15px;line-height:15px">&nbsp;</div><div class="hide" style="font-size:15px;height:15px;line-height:15px">&nbsp;</div></td><td class="hide" width=15>&nbsp;</td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
56
+ end
57
+
54
58
  it 'supports mobile padding' do
55
- Inkcite::Renderer.render('{background src=background.jpg mobile-padding=15}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(images/background.jpg)" width=100%><tr><td class="m1"><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="images/background.jpg" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
59
+ Inkcite::Renderer.render('{background src=background.jpg mobile-padding=15}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(images/background.jpg)" width=100%><tr><td class="m1"><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="images/background.jpg" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div><table border=0 cellpadding=0 cellspacing=0 width=100%><tr><td></td></tr></table></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
56
60
  @view.media_query.find_by_klass('m1').declaration_string.must_equal('padding:15px')
57
61
  end
58
62
 
@@ -147,4 +147,15 @@ describe Inkcite::Renderer::Div do
147
147
  @view.media_query.find_by_klass('m1').declarations.must_match('display:block')
148
148
  end
149
149
 
150
+ it 'supports mobile height' do
151
+ Inkcite::Renderer.render('{div mobile-height=215}{/div}', @view).must_equal('<div class="m1"></div>')
152
+ @view.media_query.find_by_klass('m1').declarations.must_match('height:215px')
153
+ end
154
+
155
+
156
+ it 'supports mobile height override' do
157
+ Inkcite::Renderer.render('{div height=63 mobile-height=182}{/div}', @view).must_equal('<div class="m1" style="height:63px"></div>')
158
+ @view.media_query.find_by_klass('m1').declarations.must_match('height:182px !important')
159
+ end
160
+
150
161
  end
@@ -6,7 +6,7 @@ describe Inkcite::Renderer::Footnote do
6
6
 
7
7
  it 'requires text' do
8
8
  Inkcite::Renderer.render('({footnote symbol="†"})', @view)
9
- @view.errors.must_include('Footnote requires text attribute (line 0) [id=, symbol=†]')
9
+ assert_error @view, 'Footnote requires text attribute', 'symbol=†'
10
10
  end
11
11
 
12
12
  it 'can have a custom symbol' do
@@ -54,4 +54,8 @@ describe Inkcite::Renderer::Footnote do
54
54
  Inkcite::Renderer.render('({footnote text="EPA-estimated fuel economy."}) {footnotes tmpl="[$symbol$] $text$\n\n"}', text_view).must_equal("(1) [1] EPA-estimated fuel economy.\n\n")
55
55
  end
56
56
 
57
+ it 'supports the once attribute' do
58
+ Inkcite::Renderer.render('({footnote id="leatherman" text="Leatherman is a trademark of Leatherman Tool Group, inc." once})({footnote id="leatherman" once})', @view).must_equal("(1)()")
59
+ end
60
+
57
61
  end
@@ -6,69 +6,69 @@ describe Inkcite::Renderer::Image do
6
6
 
7
7
  it 'warns when an image is missing' do
8
8
  Inkcite::Renderer.render('{img src=missing.jpg}', @view)
9
- @view.errors.must_include('Missing image (line 0) [src=missing.jpg]')
9
+ assert_error(@view, 'Missing image', 'src=missing.jpg')
10
10
  end
11
11
 
12
12
  it 'warns when image dimesions are missing' do
13
13
  Inkcite::Renderer.render('{img src=inkcite.jpg}', @view)
14
- @view.errors.must_include('Missing image dimensions (line 0) [src=inkcite.jpg]')
14
+ assert_error(@view, 'Missing image dimensions', 'src=inkcite.jpg')
15
15
  end
16
16
 
17
17
  it 'substitutes a placeholder for a missing image of sufficient size' do
18
18
  @view.config[Inkcite::Email::IMAGE_PLACEHOLDERS] = true
19
- Inkcite::Renderer.render('{img src=missing.jpg height=50 width=100}', @view).must_equal('<img border=0 height=50 src="http://placeholdit.imgix.net/~text?fm=jpg&h=50&txt=missing.jpg%0A%28100%C3%9750%29&txtsize=18&txttrack=0&w=100" style="display:block" width=100>')
19
+ Inkcite::Renderer.render('{img src=missing.jpg height=50 width=100}', @view).must_equal('<img border=0 height=50 id="OWATemporaryImageDivContainer1" src="http://placeholdit.imgix.net/~text?fm=jpg&h=50&txt=missing.jpg%0A%28100%C3%9750%29&txtsize=18&txttrack=0&w=100" style="display:block" width=100>')
20
20
  end
21
21
 
22
22
  it 'has configurable placeholder text' do
23
23
  @view.config[Inkcite::Email::IMAGE_PLACEHOLDERS] = true
24
- Inkcite::Renderer.render('{img src=missing.jpg height=50 width=100 fpo="F P O"}', @view).must_equal('<img border=0 height=50 src="http://placeholdit.imgix.net/~text?fm=jpg&h=50&txt=F+P+O%0A%28100%C3%9750%29&txtsize=18&txttrack=0&w=100" style="display:block" width=100>')
24
+ Inkcite::Renderer.render('{img src=missing.jpg height=50 width=100 fpo="F P O"}', @view).must_equal('<img border=0 height=50 id="OWATemporaryImageDivContainer1" src="http://placeholdit.imgix.net/~text?fm=jpg&h=50&txt=F+P+O%0A%28100%C3%9750%29&txtsize=18&txttrack=0&w=100" style="display:block" width=100>')
25
25
  end
26
26
 
27
27
  it 'does not substitute placeholders for small images' do
28
28
  @view.config[Inkcite::Email::IMAGE_PLACEHOLDERS] = true
29
- Inkcite::Renderer.render('{img src=missing.jpg height=5 width=15}', @view).must_equal('<img border=0 height=5 src="missing.jpg" style="display:block" width=15>')
29
+ Inkcite::Renderer.render('{img src=missing.jpg height=5 width=15}', @view).must_equal('<img border=0 height=5 id="OWATemporaryImageDivContainer1" src="missing.jpg" style="display:block" width=15>')
30
30
  end
31
31
 
32
32
  it 'does not alter externally referenced images' do
33
- Inkcite::Renderer.render('{img src=://i.imgur.com/YJOX1PC.png height=5 width=15}', @view).must_equal('<img border=0 height=5 src="://i.imgur.com/YJOX1PC.png" style="display:block" width=15>')
33
+ Inkcite::Renderer.render('{img src=://i.imgur.com/YJOX1PC.png height=5 width=15}', @view).must_equal('<img border=0 height=5 id="OWATemporaryImageDivContainer1" src="://i.imgur.com/YJOX1PC.png" style="display:block" width=15>')
34
34
  end
35
35
 
36
36
  it 'has configurable dimensions' do
37
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73}', @view).must_equal('<img border=0 height=73 src="images/inkcite.jpg" style="display:block" width=73>')
37
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73}', @view).must_equal('<img border=0 height=73 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block" width=73>')
38
38
  end
39
39
 
40
40
  it 'has configurable background color' do
41
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 bgcolor=#f00}', @view).must_equal('<img border=0 height=73 src="images/inkcite.jpg" style="background-color:#ff0000;display:block" width=73>')
41
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 bgcolor=#f00}', @view).must_equal('<img border=0 height=73 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="background-color:#ff0000;display:block" width=73>')
42
42
  end
43
43
 
44
44
  it 'has an inline display helper' do
45
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 display=inline}', @view).must_equal('<img align=absmiddle border=0 height=73 src="images/inkcite.jpg" style="display:inline;vertical-align:middle" width=73>')
45
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 display=inline}', @view).must_equal('<img align=absmiddle border=0 height=73 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:inline;vertical-align:middle" width=73>')
46
46
  end
47
47
 
48
48
  it 'has no font styling unless specified' do
49
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 alt="Inkcite Avatar"}', @view).must_equal('<img alt="Inkcite Avatar" border=0 height=73 src="images/inkcite.jpg" style="display:block" width=73>')
49
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 alt="Inkcite Avatar"}', @view).must_equal('<img alt="Inkcite Avatar" border=0 height=73 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block" width=73>')
50
50
  end
51
51
 
52
52
  it 'supports blank alt text' do
53
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 alt=""}', @view).must_equal('<img alt="" border=0 height=73 src="images/inkcite.jpg" style="display:block" width=73>')
53
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 alt=""}', @view).must_equal('<img alt="" border=0 height=73 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block" width=73>')
54
54
  end
55
55
 
56
56
  it 'supports configurable font attributes' do
57
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font="small" alt="Inkcite Avatar"}', @view).must_equal('<img alt="Inkcite Avatar" border=0 height=73 src="images/inkcite.jpg" style="color:#cccccc;display:block;font-size:11px" width=73>')
57
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font="small" alt="Inkcite Avatar"}', @view).must_equal('<img alt="Inkcite Avatar" border=0 height=73 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="color:#cccccc;display:block;font-size:11px" width=73>')
58
58
  end
59
59
 
60
60
  it 'has configurable font size' do
61
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font-size=18 alt="Inkcite Avatar"}', @view).must_equal('<img alt="Inkcite Avatar" border=0 height=73 src="images/inkcite.jpg" style="display:block;font-size:18px" width=73>')
61
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font-size=18 alt="Inkcite Avatar"}', @view).must_equal('<img alt="Inkcite Avatar" border=0 height=73 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block;font-size:18px" width=73>')
62
62
  end
63
63
 
64
64
  it 'supports font-size override' do
65
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font="small" font-size=18 alt="Inkcite Avatar"}', @view).must_equal('<img alt="Inkcite Avatar" border=0 height=73 src="images/inkcite.jpg" style="color:#cccccc;display:block;font-size:18px" width=73>')
65
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font="small" font-size=18 alt="Inkcite Avatar"}', @view).must_equal('<img alt="Inkcite Avatar" border=0 height=73 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="color:#cccccc;display:block;font-size:18px" width=73>')
66
66
  end
67
67
 
68
68
  it 'ignores font attributes when alt text is not present' do
69
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font=large}', @view).must_equal('<img border=0 height=73 src="images/inkcite.jpg" style="display:block" width=73>')
70
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font-size=24}', @view).must_equal('<img border=0 height=73 src="images/inkcite.jpg" style="display:block" width=73>')
71
- Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 text-shadow=#f00}', @view).must_equal('<img border=0 height=73 src="images/inkcite.jpg" style="display:block" width=73>')
69
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font=large}', @view).must_equal('<img border=0 height=73 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block" width=73>')
70
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 font-size=24}', @view).must_equal('<img border=0 height=73 id="OWATemporaryImageDivContainer2" src="images/inkcite.jpg" style="display:block" width=73>')
71
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=73 width=73 text-shadow=#f00}', @view).must_equal('<img border=0 height=73 id="OWATemporaryImageDivContainer3" src="images/inkcite.jpg" style="display:block" width=73>')
72
72
  end
73
73
 
74
74
  it 'includes a timestamp when cache-busting is enabled' do
@@ -76,39 +76,62 @@ describe Inkcite::Renderer::Image do
76
76
 
77
77
  html = Inkcite::Renderer.render('{img src=inkcite.jpg}', @view)
78
78
 
79
- html[0,47].must_equal('<img border=0 height=0 src="images/inkcite.jpg?')
80
- html[47,10].must_match(/[0-9]{10,}/)
81
- html[57..-1].must_equal('" style="display:block" width=0>')
79
+ html[0, 74].must_equal('<img border=0 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg?')
80
+ html[74, 10].must_match(/[0-9]{10,}/)
81
+ html[84..-1].must_equal('" style="display:block">')
82
82
  end
83
83
 
84
84
  it 'can substitute a different image on mobile' do
85
- Inkcite::Renderer.render('{img src=inkcite.jpg mobile-src=inkcite-mobile.jpg height=75 width=125}', @view).must_equal('<img border=0 class="i01" height=75 src="images/inkcite.jpg" style="display:block" width=125>')
85
+ Inkcite::Renderer.render('{img src=inkcite.jpg mobile-src=inkcite-mobile.jpg height=75 id="OWATemporaryImageDivContainer1" width=125}', @view).must_equal('<img border=0 class="i01" height=75 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block" width=125>')
86
86
  @view.media_query.find_by_klass('i01').to_css.must_equal('img.i01 { content: url("images/inkcite-mobile.jpg") !important; }')
87
87
  end
88
88
 
89
89
  it 'supports fluid-hybrid desktop and style' do
90
- Inkcite::Renderer.render('{img src=inkcite.jpg height=200 width=325 mobile=fluid}', @view).must_equal('<img border=0 src="images/inkcite.jpg" style="display:block;height:auto;max-width:325px;width:100%" width=325>')
90
+ Inkcite::Renderer.render('{img src=inkcite.jpg height=200 width=325 mobile=fluid}', @view).must_equal('<img border=0 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block;height:auto;max-width:325px;width:100%" width=325>')
91
91
  end
92
92
 
93
93
  it 'supports multi-line alt text' do
94
- Inkcite::Renderer.render(%Q({img src=inkcite.jpg height=150 width=100 font=none alt="Multiple\nLine\nAlt\nText"}), @view).must_equal(%Q(<img alt="Multiple \nLine \nAlt \nText" border=0 height=150 src="images/inkcite.jpg" style="display:block;white-space:pre" width=100>))
94
+ Inkcite::Renderer.render(%Q({img src=inkcite.jpg height=150 width=100 font=none alt="Multiple\nLine\nAlt\nText"}), @view).must_equal(%Q(<img alt="Multiple \nLine \nAlt \nText" border=0 height=150 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block;white-space:pre" width=100>))
95
95
  end
96
96
 
97
97
  it 'supports virtual (\n) multi-line alt text' do
98
- Inkcite::Renderer.render(%q({img src=inkcite.jpg height=150 width=100 font=none alt="Multiple\nLine\nAlt\nText"}), @view).must_equal(%Q(<img alt="Multiple \nLine \nAlt \nText" border=0 height=150 src="images/inkcite.jpg" style="display:block;white-space:pre" width=100>))
98
+ Inkcite::Renderer.render(%q({img src=inkcite.jpg height=150 width=100 font=none alt="Multiple\nLine\nAlt\nText"}), @view).must_equal(%Q(<img alt="Multiple \nLine \nAlt \nText" border=0 height=150 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block;white-space:pre" width=100>))
99
99
  end
100
100
 
101
101
  it 'supports multi-line alt text in production, too' do
102
- Inkcite::Renderer.render(%Q({img src=inkcite.jpg height=150 width=100 font=none alt="Multiple\nLine\nAlt\nText"}), Inkcite::Email.new('test/project/').view(:production, :email)).must_equal(%Q(<img alt="Multiple \nLine \nAlt \nText" border=0 height=150 src="http://production.imagehost.com/emails/myemail/inkcite.jpg" style="display:block;white-space:pre" width=100>))
103
- Inkcite::Renderer.render(%q({img src=inkcite.jpg height=150 width=100 font=none alt="Multiple\nLine\nAlt\nText"}), Inkcite::Email.new('test/project/').view(:production, :email)).must_equal(%Q(<img alt="Multiple \nLine \nAlt \nText" border=0 height=150 src="http://production.imagehost.com/emails/myemail/inkcite.jpg" style="display:block;white-space:pre" width=100>))
102
+ Inkcite::Renderer.render(%Q({img src=inkcite.jpg height=150 width=100 font=none alt="Multiple\nLine\nAlt\nText"}), Inkcite::Email.new('test/project/').view(:production, :email)).must_equal(%Q(<img alt="Multiple \nLine \nAlt \nText" border=0 height=150 id="OWATemporaryImageDivContainer1" src="http://production.imagehost.com/emails/myemail/inkcite.jpg" style="display:block;white-space:pre" width=100>))
103
+ Inkcite::Renderer.render(%q({img src=inkcite.jpg height=150 width=100 font=none alt="Multiple\nLine\nAlt\nText"}), Inkcite::Email.new('test/project/').view(:production, :email)).must_equal(%Q(<img alt="Multiple \nLine \nAlt \nText" border=0 height=150 id="OWATemporaryImageDivContainer1" src="http://production.imagehost.com/emails/myemail/inkcite.jpg" style="display:block;white-space:pre" width=100>))
104
104
  end
105
105
 
106
106
  it 'removes HTML from alt text' do
107
- Inkcite::Renderer.render(%q({img src=inkcite.jpg height=150 width=100 alt="HTML <i>is not</i> allowed in alt text"}), @view).must_equal(%q(<img alt="HTML is not allowed in alt text" border=0 height=150 src="images/inkcite.jpg" style="display:block" width=100>))
107
+ Inkcite::Renderer.render(%q({img src=inkcite.jpg height=150 width=100 alt="HTML <i>is not</i> allowed in alt text"}), @view).must_equal(%q(<img alt="HTML is not allowed in alt text" border=0 height=150 id="OWATemporaryImageDivContainer1" src="images/inkcite.jpg" style="display:block" width=100>))
108
108
  end
109
109
 
110
110
  it 'can show a different image in Outlook' do
111
- Inkcite::Renderer.render(%q({img src=animated.gif outlook-src=static.jpg height=150 width=100 alt="Don't repeat yourself"}), @view).must_equal(%q(<!--[if mso]><img alt="Don't repeat yourself" border=0 height=150 src="images/static.jpg" style="display:block" width=100><![endif]--><!--[if !mso]><!-- --><img alt="Don't repeat yourself" border=0 height=150 src="images/animated.gif" style="display:block" width=100><!--<![endif]-->))
111
+ Inkcite::Renderer.render(%q({img src=animated.gif outlook-src=static.jpg height=150 width=100 alt="Don't repeat yourself"}), @view).must_equal(%q(<!--[if mso]><img alt="Don't repeat yourself" border=0 height=150 id="OWATemporaryImageDivContainer1" src="images/static.jpg" style="display:block" width=100><![endif]--><!--[if !mso]><!-- --><img alt="Don't repeat yourself" border=0 height=150 id="OWATemporaryImageDivContainer1" src="images/animated.gif" style="display:block" width=100><!--<![endif]-->))
112
+ end
113
+
114
+ it 'supports mobile margins' do
115
+ Inkcite::Renderer.render(%q({img src=logo.jpg height=75 width=75 mobile-margin-bottom=15}), @view).must_equal(%q(<img border=0 class="m1" height=75 id="OWATemporaryImageDivContainer1" src="images/logo.jpg" style="display:block" width=75>))
116
+ @view.media_query.find_by_klass('m1').to_css.must_equal('img.m1 { margin-bottom:15px }')
117
+ end
118
+
119
+ it 'supports mobile-max-width in pixels' do
120
+ Inkcite::Renderer.render(%q({img src=logo.jpg height=75 width=75 mobile="fill" mobile-max-width=150}), @view).must_equal(%q(<img border=0 class="fill m1" height=75 id="OWATemporaryImageDivContainer1" src="images/logo.jpg" style="display:block" width=75>))
121
+ @view.media_query.find_by_klass('m1').to_css.must_equal('img.m1 { max-width:150px }')
122
+ end
123
+
124
+ it 'supports mobile-max-width as a percent' do
125
+ Inkcite::Renderer.render(%q({img src=logo.jpg height=75 width=75 mobile="fill" mobile-max-width=80%}), @view).must_equal(%q(<img border=0 class="fill m1" height=75 id="OWATemporaryImageDivContainer1" src="images/logo.jpg" style="display:block" width=75>))
126
+ @view.media_query.find_by_klass('m1').to_css.must_equal('img.m1 { max-width:80% }')
127
+ end
128
+
129
+ it 'supports max-height' do
130
+ Inkcite::Renderer.render(%q({img src=logo.jpg height=75 width=75 max-height=150}), @view).must_equal(%q(<img border=0 height=75 id="OWATemporaryImageDivContainer1" src="images/logo.jpg" style="display:block;max-height:150px" width=75>))
131
+ end
132
+
133
+ it 'supports max-height of zero (needed for carousels)' do
134
+ Inkcite::Renderer.render(%q({img src=logo.jpg height=75 width=75 max-height=0}), @view).must_equal(%q(<img border=0 height=75 id="OWATemporaryImageDivContainer1" src="images/logo.jpg" style="display:block;max-height:0" width=75>))
112
135
  end
113
136
 
114
137
  end
@@ -9,38 +9,50 @@ describe Inkcite::Renderer::Link do
9
9
  end
10
10
 
11
11
  it 'can be configured to tag all links' do
12
- @view.config[:'tag-links'] = "tag=inkcite|{id}"
12
+ @view.config[:'tag-links'] = 'tag=inkcite|{id}'
13
13
  Inkcite::Renderer.render('{a id="litmus" href="http://litmus.com"}Test Emails Here{/a}', @view).must_equal('<a href="http://litmus.com?tag=inkcite|litmus" style="color:#0099cc;text-decoration:none" target=_blank>Test Emails Here</a>')
14
14
  end
15
15
 
16
16
  it 'can be configured to tag links to specific domains' do
17
- @view.config[:'tag-links'] = "tag=inkcite|{id}"
17
+ @view.config[:'tag-links'] = 'tag=inkcite|{id}'
18
18
  @view.config[:'tag-links-domain'] = 'inkceptional.com'
19
19
  Inkcite::Renderer.render('{a id="blog" href="http://blog.inkceptional.com"}Our blog{/a}', @view).must_equal('<a href="http://blog.inkceptional.com?tag=inkcite|blog" style="color:#0099cc;text-decoration:none" target=_blank>Our blog</a>')
20
20
  Inkcite::Renderer.render('{a id="litmus" href="http://litmus.com"}Test Emails Here{/a}', @view).must_equal('<a href="http://litmus.com" style="color:#0099cc;text-decoration:none" target=_blank>Test Emails Here</a>')
21
21
  end
22
22
 
23
+ it 'can be configured to tag links to at different domains' do
24
+ @view.config[:'tag-links'] = { 'inkceptional.com' => 'tag=inkcite|{id}', 'blog.inkceptional.com' => 'campaign=blog' }
25
+ Inkcite::Renderer.render('{a id="blog" href="http://blog.inkceptional.com"}Our blog{/a}', @view).must_equal('<a href="http://blog.inkceptional.com?campaign=blog" style="color:#0099cc;text-decoration:none" target=_blank>Our blog</a>')
26
+ Inkcite::Renderer.render('{a id="litmus" href="http://litmus.com"}Test Emails Here{/a}', @view).must_equal('<a href="http://litmus.com" style="color:#0099cc;text-decoration:none" target=_blank>Test Emails Here</a>')
27
+ Inkcite::Renderer.render('{a id="cp" href="http://client-preview.inkceptional.com"}Client Previews{/a}', @view).must_equal('<a href="http://client-preview.inkceptional.com?tag=inkcite|cp" style="color:#0099cc;text-decoration:none" target=_blank>Client Previews</a>')
28
+ end
29
+
23
30
  it 'will not tag mailto: links' do
24
- @view.config[:'tag-links'] = "tag=inkcite|{id}"
31
+ @view.config[:'tag-links'] = 'tag=inkcite|{id}'
25
32
  Inkcite::Renderer.render('{a id="contact-us" href="mailto:some.email@some.where"}Contact Us{/a}', @view).must_equal('<a href="mailto:some.email@some.where" style="color:#0099cc;text-decoration:none">Contact Us</a>')
26
33
  end
27
34
 
28
35
  it 'will not tag links that lead to an element in the email' do
29
- @view.config[:'tag-links'] = "tag=inkcite|{id}"
36
+ @view.config[:'tag-links'] = 'tag=inkcite|{id}'
30
37
  Inkcite::Renderer.render('{a href="#news"}Latest News{/a}', @view).must_equal('<a href="#news" style="color:#0099cc;text-decoration:none">Latest News</a>')
31
38
  end
32
39
 
33
40
  it 'tags a reused link once and only once' do
34
- @view.config[:'tag-links'] = "tag=inkcite|{id}"
41
+ @view.config[:'tag-links'] = 'tag=inkcite|{id}'
35
42
  @view.links_tsv['litmus'] = 'http://litmus.com'
36
43
 
37
44
  Inkcite::Renderer.render('{a id="litmus"}Test Emails Here{/a}{a id="litmus"}Also Here{/a}', @view).must_equal('<a href="http://litmus.com?tag=inkcite|litmus" style="color:#0099cc;text-decoration:none" target=_blank>Test Emails Here</a><a href="http://litmus.com?tag=inkcite|litmus" style="color:#0099cc;text-decoration:none" target=_blank>Also Here</a>')
38
45
 
39
46
  end
40
47
 
48
+ it 'accepts no-tag to prevent tagging of a link' do
49
+ @view.config[:'tag-links'] = { 'inkceptional.com' => 'tag=inkcite|{id}' }
50
+ Inkcite::Renderer.render('{a id="blog" href="http://blog.inkceptional.com" no-tag}Our blog{/a}', @view).must_equal('<a href="http://blog.inkceptional.com" style="color:#0099cc;text-decoration:none" target=_blank>Our blog</a>')
51
+ end
52
+
41
53
  it 'raises a warning and generates an ID if one is not present' do
42
54
  Inkcite::Renderer.render('{a href="http://inkceptional.com"}Click Here{/a}', @view).must_equal('<a href="http://inkceptional.com" style="color:#0099cc;text-decoration:none" target=_blank>Click Here</a>')
43
- @view.errors.must_include('Link missing ID (line 0) [href=http://inkceptional.com]')
55
+ assert_error @view, 'Link missing ID', 'href="http://inkceptional.com"'
44
56
  end
45
57
 
46
58
  it 'increments its automatically generated link ID' do
@@ -87,12 +99,12 @@ describe Inkcite::Renderer::Link do
87
99
 
88
100
  it 'detects invalid URLs' do
89
101
  Inkcite::Renderer.render(%Q({a id="oops" href="http://ink\nceptional.com"}), @view)
90
- @view.errors.must_include(%Q(Link href appears to be invalid (line 0) [id=oops, href=http://ink\nceptional.com]))
102
+ assert_error(@view, 'Link href appears to be invalid', 'id=oops', "href=http://ink\nceptional.com")
91
103
  end
92
104
 
93
105
  it 'accepts invalid URLs if forced' do
94
106
  Inkcite::Renderer.render(%Q({a id="oops" href="http://ink\nceptional.com" force}), @view)
95
- @view.errors.must_be_nil
107
+ assert_no_errors @view
96
108
  end
97
109
 
98
110
  it 'supports the block attribute' do
@@ -10,12 +10,12 @@ describe Inkcite::Renderer::Lorem do
10
10
 
11
11
  it 'triggers an error when included' do
12
12
  Inkcite::Renderer.render('{lorem}', @view)
13
- @view.errors.must_include('Email contains Lorem Ipsum (line 0)')
13
+ assert_error @view, 'Email contains Lorem Ipsum [markup={lorem}]'
14
14
  end
15
15
 
16
16
  it 'does not trigger an error when included and forced' do
17
17
  Inkcite::Renderer.render('{lorem force}', @view)
18
- @view.errors.must_be_nil
18
+ assert_no_errors @view
19
19
  end
20
20
 
21
21
  end
@@ -16,4 +16,10 @@ describe Inkcite::Renderer::MobileImage do
16
16
  @view.media_query.find_by_klass('i01').to_css.must_equal('span.i01 { background-image:url("http://placeholdit.imgix.net/~text?fm=jpg&h=100&txt=inkcite-mobile.jpg%0A%28300%C3%97100%29&txtsize=18&txttrack=0&w=300");height:100px;width:300px }')
17
17
  end
18
18
 
19
+ it 'supports mobile margins' do
20
+ Inkcite::Renderer.render('{mobile-img src=inkcite-mobile.jpg height=100 width=300 margin-bottom=15 margin-left=15}', @view).must_equal('<span class="i01 img"></span>')
21
+ @view.media_query.find_by_klass('i01').to_css.must_equal('span.i01 { background-image:url("images/inkcite-mobile.jpg");height:100px;margin-bottom:15px;margin-left:15px;width:300px }')
22
+ end
23
+
24
+
19
25
  end
@@ -6,18 +6,18 @@ describe Inkcite::Renderer::MobileStyle do
6
6
 
7
7
  it 'requires a class name' do
8
8
  Inkcite::Renderer.render('{mobile-style}', @view).must_equal('')
9
- @view.errors.must_include('Declaring a mobile style requires a name attribute (line 0)')
9
+ assert_error(@view, 'Declaring a mobile style requires a name attribute')
10
10
  end
11
11
 
12
12
  it 'requires a style declaration' do
13
13
  Inkcite::Renderer.render('{mobile-style name="slider"}', @view).must_equal('')
14
- @view.errors.must_include('Declaring a mobile style requires a style attribute (line 0) [name=slider]')
14
+ assert_error(@view, 'Declaring a mobile style requires a style attribute', 'name=slider')
15
15
  end
16
16
 
17
17
  it 'raises a warning if the class name is not unique' do
18
18
  Inkcite::Renderer.render('{mobile-style name="outlined" style="border: 1px solid #f00"}', @view).must_equal('')
19
19
  Inkcite::Renderer.render('{mobile-style name="outlined" style="border: 1px solid #0f0"}', @view).must_equal('')
20
- @view.errors.must_include('A mobile style was already defined with that class name (line 0) [name=outlined, style=border: 1px solid #0f0]')
20
+ assert_error(@view, 'A mobile style was already defined with that class name', 'name=outlined', 'style=border: 1px solid #0f0')
21
21
  end
22
22
 
23
23
  it 'adds an inactive responsive style to the context' do