sablon 0.0.22 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,120 +12,167 @@ class HTMLConverterTest < Sablon::TestCase
12
12
  def test_convert_text_inside_div
13
13
  input = '<div>Lorem ipsum dolor sit amet</div>'
14
14
  expected_output = <<-DOCX.strip
15
- <w:p>
16
- <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
17
- <w:r><w:t xml:space="preserve">Lorem ipsum dolor sit amet</w:t></w:r>
18
- </w:p>
19
- DOCX
15
+ <w:p>
16
+ <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
17
+ <w:r><w:t xml:space="preserve">Lorem ipsum dolor sit amet</w:t></w:r>
18
+ </w:p>
19
+ DOCX
20
20
  assert_equal normalize_wordml(expected_output), process(input)
21
21
  end
22
22
 
23
23
  def test_convert_text_inside_p
24
24
  input = '<p>Lorem ipsum dolor sit amet</p>'
25
25
  expected_output = <<-DOCX.strip
26
+ <w:p>
27
+ <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
28
+ <w:r><w:t xml:space="preserve">Lorem ipsum dolor sit amet</w:t></w:r>
29
+ </w:p>
30
+ DOCX
31
+ assert_equal normalize_wordml(expected_output), process(input)
32
+ end
33
+
34
+ def test_convert_hyperlink_inside_div
35
+ uid_generator = UIDTestGenerator.new
36
+ SecureRandom.stub(:uuid, uid_generator.method(:new_uid)) do |secure_random_instance|
37
+
38
+ input = '<div>Lorem ipsum dolor sit amet; search it at <a href="http://www.google.com">google</a></div>'
39
+ expected_output = <<-DOCX.strip
26
40
  <w:p>
27
- <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
28
- <w:r><w:t xml:space="preserve">Lorem ipsum dolor sit amet</w:t></w:r>
41
+ <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
42
+ <w:r><w:t xml:space="preserve">Lorem ipsum dolor sit amet; search it at </w:t></w:r>
43
+ <w:hyperlink r:id=\"rId#{secure_random_instance.uuid}\">
44
+ <w:r>
45
+ <w:rPr>
46
+ <w:rStyle w:val=\"Hyperlink\" />
47
+ </w:rPr>
48
+ <w:t xml:space=\"preserve\">google</w:t>
49
+ </w:r>
50
+ </w:hyperlink>
29
51
  </w:p>
30
- DOCX
31
- assert_equal normalize_wordml(expected_output), process(input)
52
+ DOCX
53
+ uid_generator.reset
54
+ assert_equal normalize_wordml(expected_output), process(input)
55
+ end
56
+ end
57
+
58
+ def test_convert_hyperlink_inside_p
59
+ uid_generator = UIDTestGenerator.new
60
+ SecureRandom.stub(:uuid, uid_generator.method(:new_uid)) do |secure_random_instance|
61
+ input = '<p>Lorem ipsum dolor sit amet; search it at <a href="http://www.google.com">google</a></p>'
62
+ expected_output = <<-DOCX.strip
63
+ <w:p>
64
+ <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
65
+ <w:r><w:t xml:space="preserve">Lorem ipsum dolor sit amet; search it at </w:t></w:r>
66
+ <w:hyperlink r:id=\"rId#{secure_random_instance.uuid}\">
67
+ <w:r>
68
+ <w:rPr>
69
+ <w:rStyle w:val=\"Hyperlink\" />
70
+ </w:rPr>
71
+ <w:t xml:space=\"preserve\">google</w:t>
72
+ </w:r>
73
+ </w:hyperlink>
74
+ </w:p>
75
+ DOCX
76
+ uid_generator.reset
77
+ assert_equal normalize_wordml(expected_output), process(input)
78
+ end
32
79
  end
33
80
 
34
81
  def test_convert_text_inside_multiple_divs
35
82
  input = '<div>Lorem ipsum</div><div>dolor sit amet</div>'
36
83
  expected_output = <<-DOCX.strip
37
- <w:p>
38
- <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
39
- <w:r><w:t xml:space="preserve">Lorem ipsum</w:t></w:r>
40
- </w:p>
41
- <w:p>
42
- <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
43
- <w:r><w:t xml:space="preserve">dolor sit amet</w:t></w:r>
44
- </w:p>
45
- DOCX
84
+ <w:p>
85
+ <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
86
+ <w:r><w:t xml:space="preserve">Lorem ipsum</w:t></w:r>
87
+ </w:p>
88
+ <w:p>
89
+ <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
90
+ <w:r><w:t xml:space="preserve">dolor sit amet</w:t></w:r>
91
+ </w:p>
92
+ DOCX
46
93
  assert_equal normalize_wordml(expected_output), process(input)
47
94
  end
48
95
 
49
96
  def test_convert_newline_inside_div
50
97
  input = '<div>Lorem ipsum<br>dolor sit amet</div>'
51
98
  expected_output = <<-DOCX.strip
52
- <w:p>
53
- <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
54
- <w:r><w:t xml:space="preserve">Lorem ipsum</w:t></w:r>
55
- <w:r><w:br/></w:r>
56
- <w:r><w:t xml:space="preserve">dolor sit amet</w:t></w:r>
57
- </w:p>
58
- DOCX
99
+ <w:p>
100
+ <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
101
+ <w:r><w:t xml:space="preserve">Lorem ipsum</w:t></w:r>
102
+ <w:r><w:br/></w:r>
103
+ <w:r><w:t xml:space="preserve">dolor sit amet</w:t></w:r>
104
+ </w:p>
105
+ DOCX
59
106
  assert_equal normalize_wordml(expected_output), process(input)
60
107
  end
61
108
 
62
109
  def test_convert_strong_tags_inside_div
63
110
  input = '<div>Lorem&nbsp;<strong>ipsum dolor</strong>&nbsp;sit amet</div>'
