prosereflect 0.1.0 → 0.1.1

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +23 -4
  3. data/README.adoc +193 -12
  4. data/lib/prosereflect/attribute/base.rb +34 -0
  5. data/lib/prosereflect/attribute/bold.rb +20 -0
  6. data/lib/prosereflect/attribute/href.rb +24 -0
  7. data/lib/prosereflect/attribute/id.rb +24 -0
  8. data/lib/prosereflect/attribute.rb +13 -0
  9. data/lib/prosereflect/blockquote.rb +85 -0
  10. data/lib/prosereflect/bullet_list.rb +83 -0
  11. data/lib/prosereflect/code_block.rb +135 -0
  12. data/lib/prosereflect/code_block_wrapper.rb +66 -0
  13. data/lib/prosereflect/document.rb +99 -24
  14. data/lib/prosereflect/hard_break.rb +11 -9
  15. data/lib/prosereflect/heading.rb +64 -0
  16. data/lib/prosereflect/horizontal_rule.rb +70 -0
  17. data/lib/prosereflect/image.rb +126 -0
  18. data/lib/prosereflect/input/html.rb +505 -0
  19. data/lib/prosereflect/list_item.rb +65 -0
  20. data/lib/prosereflect/mark/base.rb +49 -0
  21. data/lib/prosereflect/mark/bold.rb +15 -0
  22. data/lib/prosereflect/mark/code.rb +14 -0
  23. data/lib/prosereflect/mark/italic.rb +15 -0
  24. data/lib/prosereflect/mark/link.rb +18 -0
  25. data/lib/prosereflect/mark/strike.rb +15 -0
  26. data/lib/prosereflect/mark/subscript.rb +15 -0
  27. data/lib/prosereflect/mark/superscript.rb +15 -0
  28. data/lib/prosereflect/mark/underline.rb +15 -0
  29. data/lib/prosereflect/mark.rb +11 -0
  30. data/lib/prosereflect/node.rb +181 -32
  31. data/lib/prosereflect/ordered_list.rb +85 -0
  32. data/lib/prosereflect/output/html.rb +374 -0
  33. data/lib/prosereflect/paragraph.rb +26 -15
  34. data/lib/prosereflect/parser.rb +111 -24
  35. data/lib/prosereflect/table.rb +40 -9
  36. data/lib/prosereflect/table_cell.rb +33 -8
  37. data/lib/prosereflect/table_header.rb +92 -0
  38. data/lib/prosereflect/table_row.rb +31 -8
  39. data/lib/prosereflect/text.rb +13 -17
  40. data/lib/prosereflect/user.rb +63 -0
  41. data/lib/prosereflect/version.rb +1 -1
  42. data/lib/prosereflect.rb +6 -0
  43. data/prosereflect.gemspec +1 -0
  44. data/spec/prosereflect/document_spec.rb +436 -36
  45. data/spec/prosereflect/hard_break_spec.rb +218 -22
  46. data/spec/prosereflect/input/html_spec.rb +797 -0
  47. data/spec/prosereflect/node_spec.rb +258 -89
  48. data/spec/prosereflect/output/html_spec.rb +369 -0
  49. data/spec/prosereflect/paragraph_spec.rb +424 -49
  50. data/spec/prosereflect/parser_spec.rb +304 -91
  51. data/spec/prosereflect/table_cell_spec.rb +268 -57
  52. data/spec/prosereflect/table_row_spec.rb +210 -40
  53. data/spec/prosereflect/table_spec.rb +392 -61
  54. data/spec/prosereflect/text_spec.rb +206 -48
  55. data/spec/prosereflect/user_spec.rb +73 -0
  56. data/spec/prosereflect_spec.rb +5 -0
  57. data/spec/support/shared_examples.rb +44 -15
  58. metadata +47 -3
  59. data/debug_loading.rb +0 -34
@@ -13,96 +13,307 @@ RSpec.describe Prosereflect::TableCell do
13
13
  describe '.create' do
14
14
  it 'creates an empty table cell' do
15
15
  cell = described_class.create
16
- expect(cell).to be_a(described_class)
17
- expect(cell.type).to eq('table_cell')
18
- expect(cell.content).to be_empty
16
+
17
+ expected = {
18
+ 'type' => 'table_cell',
19
+ 'content' => []
20
+ }
21
+
22
+ expect(cell.to_h).to eq(expected)
19
23
  end
20
24
 
