prosereflect 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +4 -0
- data/.github/workflows/release.yml +5 -0
- data/.rubocop.yml +19 -1
- data/.rubocop_todo.yml +141 -191
- data/CLAUDE.md +78 -0
- data/Gemfile +8 -4
- data/Rakefile +3 -3
- data/lib/prosereflect/attribute/base.rb +4 -6
- data/lib/prosereflect/attribute/bold.rb +2 -4
- data/lib/prosereflect/attribute/href.rb +1 -3
- data/lib/prosereflect/attribute/id.rb +7 -7
- data/lib/prosereflect/attribute.rb +4 -7
- data/lib/prosereflect/blockquote.rb +10 -11
- data/lib/prosereflect/bullet_list.rb +16 -15
- data/lib/prosereflect/code_block.rb +26 -26
- data/lib/prosereflect/code_block_wrapper.rb +12 -13
- data/lib/prosereflect/document.rb +14 -22
- data/lib/prosereflect/hard_break.rb +6 -6
- data/lib/prosereflect/heading.rb +14 -15
- data/lib/prosereflect/horizontal_rule.rb +14 -14
- data/lib/prosereflect/image.rb +23 -23
- data/lib/prosereflect/input/html.rb +83 -104
- data/lib/prosereflect/input.rb +7 -0
- data/lib/prosereflect/list_item.rb +11 -12
- data/lib/prosereflect/mark/base.rb +9 -11
- data/lib/prosereflect/mark/bold.rb +1 -3
- data/lib/prosereflect/mark/code.rb +1 -3
- data/lib/prosereflect/mark/italic.rb +1 -3
- data/lib/prosereflect/mark/link.rb +1 -3
- data/lib/prosereflect/mark/strike.rb +1 -3
- data/lib/prosereflect/mark/subscript.rb +1 -3
- data/lib/prosereflect/mark/superscript.rb +1 -3
- data/lib/prosereflect/mark/underline.rb +1 -3
- data/lib/prosereflect/mark.rb +9 -5
- data/lib/prosereflect/node.rb +31 -31
- data/lib/prosereflect/ordered_list.rb +15 -14
- data/lib/prosereflect/output/html.rb +52 -50
- data/lib/prosereflect/output.rb +7 -0
- data/lib/prosereflect/paragraph.rb +11 -13
- data/lib/prosereflect/parser.rb +47 -66
- data/lib/prosereflect/table.rb +12 -13
- data/lib/prosereflect/table_cell.rb +13 -13
- data/lib/prosereflect/table_header.rb +17 -17
- data/lib/prosereflect/table_row.rb +12 -12
- data/lib/prosereflect/text.rb +11 -11
- data/lib/prosereflect/user.rb +15 -15
- data/lib/prosereflect/version.rb +1 -1
- data/lib/prosereflect.rb +27 -17
- data/prosereflect.gemspec +17 -16
- data/spec/prosereflect/document_spec.rb +332 -330
- data/spec/prosereflect/hard_break_spec.rb +125 -125
- data/spec/prosereflect/input/html_spec.rb +522 -522
- data/spec/prosereflect/node_spec.rb +183 -182
- data/spec/prosereflect/output/html_spec.rb +105 -105
- data/spec/prosereflect/paragraph_spec.rb +275 -274
- data/spec/prosereflect/parser_spec.rb +185 -180
- data/spec/prosereflect/table_cell_spec.rb +183 -183
- data/spec/prosereflect/table_row_spec.rb +149 -149
- data/spec/prosereflect/table_spec.rb +320 -318
- data/spec/prosereflect/text_spec.rb +133 -132
- data/spec/prosereflect/user_spec.rb +31 -28
- data/spec/prosereflect_spec.rb +28 -26
- data/spec/spec_helper.rb +6 -6
- data/spec/support/matchers.rb +6 -6
- data/spec/support/shared_examples.rb +49 -49
- metadata +8 -5
- data/spec/prosereflect/version_spec.rb +0 -11
|
@@ -1,274 +1,275 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "spec_helper"
|
|
4
4
|
|
|
5
5
|
RSpec.describe Prosereflect::Text do
|
|
6
|
-
describe
|
|
7
|
-
it
|
|
8
|
-
text = described_class.new({
|
|
9
|
-
expect(text.type).to eq(
|
|
10
|
-
expect(text.text).to eq(
|
|
6
|
+
describe "initialization" do
|
|
7
|
+
it "initializes as a text node" do
|
|
8
|
+
text = described_class.new({ "type" => "text", "text" => "Hello" })
|
|
9
|
+
expect(text.type).to eq("text")
|
|
10
|
+
expect(text.text).to eq("Hello")
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
it
|
|
14
|
-
text = described_class.new({
|
|
15
|
-
expect(text.text).to eq(
|
|
13
|
+
it "initializes with empty text" do
|
|
14
|
+
text = described_class.new({ "type" => "text" })
|
|
15
|
+
expect(text.text).to eq("")
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
it
|
|
18
|
+
it "initializes with marks" do
|
|
19
19
|
marks = [
|
|
20
20
|
Prosereflect::Mark::Bold.new,
|
|
21
|
-
Prosereflect::Mark::Italic.new
|
|
21
|
+
Prosereflect::Mark::Italic.new,
|
|
22
22
|
]
|
|
23
|
-
text = described_class.new(text:
|
|
23
|
+
text = described_class.new(text: "Hello", marks: marks)
|
|
24
24
|
|
|
25
25
|
expect(text.raw_marks).to eq(marks)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
describe
|
|
30
|
-
it
|
|
31
|
-
text = described_class.create(
|
|
29
|
+
describe ".create" do
|
|
30
|
+
it "creates a simple text node" do
|
|
31
|
+
text = described_class.create("Hello world")
|
|
32
32
|
|
|
33
33
|
expected = {
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
"type" => "text",
|
|
35
|
+
"text" => "Hello world",
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
expect(text.to_h).to eq(expected)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
it
|
|
42
|
-
text = described_class.create(
|
|
41
|
+
it "creates a text node with marks" do
|
|
42
|
+
text = described_class.create("Formatted text", [
|
|
43
43
|
Prosereflect::Mark::Bold.new,
|
|
44
|
-
Prosereflect::Mark::Italic.new
|
|
44
|
+
Prosereflect::Mark::Italic.new,
|
|
45
45
|
])
|
|
46
46
|
|
|
47
47
|
expected = {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
{
|
|
53
|
-
]
|
|
48
|
+
"type" => "text",
|
|
49
|
+
"text" => "Formatted text",
|
|
50
|
+
"marks" => [
|
|
51
|
+
{ "type" => "bold" },
|
|
52
|
+
{ "type" => "italic" },
|
|
53
|
+
],
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
expect(text.to_h).to eq(expected)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
it
|
|
60
|
-
text = described_class.create(
|
|
61
|
-
Prosereflect::Mark::Link.new(attrs: {
|
|
62
|
-
|
|
59
|
+
it "creates a text node with marks and attributes" do
|
|
60
|
+
text = described_class.create("Link text", [
|
|
61
|
+
Prosereflect::Mark::Link.new(attrs: { "href" => "https://example.com",
|
|
62
|
+
"title" => "Example" }),
|
|
63
|
+
Prosereflect::Mark::Bold.new,
|
|
63
64
|
])
|
|
64
65
|
|
|
65
66
|
expected = {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
"type" => "text",
|
|
68
|
+
"text" => "Link text",
|
|
69
|
+
"marks" => [
|
|
69
70
|
{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
71
|
+
"type" => "link",
|
|
72
|
+
"attrs" => {
|
|
73
|
+
"href" => "https://example.com",
|
|
74
|
+
"title" => "Example",
|
|
75
|
+
},
|
|
75
76
|
},
|
|
76
|
-
{
|
|
77
|
-
]
|
|
77
|
+
{ "type" => "bold" },
|
|
78
|
+
],
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
expect(text.to_h).to eq(expected)
|
|
81
82
|
end
|
|
82
83
|
end
|
|
83
84
|
|
|
84
|
-
describe
|
|
85
|
-
it
|
|
86
|
-
text = described_class.create(
|
|
85
|
+
describe "text structure" do
|
|
86
|
+
it "creates text with special characters" do
|
|
87
|
+
text = described_class.create("Special chars: →, ←, ©, ®, ™")
|
|
87
88
|
|
|
88
89
|
expected = {
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
"type" => "text",
|
|
91
|
+
"text" => "Special chars: →, ←, ©, ®, ™",
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
expect(text.to_h).to eq(expected)
|
|
94
95
|
end
|
|
95
96
|
|
|
96
|
-
it
|
|
97
|
-
text = described_class.create(
|
|
97
|
+
it "creates text with multiple marks and attributes" do
|
|
98
|
+
text = described_class.create("Complex text", [
|
|
98
99
|
Prosereflect::Mark::Bold.new,
|
|
99
100
|
Prosereflect::Mark::Italic.new,
|
|
100
101
|
Prosereflect::Mark::Strike.new,
|
|
101
|
-
Prosereflect::Mark::Link.new(attrs: {
|
|
102
|
-
Prosereflect::Mark::Underline.new
|
|
102
|
+
Prosereflect::Mark::Link.new(attrs: { "href" => "https://example.com" }),
|
|
103
|
+
Prosereflect::Mark::Underline.new,
|
|
103
104
|
])
|
|
104
105
|
|
|
105
106
|
expected = {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
{
|
|
111
|
-
{
|
|
107
|
+
"type" => "text",
|
|
108
|
+
"text" => "Complex text",
|
|
109
|
+
"marks" => [
|
|
110
|
+
{ "type" => "bold" },
|
|
111
|
+
{ "type" => "italic" },
|
|
112
|
+
{ "type" => "strike" },
|
|
112
113
|
{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
114
|
+
"type" => "link",
|
|
115
|
+
"attrs" => {
|
|
116
|
+
"href" => "https://example.com",
|
|
117
|
+
},
|
|
117
118
|
},
|
|
118
|
-
{
|
|
119
|
-
]
|
|
119
|
+
{ "type" => "underline" },
|
|
120
|
+
],
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
expect(text.to_h).to eq(expected)
|
|
123
124
|
end
|
|
124
125
|
end
|
|
125
126
|
|
|
126
|
-
describe
|
|
127
|
-
describe
|
|
128
|
-
it
|
|
129
|
-
text = described_class.create(
|
|
127
|
+
describe "text operations" do
|
|
128
|
+
describe "#text_content" do
|
|
129
|
+
it "returns the text content regardless of marks" do
|
|
130
|
+
text = described_class.create("Sample text", [
|
|
130
131
|
Prosereflect::Mark::Bold.new,
|
|
131
|
-
Prosereflect::Mark::Italic.new
|
|
132
|
+
Prosereflect::Mark::Italic.new,
|
|
132
133
|
])
|
|
133
134
|
|
|
134
|
-
expect(text.text_content).to eq(
|
|
135
|
+
expect(text.text_content).to eq("Sample text")
|
|
135
136
|
end
|
|
136
137
|
|
|
137
|
-
it
|
|
138
|
-
text = described_class.create(
|
|
139
|
-
expect(text.text_content).to eq(
|
|
138
|
+
it "returns empty string for empty text" do
|
|
139
|
+
text = described_class.create("")
|
|
140
|
+
expect(text.text_content).to eq("")
|
|
140
141
|
end
|
|
141
142
|
|
|
142
|
-
it
|
|
143
|
+
it "preserves whitespace and special characters" do
|
|
143
144
|
text = described_class.create(" Multiple spaces \t\nand\ttabs ")
|
|
144
145
|
expect(text.text_content).to eq(" Multiple spaces \t\nand\ttabs ")
|
|
145
146
|
end
|
|
146
147
|
end
|
|
147
148
|
|
|
148
|
-
describe
|
|
149
|
-
it
|
|
150
|
-
text = described_class.new(text:
|
|
149
|
+
describe "#marks" do
|
|
150
|
+
it "preserves mark order" do
|
|
151
|
+
text = described_class.new(text: "Hello")
|
|
151
152
|
marks = [
|
|
152
153
|
Prosereflect::Mark::Bold.new,
|
|
153
154
|
Prosereflect::Mark::Italic.new,
|
|
154
|
-
Prosereflect::Mark::Strike.new
|
|
155
|
+
Prosereflect::Mark::Strike.new,
|
|
155
156
|
]
|
|
156
157
|
text.marks = marks
|
|
157
158
|
|
|
158
159
|
expect(text.raw_marks.map(&:type)).to eq(%w[bold italic strike])
|
|
159
160
|
end
|
|
160
161
|
|
|
161
|
-
it
|
|
162
|
-
text = described_class.create(
|
|
162
|
+
it "handles empty marks array" do
|
|
163
|
+
text = described_class.create("No marks", [])
|
|
163
164
|
expect(text.marks).to eq([])
|
|
164
|
-
expect(text.to_h).not_to have_key(
|
|
165
|
+
expect(text.to_h).not_to have_key("marks")
|
|
165
166
|
end
|
|
166
167
|
|
|
167
|
-
it
|
|
168
|
-
text = described_class.create(
|
|
168
|
+
it "handles nil marks" do
|
|
169
|
+
text = described_class.create("No marks", nil)
|
|
169
170
|
expect(text.marks).to be_nil
|
|
170
|
-
expect(text.to_h).not_to have_key(
|
|
171
|
+
expect(text.to_h).not_to have_key("marks")
|
|
171
172
|
end
|
|
172
173
|
end
|
|
173
174
|
end
|
|
174
175
|
|
|
175
|
-
describe
|
|
176
|
-
it
|
|
177
|
-
text = described_class.create(
|
|
176
|
+
describe "mark attributes" do
|
|
177
|
+
it "preserves mark attributes in serialization" do
|
|
178
|
+
text = described_class.create("Styled text", [
|
|
178
179
|
Prosereflect::Mark::Link.new(attrs: {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
"href" => "https://example.com",
|
|
181
|
+
"title" => "Example Link",
|
|
182
|
+
"target" => "_blank",
|
|
182
183
|
}),
|
|
183
184
|
Prosereflect::Mark::Bold.new,
|
|
184
|
-
Prosereflect::Mark::Italic.new
|
|
185
|
+
Prosereflect::Mark::Italic.new,
|
|
185
186
|
])
|
|
186
187
|
|
|
187
188
|
expected = {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
"type" => "text",
|
|
190
|
+
"text" => "Styled text",
|
|
191
|
+
"marks" => [
|
|
191
192
|
{
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
193
|
+
"type" => "link",
|
|
194
|
+
"attrs" => {
|
|
195
|
+
"href" => "https://example.com",
|
|
196
|
+
"title" => "Example Link",
|
|
197
|
+
"target" => "_blank",
|
|
198
|
+
},
|
|
198
199
|
},
|
|
199
|
-
{
|
|
200
|
-
{
|
|
201
|
-
]
|
|
200
|
+
{ "type" => "bold" },
|
|
201
|
+
{ "type" => "italic" },
|
|
202
|
+
],
|
|
202
203
|
}
|
|
203
204
|
|
|
204
205
|
expect(text.to_h).to eq(expected)
|
|
205
206
|
end
|
|
206
207
|
|
|
207
|
-
it
|
|
208
|
-
text = described_class.create(
|
|
208
|
+
it "handles marks with empty attributes" do
|
|
209
|
+
text = described_class.create("Test text", [
|
|
209
210
|
Prosereflect::Mark::Link.new(attrs: {}),
|
|
210
211
|
Prosereflect::Mark::Bold.new,
|
|
211
|
-
Prosereflect::Mark::Italic.new
|
|
212
|
+
Prosereflect::Mark::Italic.new,
|
|
212
213
|
])
|
|
213
214
|
|
|
214
215
|
expected = {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
{
|
|
219
|
-
{
|
|
220
|
-
{
|
|
221
|
-
]
|
|
216
|
+
"type" => "text",
|
|
217
|
+
"text" => "Test text",
|
|
218
|
+
"marks" => [
|
|
219
|
+
{ "type" => "link" },
|
|
220
|
+
{ "type" => "bold" },
|
|
221
|
+
{ "type" => "italic" },
|
|
222
|
+
],
|
|
222
223
|
}
|
|
223
224
|
|
|
224
225
|
expect(text.to_h).to eq(expected)
|
|
225
226
|
end
|
|
226
227
|
end
|
|
227
228
|
|
|
228
|
-
describe
|
|
229
|
-
it
|
|
230
|
-
text = described_class.new({
|
|
229
|
+
describe "#to_h" do
|
|
230
|
+
it "creates a hash representation with text" do
|
|
231
|
+
text = described_class.new({ "type" => "text", "text" => "Hello" })
|
|
231
232
|
hash = text.to_h
|
|
232
233
|
|
|
233
|
-
expect(hash[
|
|
234
|
-
expect(hash[
|
|
234
|
+
expect(hash["type"]).to eq("text")
|
|
235
|
+
expect(hash["text"]).to eq("Hello")
|
|
235
236
|
end
|
|
236
237
|
|
|
237
|
-
it
|
|
238
|
-
mark = Prosereflect::Mark::Base.new(type:
|
|
238
|
+
it "includes marks in hash representation when present" do
|
|
239
|
+
mark = Prosereflect::Mark::Base.new(type: "bold")
|
|
239
240
|
marks = [mark]
|
|
240
|
-
text = described_class.new(text:
|
|
241
|
+
text = described_class.new(text: "Bold text", marks: marks)
|
|
241
242
|
|
|
242
243
|
hash = text.to_h
|
|
243
|
-
expect(hash[
|
|
244
|
+
expect(hash["marks"]).to eq([{ "type" => "bold" }])
|
|
244
245
|
end
|
|
245
246
|
end
|
|
246
247
|
|
|
247
|
-
describe
|
|
248
|
-
it
|
|
249
|
-
text = described_class.new({
|
|
248
|
+
describe "inheritance" do
|
|
249
|
+
it "is a Node" do
|
|
250
|
+
text = described_class.new({ "type" => "text", "text" => "Test" })
|
|
250
251
|
expect(text).to be_a(Prosereflect::Node)
|
|
251
252
|
end
|
|
252
253
|
end
|
|
253
254
|
|
|
254
|
-
describe
|
|
255
|
-
it
|
|
256
|
-
bold_mark = Prosereflect::Mark::Base.new(type:
|
|
257
|
-
italic_mark = Prosereflect::Mark::Base.new(type:
|
|
258
|
-
underline_mark = Prosereflect::Mark::Base.new(type:
|
|
255
|
+
describe "with marks" do
|
|
256
|
+
it "can have multiple marks" do
|
|
257
|
+
bold_mark = Prosereflect::Mark::Base.new(type: "bold")
|
|
258
|
+
italic_mark = Prosereflect::Mark::Base.new(type: "italic")
|
|
259
|
+
underline_mark = Prosereflect::Mark::Base.new(type: "underline")
|
|
259
260
|
marks = [bold_mark, italic_mark, underline_mark]
|
|
260
261
|
|
|
261
|
-
text = described_class.new(text:
|
|
262
|
+
text = described_class.new(text: "Formatted text", marks: marks)
|
|
262
263
|
|
|
263
264
|
expect(text.marks.size).to eq(3)
|
|
264
265
|
end
|
|
265
266
|
|
|
266
|
-
it
|
|
267
|
-
text = described_class.new(text:
|
|
268
|
-
mark = Prosereflect::Mark::Link.new(attrs: {
|
|
267
|
+
it "can have marks with attributes" do
|
|
268
|
+
text = described_class.new(text: "Hello")
|
|
269
|
+
mark = Prosereflect::Mark::Link.new(attrs: { "href" => "https://example.com" })
|
|
269
270
|
text.marks = [mark]
|
|
270
271
|
|
|
271
|
-
expect(text.raw_marks[0].attrs[
|
|
272
|
+
expect(text.raw_marks[0].attrs["href"]).to eq("https://example.com")
|
|
272
273
|
end
|
|
273
274
|
end
|
|
274
275
|
end
|
|
@@ -1,73 +1,76 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "spec_helper"
|
|
4
4
|
|
|
5
5
|
RSpec.describe Prosereflect::User do
|
|
6
6
|
let(:user) { described_class.new }
|
|
7
7
|
|
|
8
|
-
describe
|
|
9
|
-
it
|
|
8
|
+
describe "#initialize" do
|
|
9
|
+
it "creates a user mention node with empty content" do
|
|
10
10
|
expect(user.content).to eq([])
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
describe
|
|
15
|
-
it
|
|
16
|
-
user.id =
|
|
17
|
-
expect(user.id).to eq(
|
|
14
|
+
describe "#id" do
|
|
15
|
+
it "gets and sets the user id" do
|
|
16
|
+
user.id = "123"
|
|
17
|
+
expect(user.id).to eq("123")
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
it
|
|
21
|
-
user = described_class.new(attrs: {
|
|
22
|
-
expect(user.id).to eq(
|
|
20
|
+
it "gets id from attrs" do
|
|
21
|
+
user = described_class.new(attrs: { "id" => "456" })
|
|
22
|
+
expect(user.id).to eq("456")
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
describe
|
|
27
|
-
it
|
|
28
|
-
expect
|
|
26
|
+
describe "#add_child" do
|
|
27
|
+
it "raises NotImplementedError" do
|
|
28
|
+
expect do
|
|
29
|
+
user.add_child(double)
|
|
30
|
+
end.to raise_error(NotImplementedError,
|
|
31
|
+
"User mention nodes cannot have children")
|
|
29
32
|
end
|
|
30
33
|
end
|
|
31
34
|
|
|
32
|
-
describe
|
|
33
|
-
it
|
|
34
|
-
user.id =
|
|
35
|
+
describe "#to_h" do
|
|
36
|
+
it "serializes correctly" do
|
|
37
|
+
user.id = "789"
|
|
35
38
|
expect(user.to_h).to eq({
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
"type" => "user",
|
|
40
|
+
"attrs" => { "id" => "789" },
|
|
41
|
+
"content" => [],
|
|
39
42
|
})
|
|
40
43
|
end
|
|
41
44
|
end
|
|
42
45
|
|
|
43
|
-
describe
|
|
44
|
-
it
|
|
46
|
+
describe "integration with Document" do
|
|
47
|
+
it "can be added to a document" do
|
|
45
48
|
document = Prosereflect::Document.create
|
|
46
|
-
user = document.add_user(
|
|
49
|
+
user = document.add_user("123")
|
|
47
50
|
|
|
48
51
|
expect(user).to be_a(described_class)
|
|
49
|
-
expect(user.id).to eq(
|
|
52
|
+
expect(user.id).to eq("123")
|
|
50
53
|
expect(document.content.size).to eq(1)
|
|
51
54
|
expect(document.content.first).to be_a(described_class)
|
|
52
55
|
end
|
|
53
56
|
end
|
|
54
57
|
|
|
55
|
-
describe
|
|
56
|
-
it
|
|
58
|
+
describe "HTML conversion" do
|
|
59
|
+
it "converts to HTML correctly" do
|
|
57
60
|
document = Prosereflect::Document.create
|
|
58
|
-
document.add_user(
|
|
61
|
+
document.add_user("123")
|
|
59
62
|
|
|
60
63
|
html = Prosereflect::Output::Html.convert(document)
|
|
61
64
|
expect(html).to eq('<user-mention data-id="123"></user-mention>')
|
|
62
65
|
end
|
|
63
66
|
|
|
64
|
-
it
|
|
67
|
+
it "parses from HTML correctly" do
|
|
65
68
|
html = '<user-mention data-id="123"></user-mention>'
|
|
66
69
|
document = Prosereflect::Input::Html.parse(html)
|
|
67
70
|
|
|
68
71
|
expect(document.content.size).to eq(1)
|
|
69
72
|
expect(document.content.first).to be_a(described_class)
|
|
70
|
-
expect(document.content.first.id).to eq(
|
|
73
|
+
expect(document.content.first.id).to eq("123")
|
|
71
74
|
end
|
|
72
75
|
end
|
|
73
76
|
end
|
data/spec/prosereflect_spec.rb
CHANGED
|
@@ -1,62 +1,64 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "spec_helper"
|
|
4
4
|
|
|
5
5
|
RSpec.describe Prosereflect do
|
|
6
|
-
let(:fixtures_path) { File.join(__dir__,
|
|
6
|
+
let(:fixtures_path) { File.join(__dir__, "fixtures") }
|
|
7
7
|
|
|
8
|
-
it
|
|
9
|
-
expect(Prosereflect::VERSION).not_to
|
|
8
|
+
it "has a version number" do
|
|
9
|
+
expect(Prosereflect::VERSION).not_to be_nil
|
|
10
|
+
expect(Prosereflect::VERSION).to be_a(String)
|
|
11
|
+
expect(Prosereflect::VERSION).to match(/\d+\.\d+\.\d+/)
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
# Test YAML parsing for different fixtures
|
|
13
|
-
Dir.glob(File.join(__dir__,
|
|
15
|
+
Dir.glob(File.join(__dir__, "fixtures", "*/*.yaml")).each do |yaml_file|
|
|
14
16
|
context "with YAML fixture #{File.basename(yaml_file)}" do
|
|
15
17
|
let(:file_content) { File.read(yaml_file) }
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
it_behaves_like "a parsable format", :yaml
|
|
18
20
|
|
|
19
21
|
# Test table functionality for DP fixtures
|
|
20
|
-
if yaml_file.include?(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
if yaml_file.include?("DP")
|
|
23
|
+
it_behaves_like "a document with tables"
|
|
24
|
+
it_behaves_like "document traversal"
|
|
25
|
+
it_behaves_like "text content extraction"
|
|
24
26
|
end
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
# Test JSON parsing for different fixtures
|
|
29
|
-
Dir.glob(File.join(__dir__,
|
|
31
|
+
Dir.glob(File.join(__dir__, "fixtures", "*/*.json")).each do |json_file|
|
|
30
32
|
context "with JSON fixture #{File.basename(json_file)}" do
|
|
31
33
|
let(:file_content) { File.read(json_file) }
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
it_behaves_like "a parsable format", :json
|
|
34
36
|
|
|
35
37
|
# Test table functionality for DP fixtures
|
|
36
|
-
if json_file.include?(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
if json_file.include?("DP")
|
|
39
|
+
it_behaves_like "a document with tables"
|
|
40
|
+
it_behaves_like "document traversal"
|
|
41
|
+
it_behaves_like "text content extraction"
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
end
|
|
43
45
|
|
|
44
|
-
describe
|
|
45
|
-
|
|
46
|
+
describe "Document creation" do
|
|
47
|
+
it_behaves_like "document creation"
|
|
46
48
|
end
|
|
47
49
|
|
|
48
|
-
describe
|
|
49
|
-
context
|
|
50
|
-
|
|
50
|
+
describe "Round-trip format conversion" do
|
|
51
|
+
context "with YAML format" do
|
|
52
|
+
it_behaves_like "format round-trip", :yaml
|
|
51
53
|
end
|
|
52
54
|
|
|
53
|
-
context
|
|
54
|
-
|
|
55
|
+
context "with JSON format" do
|
|
56
|
+
it_behaves_like "format round-trip", :json
|
|
55
57
|
end
|
|
56
58
|
|
|
57
|
-
context
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
context "with HTML format" do
|
|
60
|
+
it_behaves_like "format round-trip", :html
|
|
61
|
+
it_behaves_like "html conversion"
|
|
60
62
|
end
|
|
61
63
|
end
|
|
62
64
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "yaml"
|
|
5
|
+
require "json"
|
|
6
|
+
require "prosereflect"
|
|
7
7
|
|
|
8
8
|
# Load shared examples
|
|
9
|
-
Dir[File.join(__dir__,
|
|
9
|
+
Dir[File.join(__dir__, "support", "**", "*.rb")].each { |f| require f }
|
|
10
10
|
|
|
11
11
|
RSpec.configure do |config|
|
|
12
12
|
# Enable flags like --only-failures and --next-failure
|
|
13
|
-
config.example_status_persistence_file_path =
|
|
13
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
|
14
14
|
|
|
15
15
|
# Disable RSpec exposing methods globally on `Module` and `main`
|
|
16
16
|
config.disable_monkey_patching!
|