64
111
  expected_output = <<-DOCX.strip
65
- <w:p>
66
- <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
67
- <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
68
- <w:r><w:rPr><w:b /></w:rPr><w:t xml:space="preserve">ipsum dolor</w:t></w:r>
69
- <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
70
- </w:p>
71
- DOCX
112
+ <w:p>
113
+ <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
114
+ <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
115
+ <w:r><w:rPr><w:b /></w:rPr><w:t xml:space="preserve">ipsum dolor</w:t></w:r>
116
+ <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
117
+ </w:p>
118
+ DOCX
72
119
  assert_equal normalize_wordml(expected_output), process(input)
73
120
  end
74
121
 
75
122
  def test_convert_span_tags_inside_p
76
123
  input = '<p>Lorem&nbsp;<span>ipsum dolor</span>&nbsp;sit amet</p>'
77
124
  expected_output = <<-DOCX.strip
78
- <w:p>
79
- <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
80
- <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
81
- <w:r><w:t xml:space="preserve">ipsum dolor</w:t></w:r>
82
- <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r></w:p>
83
- DOCX
84
-
125
+ <w:p>
126
+ <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
127
+ <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
128
+ <w:r><w:t xml:space="preserve">ipsum dolor</w:t></w:r>
129
+ <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
130
+ </w:p>
131
+ DOCX
85
132
  assert_equal normalize_wordml(expected_output), process(input)
86
133
  end
87
134
 
88
135
  def test_convert_u_tags_inside_p
89
136
  input = '<p>Lorem&nbsp;<u>ipsum dolor</u>&nbsp;sit amet</p>'
90
137
  expected_output = <<-DOCX.strip
91
- <w:p>
92
- <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
93
- <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
94
- <w:r>
95
- <w:rPr><w:u w:val="single" /></w:rPr>
96
- <w:t xml:space="preserve">ipsum dolor</w:t>
97
- </w:r>
98
- <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
99
- </w:p>
100
- DOCX
138
+ <w:p>
139
+ <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
140
+ <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
141
+ <w:r>
142
+ <w:rPr><w:u w:val="single" /></w:rPr>
143
+ <w:t xml:space="preserve">ipsum dolor</w:t>
144
+ </w:r>
145
+ <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
146
+ </w:p>
147
+ DOCX
101
148
  assert_equal normalize_wordml(expected_output), process(input)
102
149
  end
103
150
 
104
151
  def test_convert_em_tags_inside_div
105
152
  input = '<div>Lorem&nbsp;<em>ipsum dolor</em>&nbsp;sit amet</div>'
106
153
  expected_output = <<-DOCX.strip
107
- <w:p>
108
- <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
109
- <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
110
- <w:r><w:rPr><w:i /></w:rPr><w:t xml:space="preserve">ipsum dolor</w:t></w:r>
111
- <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
112
- </w:p>
113
- DOCX
154
+ <w:p>
155
+ <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
156
+ <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
157
+ <w:r><w:rPr><w:i /></w:rPr><w:t xml:space="preserve">ipsum dolor</w:t></w:r>
158
+ <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
159
+ </w:p>
160
+ DOCX
114
161
  assert_equal normalize_wordml(expected_output), process(input)
115
162
  end
116
163
 
117
164
  def test_convert_s_tags_inside_p
118
165
  input = '<p>Lorem&nbsp;<s>ipsum dolor</s>&nbsp;sit amet</p>'
119
166
  expected_output = <<-DOCX.strip
120
- <w:p>
121
- <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
122
- <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
123
- <w:r>
124
- <w:rPr><w:strike w:val="true" /></w:rPr>
125
- <w:t xml:space="preserve">ipsum dolor</w:t>
126
- </w:r>
127
- <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
128
- </w:p>
167
+ <w:p>
168
+ <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
169
+ <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
170
+ <w:r>
171
+ <w:rPr><w:strike w:val="true" /></w:rPr>
172
+ <w:t xml:space="preserve">ipsum dolor</w:t>
173
+ </w:r>
174
+ <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
175
+ </w:p>
129
176
  DOCX
130
177
  assert_equal normalize_wordml(expected_output), process(input)
131
178
  end
@@ -133,15 +180,15 @@ DOCX
133
180
  def test_convert_sub_tags_inside_p
134
181
  input = '<p>Lorem&nbsp;<sub>ipsum dolor</sub>&nbsp;sit amet</p>'
135
182
  expected_output = <<-DOCX.strip
136
- <w:p>
137
- <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
138
- <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
139
- <w:r>
140
- <w:rPr><w:vertAlign w:val="subscript" /></w:rPr>
141
- <w:t xml:space="preserve">ipsum dolor</w:t>
142
- </w:r>
143
- <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
144
- </w:p>
183
+ <w:p>
184
+ <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
185
+ <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
186
+ <w:r>
187
+ <w:rPr><w:vertAlign w:val="subscript" /></w:rPr>
188
+ <w:t xml:space="preserve">ipsum dolor</w:t>
189
+ </w:r>
190
+ <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
191
+ </w:p>
145
192
  DOCX
146
193
  assert_equal normalize_wordml(expected_output), process(input)
147
194
  end
@@ -149,15 +196,15 @@ DOCX
149
196
  def test_convert_sup_tags_inside_p
150
197
  input = '<p>Lorem&nbsp;<sup>ipsum dolor</sup>&nbsp;sit amet</p>'
151
198
  expected_output = <<-DOCX.strip