21
25
  it 'creates a table cell with attributes' do
22
- attrs = { 'colspan' => 2, 'rowspan' => 1 }
23
- cell = described_class.create(attrs)
24
- expect(cell.attrs).to eq(attrs)
26
+ cell = described_class.create(attrs: {
27
+ 'colspan' => 2,
28
+ 'rowspan' => 1,
29
+ 'background' => '#f5f5f5',
30
+ 'align' => 'center',
31
+ 'valign' => 'middle'
32
+ })
33
+
34
+ expected = {
35
+ 'type' => 'table_cell',
36
+ 'attrs' => {
37
+ 'colspan' => 2,
38
+ 'rowspan' => 1,
39
+ 'background' => '#f5f5f5',
40
+ 'align' => 'center',
41
+ 'valign' => 'middle'
42
+ },
43
+ 'content' => []
44
+ }
45
+
46
+ expect(cell.to_h).to eq(expected)
25
47
  end
26
48
  end
27
49
 
28
- describe '#paragraphs' do
29
- it 'returns all paragraphs in the cell' do
50
+ describe 'cell structure' do
51
+ it 'creates a cell with simple text content' do
30
52
  cell = described_class.create
31
- cell.add_paragraph('Para 1')
32
- cell.add_paragraph('Para 2')
53
+ cell.add_paragraph('Simple text')
33
54
 
34
- expect(cell.paragraphs.size).to eq(2)
35
- expect(cell.paragraphs).to all(be_a(Prosereflect::Paragraph))
36
- end
55
+ expected = {
56
+ 'type' => 'table_cell',
57
+ 'content' => [{
58
+ 'type' => 'paragraph',
59
+ 'content' => [{
60
+ 'type' => 'text',
61
+ 'text' => 'Simple text'
62
+ }]
63
+ }]
64
+ }
37
65
 
38
- it 'returns empty array for cell with no paragraphs' do
39
- cell = described_class.create
40
- expect(cell.paragraphs).to eq([])
66
+ expect(cell.to_h).to eq(expected)
41
67
  end
42
- end
43
68
 
44
- describe '#text_content' do
45
- it 'returns concatenated text from all paragraphs with newlines' do
69
+ it 'creates a cell with complex content' do
46
70
  cell = described_class.create
47
- cell.add_paragraph('First paragraph')
48
- cell.add_paragraph('Second paragraph')
49
71
 
50
- expect(cell.text_content).to eq("First paragraph\nSecond paragraph")
51
- end
72
+ # First paragraph with mixed formatting
73
+ para = cell.add_paragraph('This is ')
74
+ para.add_text('bold', [Prosereflect::Mark::Bold.new])
75
+ para.add_text(' and ')
76
+ para.add_text('italic', [Prosereflect::Mark::Italic.new])
77
+ para.add_hard_break
78
+ para.add_text('with a line break')
52
79
 
53
- it 'returns empty string for empty cell' do
54
- cell = described_class.create
55
- expect(cell.text_content).to eq('')
80
+ # Second paragraph with more formatting
81
+ para = cell.add_paragraph
82
+ para.add_text('Status: ', [Prosereflect::Mark::Bold.new])
83
+ para.add_text('Done', [Prosereflect::Mark::Strike.new])
84
+ para.add_text(' → ')
85
+ para.add_text('In Progress', [Prosereflect::Mark::Italic.new])
86
+
87
+ expected = {
88
+ 'type' => 'table_cell',
89
+ 'content' => [{
90
+ 'type' => 'paragraph',
91
+ 'content' => [{
92
+ 'type' => 'text',
93
+ 'text' => 'This is '
94
+ }, {
95
+ 'type' => 'text',
96
+ 'text' => 'bold',
97
+ 'marks' => [{
98
+ 'type' => 'bold'
99
+ }]
100
+ }, {
101
+ 'type' => 'text',
102
+ 'text' => ' and '
103
+ }, {
104
+ 'type' => 'text',
105
+ 'text' => 'italic',
106
+ 'marks' => [{
107
+ 'type' => 'italic'
108
+ }]
109
+ }, {
110
+ 'type' => 'hard_break'
111
+ }, {
112
+ 'type' => 'text',
113
+ 'text' => 'with a line break'
114
+ }]
115
+ }, {
116
+ 'type' => 'paragraph',
117
+ 'content' => [{
118
+ 'type' => 'text',
119
+ 'text' => 'Status: ',
120
+ 'marks' => [{
121
+ 'type' => 'bold'
122
+ }]
123
+ }, {
124
+ 'type' => 'text',
125
+ 'text' => 'Done',
126
+ 'marks' => [{
127
+ 'type' => 'strike'
128
+ }]
129
+ }, {
130
+ 'type' => 'text',
131
+ 'text' => ' → '
132
+ }, {
133
+ 'type' => 'text',
134
+ 'text' => 'In Progress',
135
+ 'marks' => [{
136
+ 'type' => 'italic'
137
+ }]
138
+ }]
139
+ }]
140
+ }
141
+
142
+ expect(cell.to_h).to eq(expected)
56
143
  end
