prosereflect 0.1.1 → 0.3.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/docs.yml +63 -0
- data/.github/workflows/links.yml +97 -0
- data/.github/workflows/rake.yml +4 -0
- data/.github/workflows/release.yml +5 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +19 -1
- data/.rubocop_todo.yml +119 -183
- data/CLAUDE.md +78 -0
- data/Gemfile +8 -4
- data/README.adoc +2 -0
- data/Rakefile +3 -3
- data/docs/Gemfile +10 -0
- data/docs/INDEX.adoc +45 -0
- data/docs/_advanced/index.adoc +15 -0
- data/docs/_advanced/schema.adoc +112 -0
- data/docs/_advanced/step-map.adoc +66 -0
- data/docs/_advanced/steps.adoc +88 -0
- data/docs/_advanced/test-builder.adoc +61 -0
- data/docs/_advanced/transform.adoc +92 -0
- data/docs/_config.yml +174 -0
- data/docs/_features/html-input.adoc +69 -0
- data/docs/_features/html-output.adoc +45 -0
- data/docs/_features/index.adoc +15 -0
- data/docs/_features/marks.adoc +86 -0
- data/docs/_features/node-types.adoc +124 -0
- data/docs/_features/user-mentions.adoc +47 -0
- data/docs/_guides/custom-nodes.adoc +107 -0
- data/docs/_guides/index.adoc +13 -0
- data/docs/_guides/round-trip-html.adoc +91 -0
- data/docs/_guides/serialization.adoc +109 -0
- data/docs/_pages/index.adoc +67 -0
- data/docs/_reference/document-api.adoc +49 -0
- data/docs/_reference/index.adoc +14 -0
- data/docs/_reference/node-api.adoc +79 -0
- data/docs/_reference/schema-api.adoc +95 -0
- data/docs/_reference/transform-api.adoc +77 -0
- data/docs/_understanding/document-model.adoc +65 -0
- data/docs/_understanding/fragment.adoc +52 -0
- data/docs/_understanding/index.adoc +14 -0
- data/docs/_understanding/resolved-position.adoc +53 -0
- data/docs/_understanding/slice.adoc +54 -0
- data/docs/lychee.toml +63 -0
- 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 +19 -11
- data/lib/prosereflect/bullet_list.rb +36 -29
- data/lib/prosereflect/code_block.rb +23 -27
- data/lib/prosereflect/code_block_wrapper.rb +12 -13
- data/lib/prosereflect/document.rb +14 -22
- data/lib/prosereflect/fragment.rb +249 -0
- data/lib/prosereflect/hard_break.rb +6 -6
- data/lib/prosereflect/heading.rb +14 -15
- data/lib/prosereflect/horizontal_rule.rb +23 -14
- data/lib/prosereflect/image.rb +32 -23
- data/lib/prosereflect/input/html.rb +179 -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 +171 -33
- data/lib/prosereflect/ordered_list.rb +17 -14
- data/lib/prosereflect/output/html.rb +279 -50
- data/lib/prosereflect/output.rb +7 -0
- data/lib/prosereflect/paragraph.rb +11 -13
- data/lib/prosereflect/parser.rb +56 -66
- data/lib/prosereflect/resolved_pos.rb +256 -0
- data/lib/prosereflect/schema/attribute.rb +57 -0
- data/lib/prosereflect/schema/content_match.rb +656 -0
- data/lib/prosereflect/schema/fragment.rb +166 -0
- data/lib/prosereflect/schema/mark.rb +121 -0
- data/lib/prosereflect/schema/mark_type.rb +130 -0
- data/lib/prosereflect/schema/node.rb +236 -0
- data/lib/prosereflect/schema/node_type.rb +274 -0
- data/lib/prosereflect/schema/schema_main.rb +190 -0
- data/lib/prosereflect/schema/spec.rb +92 -0
- data/lib/prosereflect/schema.rb +39 -0
- 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 +35 -11
- data/lib/prosereflect/transform/attr_step.rb +157 -0
- data/lib/prosereflect/transform/insert_step.rb +115 -0
- data/lib/prosereflect/transform/mapping.rb +82 -0
- data/lib/prosereflect/transform/mark_step.rb +269 -0
- data/lib/prosereflect/transform/replace_around_step.rb +181 -0
- data/lib/prosereflect/transform/replace_step.rb +157 -0
- data/lib/prosereflect/transform/slice.rb +91 -0
- data/lib/prosereflect/transform/step.rb +89 -0
- data/lib/prosereflect/transform/step_map.rb +126 -0
- data/lib/prosereflect/transform/structure.rb +120 -0
- data/lib/prosereflect/transform/transform.rb +341 -0
- data/lib/prosereflect/transform.rb +26 -0
- data/lib/prosereflect/user.rb +15 -15
- data/lib/prosereflect/version.rb +1 -1
- data/lib/prosereflect.rb +30 -17
- data/prosereflect.gemspec +17 -16
- data/spec/fixtures/documents/formatted_text.yaml +14 -0
- data/spec/fixtures/documents/heading_paragraph.yaml +16 -0
- data/spec/fixtures/documents/lists_doc.yaml +32 -0
- data/spec/fixtures/documents/mixed_content.yaml +40 -0
- data/spec/fixtures/documents/nested_doc.yaml +20 -0
- data/spec/fixtures/documents/simple_doc.yaml +6 -0
- data/spec/fixtures/documents/table_doc.yaml +32 -0
- data/spec/fixtures/documents/transform_test.yaml +14 -0
- data/spec/fixtures/schema/custom_schema.rb +37 -0
- data/spec/fixtures/schema/test_schema.rb +46 -0
- data/spec/fixtures/test_builder/helpers.rb +212 -0
- data/spec/prosereflect/document_spec.rb +332 -330
- data/spec/prosereflect/fragment_spec.rb +273 -0
- data/spec/prosereflect/hard_break_spec.rb +125 -125
- data/spec/prosereflect/input/html_spec.rb +718 -522
- data/spec/prosereflect/node_spec.rb +311 -182
- data/spec/prosereflect/output/html_spec.rb +105 -105
- data/spec/prosereflect/output/whitespace_spec.rb +248 -0
- data/spec/prosereflect/paragraph_spec.rb +275 -274
- data/spec/prosereflect/parser/round_trip_spec.rb +472 -0
- data/spec/prosereflect/parser_spec.rb +185 -180
- data/spec/prosereflect/resolved_pos_spec.rb +74 -0
- data/spec/prosereflect/schema/conftest.rb +68 -0
- data/spec/prosereflect/schema/content_match_spec.rb +237 -0
- data/spec/prosereflect/schema/mark_spec.rb +274 -0
- data/spec/prosereflect/schema/mark_type_spec.rb +86 -0
- data/spec/prosereflect/schema/node_type_spec.rb +142 -0
- data/spec/prosereflect/schema/schema_spec.rb +194 -0
- 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/test_builder/marks_spec.rb +127 -0
- data/spec/prosereflect/text_spec.rb +133 -132
- data/spec/prosereflect/transform/equivalence_spec.rb +487 -0
- data/spec/prosereflect/transform/mapping_spec.rb +226 -0
- data/spec/prosereflect/transform/replace_spec.rb +832 -0
- data/spec/prosereflect/transform/replace_step_spec.rb +157 -0
- data/spec/prosereflect/transform/slice_spec.rb +48 -0
- data/spec/prosereflect/transform/step_map_spec.rb +70 -0
- data/spec/prosereflect/transform/step_spec.rb +211 -0
- data/spec/prosereflect/transform/structure_spec.rb +98 -0
- data/spec/prosereflect/transform/transform_spec.rb +238 -0
- data/spec/prosereflect/user_spec.rb +31 -28
- data/spec/prosereflect_spec.rb +28 -26
- data/spec/spec_helper.rb +7 -6
- data/spec/support/matchers.rb +6 -6
- data/spec/support/shared_examples.rb +49 -49
- metadata +96 -5
- data/spec/prosereflect/version_spec.rb +0 -11
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe Prosereflect::Transform::Transform do
|
|
6
|
+
let(:doc) { Prosereflect::Document.new }
|
|
7
|
+
|
|
8
|
+
describe "creation" do
|
|
9
|
+
it "creates transform with document" do
|
|
10
|
+
transform = described_class.new(doc)
|
|
11
|
+
expect(transform.doc).to eq(doc)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "starts with empty steps" do
|
|
15
|
+
transform = described_class.new(doc)
|
|
16
|
+
expect(transform.size).to eq(0)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "add_mark" do
|
|
21
|
+
it "adds mark step to transform" do
|
|
22
|
+
transform = described_class.new(doc)
|
|
23
|
+
mark = Prosereflect::Mark::Bold.new
|
|
24
|
+
transform.add_mark(0, 10, mark)
|
|
25
|
+
expect(transform.size).to eq(1)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "remove_mark" do
|
|
30
|
+
it "adds remove mark step to transform" do
|
|
31
|
+
transform = described_class.new(doc)
|
|
32
|
+
mark = Prosereflect::Mark::Bold.new
|
|
33
|
+
transform.remove_mark(0, 10, mark)
|
|
34
|
+
expect(transform.size).to eq(1)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe "insert" do
|
|
39
|
+
it "adds insert step to transform" do
|
|
40
|
+
transform = described_class.new(doc)
|
|
41
|
+
text = Prosereflect::Text.new(text: "hello")
|
|
42
|
+
transform.insert(0, text)
|
|
43
|
+
expect(transform.size).to eq(1)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "delete" do
|
|
48
|
+
it "adds delete step to transform" do
|
|
49
|
+
transform = described_class.new(doc)
|
|
50
|
+
transform.delete(0, 5)
|
|
51
|
+
expect(transform.size).to eq(1)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe "replace" do
|
|
56
|
+
it "adds replace step to transform" do
|
|
57
|
+
transform = described_class.new(doc)
|
|
58
|
+
slice = Prosereflect::Transform::Slice.empty
|
|
59
|
+
transform.replace(0, 5, slice)
|
|
60
|
+
expect(transform.size).to eq(1)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "defaults to empty slice" do
|
|
64
|
+
transform = described_class.new(doc)
|
|
65
|
+
transform.replace(0, 5)
|
|
66
|
+
expect(transform.size).to eq(1)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "replace_with" do
|
|
71
|
+
it "adds replace step with nodes" do
|
|
72
|
+
transform = described_class.new(doc)
|
|
73
|
+
text = Prosereflect::Text.new(text: "x")
|
|
74
|
+
transform.replace_with(0, 5, text)
|
|
75
|
+
expect(transform.size).to eq(1)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "accepts multiple nodes" do
|
|
79
|
+
transform = described_class.new(doc)
|
|
80
|
+
t1 = Prosereflect::Text.new(text: "a")
|
|
81
|
+
t2 = Prosereflect::Text.new(text: "b")
|
|
82
|
+
transform.replace_with(0, 5, t1, t2)
|
|
83
|
+
expect(transform.size).to eq(1)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe "set_node_attribute" do
|
|
88
|
+
it "adds attr step to transform" do
|
|
89
|
+
transform = described_class.new(doc)
|
|
90
|
+
transform.set_node_attribute(0, { "level" => 2 })
|
|
91
|
+
expect(transform.size).to eq(1)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe "set_doc_attribute" do
|
|
96
|
+
it "adds doc attr step to transform" do
|
|
97
|
+
transform = described_class.new(doc)
|
|
98
|
+
transform.set_doc_attribute({ "meta" => 1 })
|
|
99
|
+
expect(transform.size).to eq(1)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe "empty?" do
|
|
104
|
+
it "returns true for new transform" do
|
|
105
|
+
transform = described_class.new(doc)
|
|
106
|
+
expect(transform.empty?).to be true
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "returns false after adding step" do
|
|
110
|
+
transform = described_class.new(doc)
|
|
111
|
+
transform.delete(0, 5)
|
|
112
|
+
expect(transform.empty?).to be false
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe "clone" do
|
|
117
|
+
it "creates new transform with same document" do
|
|
118
|
+
transform = described_class.new(doc)
|
|
119
|
+
cloned = transform.clone
|
|
120
|
+
expect(cloned.doc).to eq(doc)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "clone does not share steps" do
|
|
124
|
+
transform = described_class.new(doc)
|
|
125
|
+
transform.delete(0, 5)
|
|
126
|
+
cloned = transform.clone
|
|
127
|
+
expect(cloned.size).to eq(0)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe "rollback" do
|
|
132
|
+
it "returns self for chaining on empty transform" do
|
|
133
|
+
transform = described_class.new(doc)
|
|
134
|
+
result = transform.rollback
|
|
135
|
+
expect(result).to eq(transform)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
describe "maps" do
|
|
140
|
+
it "returns empty mapping array for new transform" do
|
|
141
|
+
transform = described_class.new(doc)
|
|
142
|
+
expect(transform.maps).to eq([])
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "returns mapping after adding steps" do
|
|
146
|
+
transform = described_class.new(doc)
|
|
147
|
+
transform.delete(0, 5)
|
|
148
|
+
expect(transform.maps.length).to eq(1)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe "size" do
|
|
153
|
+
it "returns number of steps" do
|
|
154
|
+
transform = described_class.new(doc)
|
|
155
|
+
expect(transform.size).to eq(0)
|
|
156
|
+
|
|
157
|
+
transform.delete(0, 5)
|
|
158
|
+
expect(transform.size).to eq(1)
|
|
159
|
+
|
|
160
|
+
transform.delete(0, 5)
|
|
161
|
+
expect(transform.size).to eq(2)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
describe "add_step" do
|
|
166
|
+
it "returns self for chaining" do
|
|
167
|
+
transform = described_class.new(doc)
|
|
168
|
+
step = Prosereflect::Transform::ReplaceStep.new(0, 5)
|
|
169
|
+
result = transform.add_step(step)
|
|
170
|
+
expect(result).to eq(transform)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it "tracks mapping" do
|
|
174
|
+
transform = described_class.new(doc)
|
|
175
|
+
step = Prosereflect::Transform::ReplaceStep.new(0, 5)
|
|
176
|
+
transform.add_step(step)
|
|
177
|
+
expect(transform.maps.length).to eq(1)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
describe "split" do
|
|
182
|
+
it "adds split step to transform" do
|
|
183
|
+
doc_with_content = Prosereflect::Parser.parse_document({
|
|
184
|
+
"type" => "doc",
|
|
185
|
+
"content" => [
|
|
186
|
+
{
|
|
187
|
+
"type" => "paragraph",
|
|
188
|
+
"content" => [
|
|
189
|
+
{ "type" => "text", "text" => "Hello World" },
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
})
|
|
194
|
+
transform = described_class.new(doc_with_content)
|
|
195
|
+
transform.split(5)
|
|
196
|
+
expect(transform.size).to eq(1)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
describe "join" do
|
|
201
|
+
it "adds join step to transform" do
|
|
202
|
+
doc_with_two_paras = Prosereflect::Parser.parse_document({
|
|
203
|
+
"type" => "doc",
|
|
204
|
+
"content" => [
|
|
205
|
+
{
|
|
206
|
+
"type" => "paragraph",
|
|
207
|
+
"content" => [
|
|
208
|
+
{ "type" => "text", "text" => "Hello" },
|
|
209
|
+
],
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"type" => "paragraph",
|
|
213
|
+
"content" => [
|
|
214
|
+
{ "type" => "text", "text" => "World" },
|
|
215
|
+
],
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
})
|
|
219
|
+
transform = described_class.new(doc_with_two_paras)
|
|
220
|
+
transform.join(8)
|
|
221
|
+
expect(transform.size).to eq(1)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
describe "to_s" do
|
|
226
|
+
it "returns string representation" do
|
|
227
|
+
transform = described_class.new(doc)
|
|
228
|
+
expect(transform.to_s).to include("Transform")
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
describe "inspect" do
|
|
233
|
+
it "returns same as to_s" do
|
|
234
|
+
transform = described_class.new(doc)
|
|
235
|
+
expect(transform.inspect).to eq(transform.to_s)
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
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,17 @@
|
|
|
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
|
+
require "prosereflect/schema"
|
|
7
8
|
|
|
8
9
|
# Load shared examples
|
|
9
|
-
Dir[File.join(__dir__,
|
|
10
|
+
Dir[File.join(__dir__, "support", "**", "*.rb")].each { |f| require f }
|
|
10
11
|
|
|
11
12
|
RSpec.configure do |config|
|
|
12
13
|
# Enable flags like --only-failures and --next-failure
|
|
13
|
-
config.example_status_persistence_file_path =
|
|
14
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
|
14
15
|
|
|
15
16
|
# Disable RSpec exposing methods globally on `Module` and `main`
|
|
16
17
|
config.disable_monkey_patching!
|
data/spec/support/matchers.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "yaml"
|
|
4
|
+
require "json"
|
|
5
5
|
|
|
6
6
|
# Custom RSpec matcher for comparing JSON structures
|
|
7
7
|
RSpec::Matchers.define :be_equivalent_json do |expected|
|
|
@@ -64,7 +64,7 @@ RSpec::Matchers.define :have_equivalent_structure do |expected|
|
|
|
64
64
|
# Parse strings if needed
|
|
65
65
|
expected_data = case expected
|
|
66
66
|
when String
|
|
67
|
-
if expected.strip.start_with?(
|
|
67
|
+
if expected.strip.start_with?("{", "[")
|
|
68
68
|
begin
|
|
69
69
|
JSON.parse(expected)
|
|
70
70
|
rescue StandardError
|
|
@@ -79,7 +79,7 @@ RSpec::Matchers.define :have_equivalent_structure do |expected|
|
|
|
79
79
|
|
|
80
80
|
actual_data = case actual
|
|
81
81
|
when String
|
|
82
|
-
if actual.strip.start_with?(
|
|
82
|
+
if actual.strip.start_with?("{", "[")
|
|
83
83
|
begin
|
|
84
84
|
JSON.parse(actual)
|
|
85
85
|
rescue StandardError
|
|
@@ -98,7 +98,7 @@ RSpec::Matchers.define :have_equivalent_structure do |expected|
|
|
|
98
98
|
failure_message do |actual|
|
|
99
99
|
expected_data = case expected
|
|
100
100
|
when String
|
|
101
|
-
if expected.strip.start_with?(
|
|
101
|
+
if expected.strip.start_with?("{", "[")
|
|
102
102
|
begin
|
|
103
103
|
JSON.parse(expected)
|
|
104
104
|
rescue StandardError
|
|
@@ -113,7 +113,7 @@ RSpec::Matchers.define :have_equivalent_structure do |expected|
|
|
|
113
113
|
|
|
114
114
|
actual_data = case actual
|
|
115
115
|
when String
|
|
116
|
-
if actual.strip.start_with?(
|
|
116
|
+
if actual.strip.start_with?("{", "[")
|
|
117
117
|
begin
|
|
118
118
|
JSON.parse(actual)
|
|
119
119
|
rescue StandardError
|