152
- <w:p>
153
- <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
154
- <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
155
- <w:r>
156
- <w:rPr><w:vertAlign w:val="superscript" /></w:rPr>
157
- <w:t xml:space="preserve">ipsum dolor</w:t>
158
- </w:r>
159
- <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
160
- </w:p>
199
+ <w:p>
200
+ <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
201
+ <w:r><w:t xml:space="preserve">Lorem </w:t></w:r>
202
+ <w:r>
203
+ <w:rPr><w:vertAlign w:val="superscript" /></w:rPr>
204
+ <w:t xml:space="preserve">ipsum dolor</w:t>
205
+ </w:r>
206
+ <w:r><w:t xml:space="preserve"> sit amet</w:t></w:r>
207
+ </w:p>
161
208
  DOCX
162
209
  assert_equal normalize_wordml(expected_output), process(input)
163
210
  end
@@ -165,153 +212,150 @@ DOCX
165
212
  def test_convert_br_tags_inside_strong
166
213
  input = '<div><strong><br />Lorem ipsum<br />dolor sit amet</strong></div>'
167
214
  expected_output = <<-DOCX
168
- <w:p>
169
- <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
170
- <w:r><w:br/></w:r>
171
- <w:r>
172
- <w:rPr><w:b /></w:rPr>
173
- <w:t xml:space="preserve">Lorem ipsum</w:t></w:r>
174
- <w:r><w:br/></w:r>
175
- <w:r>
176
- <w:rPr><w:b /></w:rPr>
177
- <w:t xml:space="preserve">dolor sit amet</w:t>
178
- </w:r>
179
- </w:p>
180
- DOCX
215
+ <w:p>
216
+ <w:pPr><w:pStyle w:val="Normal" /></w:pPr>
217
+ <w:r><w:br/></w:r>
218
+ <w:r>
219
+ <w:rPr><w:b /></w:rPr>
220
+ <w:t xml:space="preserve">Lorem ipsum</w:t></w:r>
221
+ <w:r><w:br/></w:r>
222
+ <w:r>
223
+ <w:rPr><w:b /></w:rPr>
224
+ <w:t xml:space="preserve">dolor sit amet</w:t>
225
+ </w:r>
226
+ </w:p>
227
+ DOCX
181
228
  assert_equal normalize_wordml(expected_output), process(input)
182
229
  end
183
230
 
184
231
  def test_convert_h1
185
232
  input = '<h1>Lorem ipsum dolor</h1>'
186
- expected_output = <<-DOCX.strip
187
- <w:p>
188
- <w:pPr><w:pStyle w:val="Heading1" /></w:pPr>
189
- <w:r><w:t xml:space="preserve">Lorem ipsum dolor</w:t></w:r>
190
- </w:p>
191
- DOCX
233
+ expected_output = <<-DOCX.strip
234
+ <w:p>
235
+ <w:pPr><w:pStyle w:val="Heading1" /></w:pPr>
236
+ <w:r><w:t xml:space="preserve">Lorem ipsum dolor</w:t></w:r>
237
+ </w:p>
238
+ DOCX
192
239
  assert_equal normalize_wordml(expected_output), process(input)
193
240
  end
194
241
 
195
242
  def test_unorderd_lists
196
243
  input = '<ul><li>Lorem</li><li>ipsum</li><li>dolor</li></ul>'
197
244
  expected_output = <<-DOCX.strip
198
- <w:p>
199
- <w:pPr>
200
- <w:pStyle w:val="ListBullet" />
201
- <w:numPr>
202
- <w:ilvl w:val="0" />
203
- <w:numId w:val="1001" />
204
- </w:numPr>
205
- </w:pPr>
206
- <w:r><w:t xml:space="preserve">Lorem</w:t></w:r>
207
- </w:p>
245
+ <w:p>
246
+ <w:pPr>
247
+ <w:pStyle w:val="ListBullet" />
248
+ <w:numPr>
249
+ <w:ilvl w:val="0" />
250
+ <w:numId w:val="1001" />
251
+ </w:numPr>
252
+ </w:pPr>
253
+ <w:r><w:t xml:space="preserve">Lorem</w:t></w:r>
254
+ </w:p>
208
255
 
209
- <w:p>
210
- <w:pPr>
211
- <w:pStyle w:val="ListBullet" />
212
- <w:numPr>
213
- <w:ilvl w:val="0" />
214
- <w:numId w:val="1001" />
215
- </w:numPr>
216
- </w:pPr>
217
- <w:r><w:t xml:space="preserve">ipsum</w:t></w:r>
218
- </w:p>
256
+ <w:p>
257
+ <w:pPr>
258
+ <w:pStyle w:val="ListBullet" />
259
+ <w:numPr>
260
+ <w:ilvl w:val="0" />
261
+ <w:numId w:val="1001" />
262
+ </w:numPr>
263
+ </w:pPr>
264
+ <w:r><w:t xml:space="preserve">ipsum</w:t></w:r>
265
+ </w:p>
219
266
 
220
- <w:p>
221
- <w:pPr>
222
- <w:pStyle w:val="ListBullet" />
223
- <w:numPr>
224
- <w:ilvl w:val="0" />
225
- <w:numId w:val="1001" />
226
- </w:numPr>
227
- </w:pPr>
228
- <w:r><w:t xml:space="preserve">dolor</w:t></w:r>
229
- </w:p>
230
- DOCX
267
+ <w:p>
268
+ <w:pPr>
269
+ <w:pStyle w:val="ListBullet" />
270
+ <w:numPr>
271
+ <w:ilvl w:val="0" />
272
+ <w:numId w:val="1001" />
273
+ </w:numPr>
274
+ </w:pPr>
275
+ <w:r><w:t xml:space="preserve">dolor</w:t></w:r>
276
+ </w:p>
277
+ DOCX
231
278
  assert_equal normalize_wordml(expected_output), process(input)
232
-
233
279
  assert_equal [Sablon::Numbering::Definition.new(1001, 'ListBullet')], @numbering.definitions
234
280
  end
235
281
 
236
282
  def test_ordered_lists