57
144
  end
58
145
 
59
- describe '#lines' do
60
- it 'splits text content into lines' do
61
- cell = described_class.create
62
- cell.add_paragraph('Line 1')
63
- cell.add_paragraph('Line 2')
64
-
65
- expect(cell.lines).to eq(['Line 1', 'Line 2'])
146
+ describe 'cell operations' do
147
+ let(:cell) do
148
+ c = described_class.create
149
+ c.add_paragraph('First paragraph')
150
+ c.add_paragraph('Second paragraph')
151
+ c.add_paragraph('Third paragraph')
152
+ c
66
153
  end
67
154
 
68
- it 'returns empty array for empty cell' do
69
- cell = described_class.create
70
- expect(cell.lines).to eq([])
155
+ describe '#paragraphs' do
156
+ it 'returns all paragraphs in the cell' do
157
+ expect(cell.paragraphs.size).to eq(3)
158
+ expect(cell.paragraphs).to all(be_a(Prosereflect::Paragraph))
159
+ expect(cell.paragraphs.map(&:text_content)).to eq([
160
+ 'First paragraph',
161
+ 'Second paragraph',
162
+ 'Third paragraph'
163
+ ])
164
+ end
165
+
166
+ it 'returns empty array for cell with no paragraphs' do
167
+ empty_cell = described_class.create
168
+ expect(empty_cell.paragraphs).to eq([])
169
+ end
71
170
  end
72
171
 
73
- it 'handles multi-line paragraphs' do
74
- cell = described_class.create
75
- para = cell.add_paragraph('First line')
76
- para.add_hard_break
77
- para.add_text('Second line')
172
+ describe '#text_content' do
173
+ it 'returns concatenated text from all paragraphs with newlines' do
174
+ expect(cell.text_content).to eq("First paragraph\nSecond paragraph\nThird paragraph")
175
+ end
176
+
177
+ it 'returns empty string for empty cell' do
178
+ empty_cell = described_class.create
179
+ expect(empty_cell.text_content).to eq('')
180
+ end
181
+
182
+ it 'handles complex formatting and line breaks' do
183
+ cell = described_class.create
184
+ para = cell.add_paragraph('Line 1')
185
+ para.add_hard_break
186
+ para.add_text('Line 2', [Prosereflect::Mark::Bold.new])
187
+ para.add_hard_break
188
+ para.add_text('Line 3', [Prosereflect::Mark::Italic.new])
78
189
 
79
- expect(cell.lines).to eq(['First line', 'Second line'])
190
+ expect(cell.text_content).to eq("Line 1\nLine 2\nLine 3")
191
+ end
80
192
  end
81
- end
82
193
 
83
- describe '#add_paragraph' do
84
- it 'adds a paragraph with text' do
85
- cell = described_class.create
86
- paragraph = cell.add_paragraph('Test content')
194
+ describe '#lines' do
195
+ it 'splits text content into lines' do
196
+ expect(cell.lines).to eq([
197
+ 'First paragraph',
198
+ 'Second paragraph',
199
+ 'Third paragraph'
200
+ ])
201
+ end
202
+
203
+ it 'returns empty array for empty cell' do
204
+ empty_cell = described_class.create
205
+ expect(empty_cell.lines).to eq([])
206
+ end
207
+
208
+ it 'handles hard breaks within paragraphs' do
209
+ cell = described_class.create
210
+ para = cell.add_paragraph('First line')
211
+ para.add_hard_break
212
+ para.add_text('Second line')
213
+ cell.add_paragraph('Third line')
87
214
 
88
- expect(cell.paragraphs.size).to eq(1)
89
- expect(paragraph).to be_a(Prosereflect::Paragraph)
90
- expect(paragraph.text_content).to eq('Test content')
215
+ expect(cell.lines).to eq([
216
+ 'First line',
217
+ 'Second line',
218
+ 'Third line'
219
+ ])
220
+ end
91
221
  end
92
222
 
93
- it 'adds an empty paragraph' do
94
- cell = described_class.create
95
- paragraph = cell.add_paragraph
223
+ describe '#add_paragraph' do
224
+ it 'adds a paragraph with text and formatting' do
225
+ cell = described_class.create
226
+ para = cell.add_paragraph('Main text')
227
+ para.add_text(' (', [Prosereflect::Mark::Bold.new])
228
+ para.add_text('important', [Prosereflect::Mark::Bold.new, Prosereflect::Mark::Italic.new])
229
+ para.add_text(')', [Prosereflect::Mark::Bold.new])
230
+
231
+ expected = {
232
+ 'type' => 'table_cell',
233
+ 'content' => [{
234
+ 'type' => 'paragraph',
235
+ 'content' => [{
236
+ 'type' => 'text',
237
+ 'text' => 'Main text'
238
+ }, {
239
+ 'type' => 'text',
240
+ 'text' => ' (',
241
+ 'marks' => [{
242
+ 'type' => 'bold'
243
+ }]
244
+ }, {
245
+ 'type' => 'text',
246
+ 'text' => 'important',
247
+ 'marks' => [{
248
+ 'type' => 'bold'
249
+ }, {
250
+ 'type' => 'italic'
251
+ }]
252
+ }, {
253
+ 'type' => 'text',
254
+ 'text' => ')',
255
+ 'marks' => [{
256
+ 'type' => 'bold'
257
+ }]
258
+ }]
259
+ }]
260
+ }
261
+
262
+ expect(cell.to_h).to eq(expected)
263
+ end
264
+
265
+ it 'adds multiple paragraphs with mixed content' do
266
+ cell = described_class.create
96
267
 
97
- expect(cell.paragraphs.size).to eq(1)
98
- expect(paragraph).to be_a(Prosereflect::Paragraph)
99
- expect(paragraph.text_content).to eq('')
268
+ # First paragraph with hard break
269
+ para = cell.add_paragraph('Title')
270
+ para.add_hard_break
271
+ para.add_text('Subtitle', [Prosereflect::Mark::Italic.new])
272
+
273
+ # Second paragraph with mixed formatting
274
+ para = cell.add_paragraph
275
+ para.add_text('Note: ', [Prosereflect::Mark::Bold.new])
276
+ para.add_text('This is important')
277
+
278
+ expected = {
279
+ 'type' => 'table_cell',
280
+ 'content' => [{
281
+ 'type' => 'paragraph',
282
+ 'content' => [{
283
+ 'type' => 'text',
284
+ 'text' => 'Title'
285
+ }, {
286
+ 'type' => 'hard_break'
287
+ }, {
288
+ 'type' => 'text',
289
+ 'text' => 'Subtitle',
290
+ 'marks' => [{
291
+ 'type' => 'italic'
292
+ }]
293
+ }]
294
+ }, {
295
+ 'type' => 'paragraph',
296
+ 'content' => [{
297
+ 'type' => 'text',
298
+ 'text' => 'Note: ',
299
+ 'marks' => [{
300
+ 'type' => 'bold'
301
+ }]
302
+ }, {
303
+ 'type' => 'text',
304
+ 'text' => 'This is important'
305
+ }]
306
+ }]
307
+ }
308
+
309
+ expect(cell.to_h).to eq(expected)
310
+ end
100
311
  end
101
312
  end
102
313
 
103
314
  describe 'serialization' do
104
315
  it 'converts to hash representation' do
105
- cell = described_class.create
316
+ cell = described_class.new
106
317
  cell.add_paragraph('Test content')
107
318
 
108
319
  hash = cell.to_h
@@ -13,65 +13,235 @@ RSpec.describe Prosereflect::TableRow do
13
13
  describe '.create' do
14
14
  it 'creates an empty table row' do
15
15
  row = described_class.create
16
- expect(row).to be_a(described_class)
17
- expect(row.type).to eq('table_row')
18
- expect(row.content).to be_empty
16
+
17
+ expected = {
18
+ 'type' => 'table_row',
19
+ 'content' => []
20
+ }
21
+
22
+ expect(row.to_h).to eq(expected)
19
23
  end
20
24
 