237
283
  input = '<ol><li>Lorem</li><li>ipsum</li><li>dolor</li></ol>'
238
284
  expected_output = <<-DOCX.strip
239
- <w:p>
240
- <w:pPr>
241
- <w:pStyle w:val="ListNumber" />
242
- <w:numPr>
243
- <w:ilvl w:val="0" />
244
- <w:numId w:val="1001" />
245
- </w:numPr>
246
- </w:pPr>
247
- <w:r><w:t xml:space="preserve">Lorem</w:t></w:r>
248
- </w:p>
285
+ <w:p>
286
+ <w:pPr>
287
+ <w:pStyle w:val="ListNumber" />
288
+ <w:numPr>
289
+ <w:ilvl w:val="0" />
290
+ <w:numId w:val="1001" />
291
+ </w:numPr>
292
+ </w:pPr>
293
+ <w:r><w:t xml:space="preserve">Lorem</w:t></w:r>
294
+ </w:p>
249
295
 
250
- <w:p>
251
- <w:pPr>
252
- <w:pStyle w:val="ListNumber" />
253
- <w:numPr>
254
- <w:ilvl w:val="0" />
255
- <w:numId w:val="1001" />
256
- </w:numPr>
257
- </w:pPr>
258
- <w:r><w:t xml:space="preserve">ipsum</w:t></w:r>
259
- </w:p>
296
+ <w:p>
297
+ <w:pPr>
298
+ <w:pStyle w:val="ListNumber" />
299
+ <w:numPr>
300
+ <w:ilvl w:val="0" />
301
+ <w:numId w:val="1001" />
302
+ </w:numPr>
303
+ </w:pPr>
304
+ <w:r><w:t xml:space="preserve">ipsum</w:t></w:r>
305
+ </w:p>
260
306
 
261
- <w:p>
262
- <w:pPr>
263
- <w:pStyle w:val="ListNumber" />
264
- <w:numPr>
265
- <w:ilvl w:val="0" />
266
- <w:numId w:val="1001" />
267
- </w:numPr>
268
- </w:pPr>
269
- <w:r><w:t xml:space="preserve">dolor</w:t></w:r>
270
- </w:p>
271
- DOCX
307
+ <w:p>
308
+ <w:pPr>
309
+ <w:pStyle w:val="ListNumber" />
310
+ <w:numPr>
311
+ <w:ilvl w:val="0" />
312
+ <w:numId w:val="1001" />
313
+ </w:numPr>
314
+ </w:pPr>
315
+ <w:r><w:t xml:space="preserve">dolor</w:t></w:r>
316
+ </w:p>
317
+ DOCX
272
318
  assert_equal normalize_wordml(expected_output), process(input)
273
-
274
319
  assert_equal [Sablon::Numbering::Definition.new(1001, 'ListNumber')], @numbering.definitions
275
320
  end
276
321
 
277
322
  def test_mixed_lists
278
323
  input = '<ol><li>Lorem</li></ol><ul><li>ipsum</li></ul><ol><li>dolor</li></ol>'
279
324
  expected_output = <<-DOCX.strip
280
- <w:p>
281
- <w:pPr>
282
- <w:pStyle w:val="ListNumber" />
283
- <w:numPr>
284
- <w:ilvl w:val="0" />
285
- <w:numId w:val="1001" />
286
- </w:numPr>
287
- </w:pPr>
288
- <w:r><w:t xml:space=\"preserve\">Lorem</w:t></w:r>
289
- </w:p>
325
+ <w:p>
326
+ <w:pPr>
327
+ <w:pStyle w:val="ListNumber" />
328
+ <w:numPr>
329
+ <w:ilvl w:val="0" />
330
+ <w:numId w:val="1001" />
331
+ </w:numPr>
332
+ </w:pPr>
333
+ <w:r><w:t xml:space=\"preserve\">Lorem</w:t></w:r>
334
+ </w:p>
290
335
 
291
- <w:p>
292
- <w:pPr>
293
- <w:pStyle w:val="ListBullet" />
294
- <w:numPr>
295
- <w:ilvl w:val="0" />
296
- <w:numId w:val="1002" />
297
- </w:numPr>
298
- </w:pPr>
299
- <w:r><w:t xml:space="preserve">ipsum</w:t></w:r>
300
- </w:p>
336
+ <w:p>
337
+ <w:pPr>
338
+ <w:pStyle w:val="ListBullet" />
339
+ <w:numPr>
340
+ <w:ilvl w:val="0" />
341
+ <w:numId w:val="1002" />
342
+ </w:numPr>
343
+ </w:pPr>
344
+ <w:r><w:t xml:space="preserve">ipsum</w:t></w:r>
345
+ </w:p>
301
346
 
302
- <w:p>
303
- <w:pPr>
304
- <w:pStyle w:val="ListNumber" />
305
- <w:numPr>
306
- <w:ilvl w:val="0" />
307
- <w:numId w:val="1003" />
308
- </w:numPr>
309
- </w:pPr>
310
- <w:r><w:t xml:space="preserve">dolor</w:t></w:r>
311
- </w:p>
312
- DOCX
347
+ <w:p>
348
+ <w:pPr>
349
+ <w:pStyle w:val="ListNumber" />
350
+ <w:numPr>
351
+ <w:ilvl w:val="0" />
352
+ <w:numId w:val="1003" />
353
+ </w:numPr>
354
+ </w:pPr>
355
+ <w:r><w:t xml:space="preserve">dolor</w:t></w:r>
356
+ </w:p>
357
+ DOCX
313
358
  assert_equal normalize_wordml(expected_output), process(input)
314
-
315
359
  assert_equal [Sablon::Numbering::Definition.new(1001, 'ListNumber'),
316
360
  Sablon::Numbering::Definition.new(1002, 'ListBullet'),
317
361
  Sablon::Numbering::Definition.new(1003, 'ListNumber')], @numbering.definitions