21
25
  it 'creates a table row with attributes' do
22
- attrs = { 'background' => '#f5f5f5' }
23
- row = described_class.create(attrs)
24
- expect(row.attrs).to eq(attrs)
26
+ row = described_class.create(attrs: {
27
+ 'background' => '#f5f5f5',
28
+ 'height' => '40px',
29
+ 'alignment' => 'center'
30
+ })
31
+
32
+ expected = {
33
+ 'type' => 'table_row',
34
+ 'attrs' => {
35
+ 'background' => '#f5f5f5',
36
+ 'height' => '40px',
37
+ 'alignment' => 'center'
38
+ },
39
+ 'content' => []
40
+ }
41
+
42
+ expect(row.to_h).to eq(expected)
25
43
  end
26
44
  end
27
45
 
28
- describe '#cells' do
29
- it 'returns all cells in the row' do
46
+ describe 'row structure' do
47
+ it 'creates a row with simple text cells' do
30
48
  row = described_class.create
31
- row.add_cell('Cell 1')
32
- row.add_cell('Cell 2')
49
+ row.add_cell('First')
50
+ row.add_cell('Second')
51
+ row.add_cell('Third')
33
52
 
34
- expect(row.cells.size).to eq(2)
35
- expect(row.cells).to all(be_a(Prosereflect::TableCell))
36
- end
53
+ expected = {
54
+ 'type' => 'table_row',
55
+ 'content' => [{
56
+ 'type' => 'table_cell',
57
+ 'content' => [{
58
+ 'type' => 'paragraph',
59
+ 'content' => [{
60
+ 'type' => 'text',
61
+ 'text' => 'First'
62
+ }]
63
+ }]
64
+ }, {
65
+ 'type' => 'table_cell',
66
+ 'content' => [{
67
+ 'type' => 'paragraph',
68
+ 'content' => [{
69
+ 'type' => 'text',
70
+ 'text' => 'Second'
71
+ }]
72
+ }]
73
+ }, {
74
+ 'type' => 'table_cell',
75
+ 'content' => [{
76
+ 'type' => 'paragraph',
77
+ 'content' => [{
78
+ 'type' => 'text',
79
+ 'text' => 'Third'
80
+ }]
81
+ }]
82
+ }]
83
+ }
37
84
 
38
- it 'returns empty array for row with no cells' do
39
- row = described_class.create
40
- expect(row.cells).to eq([])
85
+ expect(row.to_h).to eq(expected)
41
86
  end
42
- end
43
87
 
44
- describe '#add_cell' do
45
- it 'adds a cell with text content' do
88
+ it 'creates a row with complex cell content' do
46
89
  row = described_class.create
47
- cell = row.add_cell('Test content')
48
90
 
49
- expect(row.cells.size).to eq(1)
50
- expect(cell).to be_a(Prosereflect::TableCell)
51
- expect(cell.text_content).to eq('Test content')
52
- end
91
+ # First cell with multiple paragraphs
92
+ cell = row.add_cell
93
+ para = cell.add_paragraph('Main point:')
94
+ para.add_hard_break
95
+ para.add_text('Important', [Prosereflect::Mark::Bold.new])
96
+ cell.add_paragraph('(details below)')
53
97
 
54
- it 'adds an empty cell' do
55
- row = described_class.create
98
+ # Second cell with mixed formatting
56
99
  cell = row.add_cell
100
+ para = cell.add_paragraph
101
+ para.add_text('Status: ', [Prosereflect::Mark::Bold.new])
102
+ para.add_text('In Progress', [Prosereflect::Mark::Italic.new])
103
+ para.add_hard_break
104
+ para.add_text('Updated', [Prosereflect::Mark::Strike.new])
105
+
106
+ expected = {
107
+ 'type' => 'table_row',
108
+ 'content' => [{
109
+ 'type' => 'table_cell',
110
+ 'content' => [{
111
+ 'type' => 'paragraph',
112
+ 'content' => [{
113
+ 'type' => 'text',
114
+ 'text' => 'Main point:'
115
+ }, {
116
+ 'type' => 'hard_break'
117
+ }, {
118
+ 'type' => 'text',
119
+ 'text' => 'Important',
120
+ 'marks' => [{
121
+ 'type' => 'bold'
122
+ }]
123
+ }]
124
+ }, {
125
+ 'type' => 'paragraph',
126
+ 'content' => [{
127
+ 'type' => 'text',
128
+ 'text' => '(details below)'
129
+ }]
130
+ }]
131
+ }, {
132
+ 'type' => 'table_cell',
133
+ 'content' => [{
134
+ 'type' => 'paragraph',
135
+ 'content' => [{
136
+ 'type' => 'text',
137
+ 'text' => 'Status: ',
138
+ 'marks' => [{
139
+ 'type' => 'bold'
140
+ }]
141
+ }, {
142
+ 'type' => 'text',
143
+ 'text' => 'In Progress',
144
+ 'marks' => [{
145
+ 'type' => 'italic'
146
+ }]
147
+ }, {
148
+ 'type' => 'hard_break'
149
+ }, {
150
+ 'type' => 'text',
151
+ 'text' => 'Updated',
152
+ 'marks' => [{
153
+ 'type' => 'strike'
154
+ }]
155
+ }]
156
+ }]
157
+ }]
158
+ }
57
159
 