@@ -320,354 +364,216 @@ DOCX
320
364
  def test_nested_unordered_lists
321
365
  input = '<ul><li>Lorem<ul><li>ipsum<ul><li>dolor</li></ul></li></ul></li></ul>'
322
366
  expected_output = <<-DOCX.strip
323
- <w:p>
324
- <w:pPr>
325
- <w:pStyle w:val="ListBullet" />
326
- <w:numPr>
327
- <w:ilvl w:val="0" />
328
- <w:numId w:val="1001" />
329
- </w:numPr>
330
- </w:pPr>
331
- <w:r><w:t xml:space="preserve">Lorem</w:t></w:r>
332
- </w:p>
367
+ <w:p>
368
+ <w:pPr>
369
+ <w:pStyle w:val="ListBullet" />
370
+ <w:numPr>
371
+ <w:ilvl w:val="0" />
372
+ <w:numId w:val="1001" />
373
+ </w:numPr>
374
+ </w:pPr>
375
+ <w:r><w:t xml:space="preserve">Lorem</w:t></w:r>
376
+ </w:p>
333
377
 
334
- <w:p>
335
- <w:pPr>
336
- <w:pStyle w:val="ListBullet" />
337
- <w:numPr>
338
- <w:ilvl w:val="1" />
339
- <w:numId w:val="1001" />
340
- </w:numPr>
341
- </w:pPr>
342
- <w:r><w:t xml:space="preserve">ipsum</w:t></w:r>
343
- </w:p>
378
+ <w:p>
379
+ <w:pPr>
380
+ <w:pStyle w:val="ListBullet" />
381
+ <w:numPr>
382
+ <w:ilvl w:val="1" />
383
+ <w:numId w:val="1001" />
384
+ </w:numPr>
385
+ </w:pPr>
386
+ <w:r><w:t xml:space="preserve">ipsum</w:t></w:r>
387
+ </w:p>
344
388
 
345
- <w:p>
346
- <w:pPr>
347
- <w:pStyle w:val="ListBullet" />
348
- <w:numPr>
349
- <w:ilvl w:val="2" />
350
- <w:numId w:val="1001" />
351
- </w:numPr>
352
- </w:pPr>
353
- <w:r><w:t xml:space="preserve">dolor</w:t></w:r>
354
- </w:p>
355
- DOCX
389
+ <w:p>
390
+ <w:pPr>
391
+ <w:pStyle w:val="ListBullet" />
392
+ <w:numPr>
393
+ <w:ilvl w:val="2" />
394
+ <w:numId w:val="1001" />
395
+ </w:numPr>
396
+ </w:pPr>
397
+ <w:r><w:t xml:space="preserve">dolor</w:t></w:r>
398
+ </w:p>
399
+ DOCX
356
400
  assert_equal normalize_wordml(expected_output), process(input)
357
-
358
401
  assert_equal [Sablon::Numbering::Definition.new(1001, 'ListBullet')], @numbering.definitions
359
402
  end
360
403
 
361
- def test_unknown_tag
362
- e = assert_raises ArgumentError do
363
- process('<badtag/>')
404
+ def test_anchor_tag
405
+ uid_generator = UIDTestGenerator.new
406
+ input = '<p><a href="www.github.com">GitHub</a></p>'
407
+ SecureRandom.stub(:uuid, uid_generator.method(:new_uid)) do |secure_random_instance|
408
+ expected_output = <<-DOCX.strip
409
+ <w:p>
410
+ <w:pPr>
411
+ <w:pStyle w:val="Paragraph" />
412
+ </w:pPr>
413
+ <w:hyperlink r:id="rId#{secure_random_instance.uuid}">
414
+ <w:r>
415
+ <w:rPr>
416
+ <w:rStyle w:val="Hyperlink" />
417
+ </w:rPr>
418
+ <w:t xml:space="preserve">GitHub</w:t>
419
+ </w:r>
420
+ </w:hyperlink>
421
+ </w:p>
422
+ DOCX
423
+ uid_generator.reset
424
+ assert_equal normalize_wordml(expected_output), process(input)
364
425
  end