58
- expect(row.cells.size).to eq(1)
59
- expect(cell).to be_a(Prosereflect::TableCell)
60
- expect(cell.text_content).to eq('')
160
+ expect(row.to_h).to eq(expected)
61
161
  end
62
162
  end
63
163
 
64
- describe 'serialization' do
65
- it 'converts to hash representation' do
66
- row = described_class.create
67
- row.add_cell('Cell 1')
68
- row.add_cell('Cell 2')
69
-
70
- hash = row.to_h
71
- expect(hash['type']).to eq('table_row')
72
- expect(hash['content'].size).to eq(2)
73
- expect(hash['content'][0]['type']).to eq('table_cell')
74
- expect(hash['content'][1]['type']).to eq('table_cell')
164
+ describe 'row operations' do
165
+ let(:row) do
166
+ r = described_class.create
167
+ r.add_cell('First')
168
+ r.add_cell('Second')
169
+ r.add_cell('Third')
170
+ r
171
+ end
172
+
173
+ describe '#cells' do
174
+ it 'returns all cells in the row' do
175
+ expect(row.cells.size).to eq(3)
176
+ expect(row.cells).to all(be_a(Prosereflect::TableCell))
177
+ expect(row.cells.map(&:text_content)).to eq(%w[First Second Third])
178
+ end
179
+
180
+ it 'returns empty array for row with no cells' do
181
+ empty_row = described_class.create
182
+ expect(empty_row.cells).to eq([])
183
+ end
184
+ end
185
+
186
+ describe '#add_cell' do
187
+ it 'adds a cell with text content and attributes' do
188
+ cell = row.add_cell('Test', attrs: {
189
+ 'colspan' => 2,
190
+ 'rowspan' => 1,
191
+ 'background' => '#eee'
192
+ })
193
+
194
+ expected = {
195
+ 'type' => 'table_cell',
196
+ 'attrs' => {
197
+ 'colspan' => 2,
198
+ 'rowspan' => 1,
199
+ 'background' => '#eee'
200
+ },
201
+ 'content' => [{
202
+ 'type' => 'paragraph',
203
+ 'content' => [{
204
+ 'type' => 'text',
205
+ 'text' => 'Test'
206
+ }]
207
+ }]
208
+ }
209
+
210
+ expect(cell.to_h).to eq(expected)
211
+ end
212
+
213
+ it 'adds a cell with formatted content' do
214
+ cell = row.add_cell
215
+ para = cell.add_paragraph
216
+ para.add_text('Bold', [Prosereflect::Mark::Bold.new])
217
+ para.add_text(' and ')
218
+ para.add_text('italic', [Prosereflect::Mark::Italic.new])
219
+
220
+ expected = {
221
+ 'type' => 'table_cell',
222
+ 'content' => [{
223
+ 'type' => 'paragraph',
224
+ 'content' => [{
225
+ 'type' => 'text',
226
+ 'text' => 'Bold',
227
+ 'marks' => [{
228
+ 'type' => 'bold'
229
+ }]
230
+ }, {
231
+ 'type' => 'text',
232
+ 'text' => ' and '
233
+ }, {
234
+ 'type' => 'text',
235
+ 'text' => 'italic',
236
+ 'marks' => [{
237
+ 'type' => 'italic'
238
+ }]
239
+ }]
240
+ }]
241
+ }
242
+
243
+ expect(cell.to_h).to eq(expected)
244
+ end
75
245
  end
76
246
  end
77
247
  end