365
- assert_match(/Don't know how to handle HTML tag:/, e.message)
366
- end
367
-
368
- private
369
-
370
- def process(input)
371
- @converter.process(input, @env)
372
- end
373
-
374
- def normalize_wordml(wordml)
375
- wordml.gsub(/^\s+/, '').tr("\n", '')
376
426
  end
377
- end
378
-
379
- class HTMLConverterStyleTest < Sablon::TestCase
380
- def setup
381
- super
382
- @env = Sablon::Environment.new(nil)
383
- @converter = Sablon::HTMLConverter.new
384
- end
385
-
386
- # testing direct CSS style -> WordML conversion for paragraphs
387
-
388
- def test_paragraph_with_background_color
389
- input = '<p style="background-color: #123456"></p>'
390
- expected_output = para_with_ppr('<w:shd w:val="clear" w:fill="123456" />')
391
- assert_equal normalize_wordml(expected_output), process(input)
392
- end
393
-
394
- def test_paragraph_with_borders
395
- # Basic single line black border
396
- input = '<p style="border: 1px"></p>'
397
- ppr = <<-DOCX.strip
398
- <w:pBdr>
399
- <w:top w:sz="2" w:val="single" w:color="000000" />
400
- <w:bottom w:sz="2" w:val="single" w:color="000000" />
401
- <w:left w:sz="2" w:val="single" w:color="000000" />
402
- <w:right w:sz="2" w:val="single" w:color="000000" />
403
- </w:pBdr>
404
- DOCX
405
- expected_output = para_with_ppr(ppr)
406
- assert_equal normalize_wordml(expected_output), process(input)
407
- # border with a line style
408
- input = '<p style="border: 1px wavy"></p>'
409
- ppr = <<-DOCX.strip
410
- <w:pBdr>
411
- <w:top w:sz="2" w:val="wavy" w:color="000000" />
412
- <w:bottom w:sz="2" w:val="wavy" w:color="000000" />
413
- <w:left w:sz="2" w:val="wavy" w:color="000000" />
414
- <w:right w:sz="2" w:val="wavy" w:color="000000" />
415
- </w:pBdr>
416
- DOCX
417
- expected_output = para_with_ppr(ppr)
418
- assert_equal normalize_wordml(expected_output), process(input)
419
- # border with line style and color
420
- input = '<p style="border: 1px wavy #123456"></p>'
421
- ppr = <<-DOCX.strip
422
- <w:pBdr>
423
- <w:top w:sz="2" w:val="wavy" w:color="123456" />
424
- <w:bottom w:sz="2" w:val="wavy" w:color="123456" />
425
- <w:left w:sz="2" w:val="wavy" w:color="123456" />
426
- <w:right w:sz="2" w:val="wavy" w:color="123456" />
427
- </w:pBdr>
428
- DOCX
429
- expected_output = para_with_ppr(ppr)
430
- assert_equal normalize_wordml(expected_output), process(input)
431
- end
432
-
433
- def test_paragraph_with_text_align
434
- input = '<p style="text-align: both"></p>'
435
- expected_output = para_with_ppr('<w:jc w:val="both" />')
436
- assert_equal normalize_wordml(expected_output), process(input)
437
- end
438
-
439
- def test_paragraph_with_vertical_align
440
- input = '<p style="vertical-align: baseline"></p>'
441
- expected_output = para_with_ppr('<w:textAlignment w:val="baseline" />')
442
- assert_equal normalize_wordml(expected_output), process(input)
443
- end
444
-
445
- def test_paragraph_with_unsupported_property
446
- input = '<p style="unsupported: true"></p>'
447
- expected_output = para_with_ppr('')
448
- assert_equal normalize_wordml(expected_output), process(input)
449
- end
450
-
451
- def test_run_with_background_color
452
- input = '<p><span style="background-color: #123456">test</span></p>'
453
- expected_output = run_with_rpr('<w:shd w:val="clear" w:fill="123456" />')
454
- assert_equal normalize_wordml(expected_output), process(input)
455
- end
456
-
457
- def test_run_with_color
458
- input = '<p><span style="color: #123456">test</span></p>'
459
- expected_output = run_with_rpr('<w:color w:val="123456" />')
460
- assert_equal normalize_wordml(expected_output), process(input)
461
- end
462
-
463
- def test_run_with_font_size
464
- input = '<p><span style="font-size: 20">test</span></p>'
465
- expected_output = run_with_rpr('<w:sz w:val="40" />')
466
- assert_equal normalize_wordml(expected_output), process(input)
467
-
468
- # test that non-numeric are ignored
469
- input = '<p><span style="font-size: 20pts">test</span></p>'
470
- assert_equal normalize_wordml(expected_output), process(input)
471
-
472
- # test that floats round up
473
- input = '<p><span style="font-size: 19.1pts">test</span></p>'
474
- assert_equal normalize_wordml(expected_output), process(input)
475
- end
476
-
477
- def test_run_with_font_style
478
- input = '<p><span style="font-style: bold">test</span></p>'
479
- expected_output = run_with_rpr('<w:b />')
480
- assert_equal normalize_wordml(expected_output), process(input)
481
427
 
482
- # test that non-numeric are ignored
483
- input = '<p><span style="font-style: italic">test</span></p>'
484
- expected_output = run_with_rpr('<w:i />')
428
+ def test_table_tag
429
+ input = '<table></table>'
430
+ expected_output = '<w:tbl></w:tbl>'
485
431
  assert_equal normalize_wordml(expected_output), process(input)
486
432
  end
487
433
 
488
- def test_run_with_font_wieght
489
- input = '<p><span style="font-weight: bold">test</span></p>'
490
- expected_output = run_with_rpr('<w:b />')
434
+ def test_table_with_table_row
435
+ # This would generate an invalid docu
436
+ input = '<table><tr></tr><tr></tr></table>'
437
+ expected_output = '<w:tbl><w:tr></w:tr><w:tr></w:tr></w:tbl>'
491
438
  assert_equal normalize_wordml(expected_output), process(input)
492
439
  end
493
440
 
494
- def test_run_with_text_decoration
495
- # testing underline configurations
496
- input = '<p><span style="text-decoration: underline">test</span></p>'
497
- expected_output = run_with_rpr('<w:u w:val="single" />')
498
- assert_equal normalize_wordml(expected_output), process(input)
499
-
500
- input = '<p><span style="text-decoration: underline dash">test</span></p>'
501
- expected_output = run_with_rpr('<w:u w:val="dash" w:color="auto" />')
502
- assert_equal normalize_wordml(expected_output), process(input)
503
-
504
- input = '<p><span style="text-decoration: underline dash #123456">test</span></p>'
505
- expected_output = run_with_rpr('<w:u w:val="dash" w:color="123456" />')
506
- assert_equal normalize_wordml(expected_output), process(input)
507
-
508
- # testing line-through
509
- input = '<p><span style="text-decoration: line-through">test</span></p>'
510
- expected_output = run_with_rpr('<w:strike w:val="true" />')
511
- assert_equal normalize_wordml(expected_output), process(input)
512
-
513
- # testing that unsupported values are passed through as a toggle
514
- input = '<p><span style="text-decoration: strike">test</span></p>'
515
- expected_output = run_with_rpr('<w:strike w:val="true" />')
516
- assert_equal normalize_wordml(expected_output), process(input)
517
-
518
- input = '<p><span style="text-decoration: emboss">test</span></p>'
519
- expected_output = run_with_rpr('<w:emboss w:val="true" />')
520
- assert_equal normalize_wordml(expected_output), process(input)
521
- end
522
-
523
- def test_run_with_vertical_align
524
- input = '<p><span style="vertical-align: subscript">test</span></p>'
525
- expected_output = run_with_rpr('<w:vertAlign w:val="subscript" />')
526
- assert_equal normalize_wordml(expected_output), process(input)
527
-
528
- input = '<p><span style="vertical-align: superscript">test</span></p>'
529
- expected_output = run_with_rpr('<w:vertAlign w:val="superscript" />')
530
- assert_equal normalize_wordml(expected_output), process(input)
531
- end
532
-
533
- def test_run_with_unsupported_property
534
- input = '<p><span style="unsupported: true">test</span></p>'
535
- expected_output = '<w:p><w:pPr><w:pStyle w:val="Paragraph" /></w:pPr><w:r><w:t xml:space="preserve">test</w:t></w:r></w:p>'
441
+ def test_table_with_table_row_and_table_cell
442
+ # This would generate an invalid docu
443
+ input = '<table><tr><td>Content</td></tr></table>'
444
+ expected_output = <<-DOCX.strip
445
+ <w:tbl>
446
+ <w:tr>
447
+ <w:tc>
448
+ <w:p>
449
+ <w:pPr><w:pStyle w:val="Paragraph" /></w:pPr>
450
+ <w:r><w:t xml:space="preserve">Content</w:t></w:r>
451
+ </w:p>
452
+ </w:tc>
453
+ </w:tr>
454
+ </w:tbl>
455
+ DOCX
536
456
  assert_equal normalize_wordml(expected_output), process(input)
537
457
  end
538
458
 
539
- # tests with nested runs and styles
540
-
541
- def test_paragraph_props_passed_to_runs
542
- input = '<p style="color: #123456"><b>Lorem</b><span>ipsum</span></p>'
459
+ def test_table_with_table_row_and_table_header_cell
460
+ # This would generate an invalid docu
461
+ input = '<table><tr><th>Content</th></tr></table>'
543
462
  expected_output = <<-DOCX.strip
544
- <w:p>
545
- <w:pPr>
546
- <w:pStyle w:val="Paragraph" />
547
- </w:pPr>
548
- <w:r>
549
- <w:rPr>
550
- <w:color w:val="123456" />
551
- <w:b />
552
- </w:rPr>
553
- <w:t xml:space="preserve">Lorem</w:t>
554
- </w:r>
555
- <w:r>
556
- <w:rPr>
557
- <w:color w:val="123456" />
558
- </w:rPr>
559
- <w:t xml:space="preserve">ipsum</w:t>
560
- </w:r>
561
- </w:p>
463
+ <w:tbl>
464
+ <w:tr>
465
+ <w:tc>
466
+ <w:p>
467
+ <w:pPr>
468
+ <w:jc w:val="center" />
469
+ <w:pStyle w:val="Paragraph" />
470
+ </w:pPr>
471
+ <w:r>
472
+ <w:rPr><w:b /></w:rPr>
473
+ <w:t xml:space="preserve">Content</w:t>
474
+ </w:r>
475
+ </w:p>
476
+ </w:tc>
477
+ </w:tr>
478
+ </w:tbl>
562
479
  DOCX
563
480
  assert_equal normalize_wordml(expected_output), process(input)
564
481
  end
565
482
 
566
- def test_run_prop_override_paragraph_prop
567
- input = '<p style="text-align: center; color: #FF0000">Lorem<span style="color: blue;">ipsum</span></p>'
483
+ def test_table_with_table_row_table_header_cell_and_caption
484
+ # This would generate an invalid docu
485
+ input = '<table><caption>Table Title</caption><tr><th>Content</th></tr></table>'
568
486
  expected_output = <<-DOCX.strip
569
487
  <w:p>
570
488
  <w:pPr>
571
- <w:pStyle w:val="Paragraph" />
572
- <w:jc w:val="center" />
489
+ <w:pStyle w:val="Caption" />
573
490
  </w:pPr>
574
491
  <w:r>
575
- <w:rPr>
576
- <w:color w:val="FF0000" />
577
- </w:rPr>
578
- <w:t xml:space="preserve">Lorem</w:t>
579
- </w:r>
580
- <w:r>
581
- <w:rPr>
582
- <w:color w:val="blue" />
583
- </w:rPr>
584
- <w:t xml:space="preserve">ipsum</w:t>
492
+ <w:t xml:space="preserve">Table Title</w:t>
585
493
  </w:r>
586
494
  </w:p>
495
+ <w:tbl>
496
+ <w:tr>
497
+ <w:tc>
498
+ <w:p>
499
+ <w:pPr>
500
+ <w:jc w:val="center" />
501
+ <w:pStyle w:val="Paragraph" />
502
+ </w:pPr>
503
+ <w:r>
504
+ <w:rPr><w:b /></w:rPr>
505
+ <w:t xml:space="preserve">Content</w:t>
506
+ </w:r>
507
+ </w:p>
508
+ </w:tc>
509
+ </w:tr>
510
+ </w:tbl>
587
511
  DOCX
588
512
  assert_equal normalize_wordml(expected_output), process(input)
589
513
  end
590
514
 
591
- def test_inline_style_overrides_tag_style
592
- # Note: a toggle property can not be removed once it becomes a symbol
593
- # unless there is a specific CSS style that will set it to false. This
594
- # is because CSS styles can only override parent properties not remove them.
595
- input = '<p><u style="text-decoration: underline wavyDouble">test</u></p>'
596
- expected_output = run_with_rpr('<w:u w:val="wavyDouble" w:color="auto" />')
597
- assert_equal normalize_wordml(expected_output), process(input)
598
- end
599
-
600
- def test_conversion_of_a_registered_tag_without_ast_class
601
- # This registers a new tag with the configuration object and then trys
602
- # to convert it
603
- Sablon.configure do |config|
604
- config.register_html_tag(:bgcyan, :inline, properties: { 'highlight' => { val: 'cyan' } })
605
- end
606
- #
607
- input = '<p><bgcyan>test</bgcyan></p>'
608
- expected_output = run_with_rpr('<w:highlight w:val="cyan" />')
609
- assert_equal normalize_wordml(expected_output), process(input)
610
-
611
- # remove the tag to avoid any accidental side effects
612
- Sablon.configure do |config|
613
- config.remove_html_tag(:bgcyan)
614
- end
615
- end
616
-
617
- def test_conversion_of_a_registered_tag_with_ast_class
618
- Sablon.configure do |config|
619
- # create the AST class and then pass it onto the register tag method
620
- ast_class = Class.new(Sablon::HTMLConverter::Node) do
621
- def self.name
622
- 'TestInstr'
623
- end
624
-
625
- def initialize(_env, node, _properties)
626
- @content = node.text
627
- end
628
-
629
- def inspect
630
- @content
631
- end
632
-
633
- def to_docx
634
- "<w:instrText xml:space=\"preserve\"> #{@content} </w:instrText>"
635
- end
636
- end
637
- #
638
- config.register_html_tag(:test_instr, :inline, ast_class: ast_class)
639
- end
640
- #
641
- input = '<p><test_instr>test</test_instr></p>'
515
+ def test_table_with_table_row_table_header_cell_thead_tbody_and_tfoot
516
+ # This would generate an invalid docu
517
+ input = <<-HTML.strip
518
+ <table>
519
+ <thead><tr><th>Head</th></tr></thead>
520
+ <tbody><tr><td>Body</td></tr></tbody>
521
+ <tfoot><tr><td>Foot</td></tr></tfoot>
522
+ </table>
523
+ HTML
642
524
  expected_output = <<-DOCX.strip
643
- <w:p>
644
- <w:pPr>
645
- <w:pStyle w:val="Paragraph" />
646
- </w:pPr>
647
- <w:instrText xml:space="preserve"> test </w:instrText>
648
- </w:p>
525
+ <w:tbl>
526
+ <w:tr>
527
+ <w:trPr>
528
+ <w:tblHeader />
529
+ </w:trPr>
530
+ <w:tc>
531
+ <w:p>
532
+ <w:pPr>
533
+ <w:jc w:val="center" />
534
+ <w:pStyle w:val="Paragraph" />
535
+ </w:pPr>
536
+ <w:r>
537
+ <w:rPr><w:b /></w:rPr>
538
+ <w:t xml:space="preserve">Head</w:t>
539
+ </w:r>
540
+ </w:p>
541
+ </w:tc>
542
+ </w:tr>
543
+ <w:tr>
544
+ <w:tc>
545
+ <w:p>
546
+ <w:pPr>
547
+ <w:pStyle w:val="Paragraph" />
548
+ </w:pPr>
549
+ <w:r>
550
+ <w:t xml:space="preserve">Body</w:t>
551
+ </w:r>
552
+ </w:p>
553
+ </w:tc>
554
+ </w:tr>
555
+ <w:tr>
556
+ <w:tc>
557
+ <w:p>
558
+ <w:pPr>
559
+ <w:pStyle w:val="Paragraph" />
560
+ </w:pPr>
561
+ <w:r>
562
+ <w:t xml:space="preserve">Foot</w:t>
563
+ </w:r>
564
+ </w:p>
565
+ </w:tc>
566
+ </w:tr>
567
+ </w:tbl>
649
568
  DOCX
650
569
  assert_equal normalize_wordml(expected_output), process(input)
651
-
652
- # remove the tag to avoid any accidental side effects
653
- Sablon.configure do |config|
654
- config.remove_html_tag(:test_instr)
655
- end
656
570
  end
657
571
 
658
- def test_conversion_of_registered_style_attribute
659
- Sablon.configure do |config|
660
- converter = ->(v) { return :highlight, v }
661
- config.register_style_converter(:run, 'test-highlight', converter)
662
- end
663
- #
664
- input = '<p><span style="test-highlight: green">test</span></p>'
665
- expected_output = run_with_rpr('<w:highlight w:val="green" />')
666
- assert_equal normalize_wordml(expected_output), process(input)
667
- #
668
- Sablon.configure do |config|
669
- config.remove_style_converter(:run, 'test-highlight')
572
+ def test_unknown_tag
573
+ e = assert_raises ArgumentError do
574
+ process('<badtag/>')
670
575
  end
576
+ assert_match(/Don't know how to handle HTML tag:/, e.message)
671
577
  end
672
578
 
673
579
  private
@@ -676,28 +582,6 @@ class HTMLConverterStyleTest < Sablon::TestCase
676
582
  @converter.process(input, @env)
677
583
  end
678
584
 
679
- def para_with_ppr(ppr_str)
680
- para_str = '<w:p><w:pPr><w:pStyle w:val="Paragraph" />%s</w:pPr></w:p>'
681
- format(para_str, ppr_str)
682
- end
683
-
684
- def run_with_rpr(rpr_str)
685
- para_str = <<-DOCX.strip
686
- <w:p>
687
- <w:pPr>
688
- <w:pStyle w:val="Paragraph" />
689
- </w:pPr>
690
- <w:r>
691
- <w:rPr>
692
- %s
693
- </w:rPr>
694
- <w:t xml:space="preserve">test</w:t>
695
- </w:r>
696
- </w:p>
697
- DOCX
698
- format(para_str, rpr_str)
699
- end
700
-
701
585
  def normalize_wordml(wordml)
702
586
  wordml.gsub(/^\s+/, '').tr("\n", '')
703
587
  end