revix 0.1.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 +7 -0
- data/.gitignore +12 -0
- data/Gemfile +10 -0
- data/LICENSE +25 -0
- data/README.adoc +317 -0
- data/Rakefile +8 -0
- data/lib/revix/amendment.rb +27 -0
- data/lib/revix/classification.rb +21 -0
- data/lib/revix/contributor.rb +21 -0
- data/lib/revix/date_info.rb +21 -0
- data/lib/revix/location.rb +26 -0
- data/lib/revix/name.rb +21 -0
- data/lib/revix/organization.rb +24 -0
- data/lib/revix/person.rb +18 -0
- data/lib/revix/revision.rb +30 -0
- data/lib/revix/revision_history.rb +18 -0
- data/lib/revix/version.rb +5 -0
- data/lib/revix.rb +29 -0
- data/revix.gemspec +35 -0
- data/spec/fixtures/iho_sample.yaml +75 -0
- data/spec/fixtures/ogc_sample.yaml +31 -0
- data/spec/fixtures/sample.xml +54 -0
- data/spec/fixtures/sample.yaml +41 -0
- data/spec/models/amendment_spec.rb +91 -0
- data/spec/models/revision_history_spec.rb +75 -0
- data/spec/models/revision_spec.rb +57 -0
- data/spec/revix_spec.rb +6 -0
- data/spec/spec_helper.rb +17 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 84fc11db5dc8582011c975954500bc7cdf138644d2eeb23f8a7be8e84e9e19a5
|
4
|
+
data.tar.gz: c4a80aaf7fc824afdd86a07637db47a016f5d2dc8090aaf1da147259dc2ed963
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 42ae71d3dacde27dbebb7dc4ba5ae7b23e428946286c57d84b4e92f5fa2493b93587c8ca0adc331d2a1c3d84b5d6454ad3489c72b9ba0aef300645bdea0412b7
|
7
|
+
data.tar.gz: ca6fb8744817b6d489d25e33ad9df7b509abbf423d79ac73b4c656319b875dc01d7620d9106c9dac855294a2c5be8a70c13445837a9865e8ad9f01e4fce9e647
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
BSD 2-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2025, Ribose Inc.
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
8
|
+
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
10
|
+
list of conditions and the following disclaimer.
|
11
|
+
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
14
|
+
and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
20
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
21
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
23
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
24
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.adoc
ADDED
@@ -0,0 +1,317 @@
|
|
1
|
+
= Revix: revision history models
|
2
|
+
|
3
|
+
image:https://img.shields.io/gem/v/revix.svg["Gem Version", link="https://rubygems.org/gems/revix"]
|
4
|
+
image:https://github.com/metanorma/revix/workflows/ubuntu/badge.svg["Ubuntu Build Status", link="https://github.com/metanorma/revix/actions?query=workflow%3Aubuntu"]
|
5
|
+
image:https://github.com/metanorma/revix/workflows/macos/badge.svg["OSX Build Status", link="https://github.com/metanorma/revix/actions?query=workflow%3Amacos"]
|
6
|
+
image:https://github.com/metanorma/revix/workflows/windows/badge.svg["Windows Build Status", link="https://github.com/metanorma/revix/actions?query=workflow%3Awindows"]
|
7
|
+
image:https://codeclimate.com/github/metanorma/revix/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/revix"]
|
8
|
+
image:https://img.shields.io/github/issues-pr-raw/metanorma/revix.svg["Pull Requests", link="https://github.com/metanorma/revix/pulls"]
|
9
|
+
image:https://img.shields.io/github/commits-since/metanorma/revix/latest.svg["Commits since latest",link="https://github.com/metanorma/revix/releases"]
|
10
|
+
|
11
|
+
== Purpose
|
12
|
+
|
13
|
+
Revix is a Ruby gem for working with Metanorma document revision history.
|
14
|
+
|
15
|
+
It provides a set of models and utilities for parsing, manipulating, and
|
16
|
+
serializing revision history data in YAML and XML formats.
|
17
|
+
|
18
|
+
== Installation
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
[source,ruby]
|
23
|
+
----
|
24
|
+
gem 'revix'
|
25
|
+
----
|
26
|
+
|
27
|
+
And then execute:
|
28
|
+
|
29
|
+
[source,shell]
|
30
|
+
----
|
31
|
+
$ bundle install
|
32
|
+
----
|
33
|
+
|
34
|
+
Or install it yourself as:
|
35
|
+
|
36
|
+
[source,shell]
|
37
|
+
----
|
38
|
+
$ gem install revix
|
39
|
+
----
|
40
|
+
|
41
|
+
== Usage
|
42
|
+
|
43
|
+
=== Parsing revision history
|
44
|
+
|
45
|
+
==== From YAML
|
46
|
+
|
47
|
+
[source,yaml]
|
48
|
+
----
|
49
|
+
- edition: 1.0.0
|
50
|
+
date:
|
51
|
+
- type: published
|
52
|
+
value: 2012-04
|
53
|
+
contributor:
|
54
|
+
- person:
|
55
|
+
name:
|
56
|
+
abbreviation: JMS
|
57
|
+
completename: J. Michael Straczynski
|
58
|
+
amend:
|
59
|
+
- description: Approved edition of S-102
|
60
|
+
location:
|
61
|
+
- type: clause
|
62
|
+
value: 4.0
|
63
|
+
- type: whole
|
64
|
+
----
|
65
|
+
|
66
|
+
[source,ruby]
|
67
|
+
----
|
68
|
+
require 'revix'
|
69
|
+
|
70
|
+
# Parse from YAML string
|
71
|
+
yaml_content = File.read('revision_history.yaml')
|
72
|
+
history = Revix::RevisionHistory.from_yaml(yaml_content)
|
73
|
+
|
74
|
+
# Access revision data
|
75
|
+
history.revisions.each do |revision|
|
76
|
+
puts "Edition: #{revision.edition}"
|
77
|
+
puts "Date: #{revision.date.first.value} (#{revision.date.first.type})"
|
78
|
+
|
79
|
+
revision.contributor.each do |contributor|
|
80
|
+
if contributor.person
|
81
|
+
puts "Contributor: #{contributor.person.name.completename} (#{contributor.person.name.abbreviation})"
|
82
|
+
elsif contributor.organization
|
83
|
+
puts "Contributor: #{contributor.organization.name}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
revision.amend.each do |amendment|
|
88
|
+
puts "Amendment: #{amendment.description}"
|
89
|
+
|
90
|
+
amendment.location&.each do |location|
|
91
|
+
if location.value
|
92
|
+
puts " Location: #{location.type}=#{location.value}"
|
93
|
+
else
|
94
|
+
puts " Location: #{location.type}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
amendment.classification&.each do |classification|
|
99
|
+
puts " Classification: #{classification.tag} = #{classification.value}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
----
|
104
|
+
|
105
|
+
==== From XML
|
106
|
+
|
107
|
+
[source,xml]
|
108
|
+
----
|
109
|
+
<revision-history>
|
110
|
+
<revision>
|
111
|
+
<date type="published">2012-04</date>
|
112
|
+
<edition>1.0.0</edition>
|
113
|
+
<contributor>
|
114
|
+
<person>
|
115
|
+
<name abbreviation="JMS">
|
116
|
+
<completename>J. Michael Straczynski</completename>
|
117
|
+
</name>
|
118
|
+
</person>
|
119
|
+
</contributor>
|
120
|
+
<amend>
|
121
|
+
<amendment>
|
122
|
+
<description>Approved edition of S-102</description>
|
123
|
+
<location type="clause">4.0</location>
|
124
|
+
<location type="whole"/>
|
125
|
+
</amendment>
|
126
|
+
</amend>
|
127
|
+
</revision>
|
128
|
+
</revision-history>
|
129
|
+
----
|
130
|
+
|
131
|
+
[source,ruby]
|
132
|
+
----
|
133
|
+
require 'revix'
|
134
|
+
|
135
|
+
# Parse from XML string
|
136
|
+
xml_content = File.read('revision_history.xml')
|
137
|
+
history = Revix::RevisionHistory.from_xml(xml_content)
|
138
|
+
|
139
|
+
# Access revision data (same as with YAML)
|
140
|
+
----
|
141
|
+
|
142
|
+
=== Serializing revision history
|
143
|
+
|
144
|
+
==== To YAML
|
145
|
+
|
146
|
+
[source,ruby]
|
147
|
+
----
|
148
|
+
require 'revix'
|
149
|
+
|
150
|
+
# Create a revision history object
|
151
|
+
history = Revix::RevisionHistory.new(revisions: [
|
152
|
+
Revix::Revision.new(
|
153
|
+
date: [Revix::DateInfo.new(type: "published", value: "2012-04")],
|
154
|
+
edition: "1.0.0",
|
155
|
+
contributor: [
|
156
|
+
Revix::Contributor.new(
|
157
|
+
person: Revix::Person.new(
|
158
|
+
name: Revix::Name.new(
|
159
|
+
abbreviation: "JMS",
|
160
|
+
completename: "J. Michael Straczynski"
|
161
|
+
)
|
162
|
+
)
|
163
|
+
)
|
164
|
+
],
|
165
|
+
amend: [
|
166
|
+
Revix::Amendment.new(
|
167
|
+
description: "Approved edition of S-102",
|
168
|
+
location: [
|
169
|
+
Revix::Location.new(type: "clause", value: "4.0"),
|
170
|
+
Revix::Location.new(type: "whole")
|
171
|
+
]
|
172
|
+
)
|
173
|
+
]
|
174
|
+
)
|
175
|
+
])
|
176
|
+
|
177
|
+
# Serialize to YAML
|
178
|
+
yaml_content = history.to_yaml
|
179
|
+
File.write('revision_history.yaml', yaml_content)
|
180
|
+
----
|
181
|
+
|
182
|
+
==== To XML
|
183
|
+
|
184
|
+
[source,ruby]
|
185
|
+
----
|
186
|
+
# Serialize to XML
|
187
|
+
xml_content = history.to_xml
|
188
|
+
File.write('revision_history.xml', xml_content)
|
189
|
+
----
|
190
|
+
|
191
|
+
== Data model
|
192
|
+
|
193
|
+
The Revix gem provides the following models.
|
194
|
+
|
195
|
+
[source]
|
196
|
+
----
|
197
|
+
+-------------------+
|
198
|
+
| RevisionHistory |
|
199
|
+
| |
|
200
|
+
| +revisions |
|
201
|
+
+--------+----------+
|
202
|
+
|
|
203
|
+
| 1..*
|
204
|
+
+--------v----------+ +------------+
|
205
|
+
| Revision | | DateInfo |
|
206
|
+
| | | |
|
207
|
+
| -edition |<>--->| -type |
|
208
|
+
| -relation_type | | -value |
|
209
|
+
| +date | | |
|
210
|
+
| +contributor | +------------+
|
211
|
+
| +amend |
|
212
|
+
+--------+----------+
|
213
|
+
|
|
214
|
+
+----+----+---------------------+
|
215
|
+
| | |
|
216
|
+
+---v---+ +---v----------+ +-------v--------+
|
217
|
+
|Person | | Organization | | Amendment |
|
218
|
+
| | | | | |
|
219
|
+
| +name | | -name | | -description |
|
220
|
+
| | | -subdivision | | -change |
|
221
|
+
| | | -abbreviation| | +location |
|
222
|
+
+---+---+ +--------------+ | +classification|
|
223
|
+
| +-------+--------+
|
224
|
+
| |
|
225
|
+
| +------------+------+
|
226
|
+
+---v---+ | |
|
227
|
+
| Name | +------+-------+ +-------+-------+
|
228
|
+
| | + Location | | Classification|
|
229
|
+
| -abbr | | | | |
|
230
|
+
| -full | | -type | | -tag |
|
231
|
+
+-------+ | -value | | -value |
|
232
|
+
+--------------+ +---------------+
|
233
|
+
----
|
234
|
+
|
235
|
+
=== RevisionHistory
|
236
|
+
|
237
|
+
The main container for all revisions.
|
238
|
+
|
239
|
+
`revisions`:: A collection of `Revision` objects
|
240
|
+
|
241
|
+
=== Revision
|
242
|
+
|
243
|
+
Represents a single revision entry.
|
244
|
+
|
245
|
+
`date`:: A collection of `DateInfo` objects
|
246
|
+
`edition`:: The version number as a string
|
247
|
+
`contributor`:: A collection of `Contributor` objects
|
248
|
+
`amend`:: A collection of `Amendment` objects
|
249
|
+
`relation_type`:: The relation type (optional)
|
250
|
+
|
251
|
+
=== DateInfo
|
252
|
+
|
253
|
+
Represents date information.
|
254
|
+
|
255
|
+
`type`:: The type of date (e.g., "published", "updated")
|
256
|
+
`value`:: The date value as a string
|
257
|
+
|
258
|
+
=== Contributor
|
259
|
+
|
260
|
+
Represents a contributor, which can be either a person or an organization.
|
261
|
+
|
262
|
+
`person`:: A `Person` object (optional)
|
263
|
+
`organization`:: An `Organization` object (optional)
|
264
|
+
|
265
|
+
=== Person
|
266
|
+
|
267
|
+
Represents a person contributor.
|
268
|
+
|
269
|
+
`name`:: A `Name` object
|
270
|
+
|
271
|
+
=== Organization
|
272
|
+
|
273
|
+
Represents an organization contributor.
|
274
|
+
|
275
|
+
`name`:: The organization name as a string
|
276
|
+
`subdivision`:: The organization subdivision as a string (optional)
|
277
|
+
`abbreviation`:: The organization abbreviation as a string (optional)
|
278
|
+
|
279
|
+
=== Name
|
280
|
+
|
281
|
+
Represents a person's name.
|
282
|
+
|
283
|
+
`abbreviation`:: The person's abbreviation or initials
|
284
|
+
`completename`:: The person's full name
|
285
|
+
|
286
|
+
=== Amendment
|
287
|
+
|
288
|
+
Represents an amendment.
|
289
|
+
|
290
|
+
`description`:: The amendment description as a string
|
291
|
+
`location`:: A collection of `Location` objects (optional)
|
292
|
+
`classification`:: A collection of `Classification` objects (optional)
|
293
|
+
`change`:: The type of change (default: "modify")
|
294
|
+
|
295
|
+
=== Location
|
296
|
+
|
297
|
+
Represents a location affected by an amendment.
|
298
|
+
|
299
|
+
`type`:: The location type. Accepts the defined Metanorma location types, including: `section`, `clause`, `part`, `paragraph`, `chapter`, `page`, `line`, `table`, `annex`, `figure`, `example`, `note`, `formula`, `list`, `time`, `anchor`, `whole`.
|
300
|
+
`value`:: The location value (e.g., `4.0`, `B`), can be `nil` for types like `whole`.
|
301
|
+
|
302
|
+
=== Classification
|
303
|
+
|
304
|
+
Represents a classification tag/value pair.
|
305
|
+
|
306
|
+
`tag`:: The classification tag (e.g., "severity", "type")
|
307
|
+
`value`:: The classification value (e.g., "major", "editorial")
|
308
|
+
|
309
|
+
== Copyright
|
310
|
+
|
311
|
+
This gem is developed, maintained and funded by
|
312
|
+
https://www.ribose.com[Ribose Inc.]
|
313
|
+
|
314
|
+
== License
|
315
|
+
|
316
|
+
The gem is available as open source under the terms of the
|
317
|
+
https://opensource.org/licenses/BSD-2-Clause[2-Clause BSD License].
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class Amendment < Lutaml::Model::Serializable
|
7
|
+
attribute :description, :string
|
8
|
+
attribute :location, Location, collection: true
|
9
|
+
attribute :classification, Classification, collection: true
|
10
|
+
attribute :change, :string, default: -> { "modify" }
|
11
|
+
|
12
|
+
xml do
|
13
|
+
root "amend"
|
14
|
+
map_element "description", to: :description
|
15
|
+
map_element "location", to: :location
|
16
|
+
map_element "classification", to: :classification
|
17
|
+
map_element "change", to: :change
|
18
|
+
end
|
19
|
+
|
20
|
+
key_value do
|
21
|
+
map "description", to: :description
|
22
|
+
map "location", to: :location
|
23
|
+
map "classification", to: :classification
|
24
|
+
map "change", to: :change
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class Classification < Lutaml::Model::Serializable
|
7
|
+
attribute :tag, :string
|
8
|
+
attribute :value, :string
|
9
|
+
|
10
|
+
xml do
|
11
|
+
root "classification"
|
12
|
+
map_element "tag", to: :tag
|
13
|
+
map_element "value", to: :value
|
14
|
+
end
|
15
|
+
|
16
|
+
key_value do
|
17
|
+
map "tag", to: :tag
|
18
|
+
map "value", to: :value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class Contributor < Lutaml::Model::Serializable
|
7
|
+
attribute :person, Person
|
8
|
+
attribute :organization, Organization
|
9
|
+
|
10
|
+
xml do
|
11
|
+
root "contributor"
|
12
|
+
map_element "person", to: :person
|
13
|
+
map_element "organization", to: :organization
|
14
|
+
end
|
15
|
+
|
16
|
+
key_value do
|
17
|
+
map "person", to: :person
|
18
|
+
map "organization", to: :organization
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class DateInfo < Lutaml::Model::Serializable
|
7
|
+
attribute :type, :string
|
8
|
+
attribute :value, :string
|
9
|
+
|
10
|
+
xml do
|
11
|
+
root "date"
|
12
|
+
map_element "type", to: :type
|
13
|
+
map_element "value", to: :value
|
14
|
+
end
|
15
|
+
|
16
|
+
key_value do
|
17
|
+
map "type", to: :type
|
18
|
+
map "value", to: :value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class Location < Lutaml::Model::Serializable
|
7
|
+
VALID_TYPES = %w[
|
8
|
+
section clause part paragraph chapter page line table annex figure
|
9
|
+
example note formula list time anchor whole
|
10
|
+
].freeze
|
11
|
+
|
12
|
+
attribute :value, :string
|
13
|
+
attribute :type, :string, values: VALID_TYPES
|
14
|
+
|
15
|
+
xml do
|
16
|
+
root "location"
|
17
|
+
map_content to: :value
|
18
|
+
map_attribute "type", to: :type
|
19
|
+
end
|
20
|
+
|
21
|
+
key_value do
|
22
|
+
map "value", to: :value
|
23
|
+
map "type", to: :type
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/revix/name.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class Name < Lutaml::Model::Serializable
|
7
|
+
attribute :abbreviation, :string
|
8
|
+
attribute :completename, :string
|
9
|
+
|
10
|
+
xml do
|
11
|
+
root "name"
|
12
|
+
map_element "abbreviation", to: :abbreviation
|
13
|
+
map_element "completename", to: :completename
|
14
|
+
end
|
15
|
+
|
16
|
+
key_value do
|
17
|
+
map "abbreviation", to: :abbreviation
|
18
|
+
map "completename", to: :completename
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class Organization < Lutaml::Model::Serializable
|
7
|
+
attribute :name, :string
|
8
|
+
attribute :subdivision, :string
|
9
|
+
attribute :abbreviation, :string
|
10
|
+
|
11
|
+
xml do
|
12
|
+
root "organization"
|
13
|
+
map_element "name", to: :name
|
14
|
+
map_element "subdivision", to: :subdivision
|
15
|
+
map_element "abbreviation", to: :abbreviation
|
16
|
+
end
|
17
|
+
|
18
|
+
key_value do
|
19
|
+
map "name", to: :name
|
20
|
+
map "subdivision", to: :subdivision
|
21
|
+
map "abbreviation", to: :abbreviation
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/revix/person.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class Person < Lutaml::Model::Serializable
|
7
|
+
attribute :name, Name
|
8
|
+
|
9
|
+
xml do
|
10
|
+
root "person"
|
11
|
+
map_element "name", to: :name
|
12
|
+
end
|
13
|
+
|
14
|
+
key_value do
|
15
|
+
map "name", to: :name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class Revision < Lutaml::Model::Serializable
|
7
|
+
attribute :date, DateInfo, collection: true
|
8
|
+
attribute :edition, :string
|
9
|
+
attribute :contributor, Contributor, collection: true
|
10
|
+
attribute :amend, Amendment, collection: true
|
11
|
+
attribute :relation_type, Amendment, collection: true
|
12
|
+
|
13
|
+
xml do
|
14
|
+
root "revision"
|
15
|
+
map_element "date", to: :date
|
16
|
+
map_element "edition", to: :edition
|
17
|
+
map_element "contributor", to: :contributor
|
18
|
+
map_element "amend", to: :amend
|
19
|
+
map_element "relation", to: :relation_type
|
20
|
+
end
|
21
|
+
|
22
|
+
key_value do
|
23
|
+
map "date", to: :date
|
24
|
+
map "edition", to: :edition
|
25
|
+
map "contributor", to: :contributor
|
26
|
+
map "amend", to: :amend
|
27
|
+
map "relation", to: :relation_type
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "lutaml/model"
|
4
|
+
|
5
|
+
module Revix
|
6
|
+
class RevisionHistory < Lutaml::Model::Serializable
|
7
|
+
attribute :revisions, Revix::Revision, collection: true
|
8
|
+
|
9
|
+
xml do
|
10
|
+
root "revision-history"
|
11
|
+
map_element "revision", to: :revisions
|
12
|
+
end
|
13
|
+
|
14
|
+
key_value do
|
15
|
+
map "revisions", to: :revisions
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/revix.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "revix/version"
|
4
|
+
require "lutaml/model"
|
5
|
+
|
6
|
+
module Revix
|
7
|
+
class Error < StandardError; end
|
8
|
+
end
|
9
|
+
|
10
|
+
require_relative "revix/name"
|
11
|
+
require_relative "revix/person"
|
12
|
+
require_relative "revix/organization"
|
13
|
+
require_relative "revix/contributor"
|
14
|
+
require_relative "revix/date_info"
|
15
|
+
require_relative "revix/classification"
|
16
|
+
require_relative "revix/location"
|
17
|
+
require_relative "revix/amendment"
|
18
|
+
require_relative "revix/revision"
|
19
|
+
require_relative "revix/revision_history"
|
20
|
+
|
21
|
+
require "lutaml/model/xml_adapter/nokogiri_adapter"
|
22
|
+
require "lutaml/model/json_adapter/standard_json_adapter"
|
23
|
+
require "lutaml/model/yaml_adapter/standard_yaml_adapter"
|
24
|
+
|
25
|
+
Lutaml::Model::Config.configure do |config|
|
26
|
+
config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter
|
27
|
+
config.yaml_adapter = Lutaml::Model::YamlAdapter::StandardYamlAdapter
|
28
|
+
config.json_adapter = Lutaml::Model::JsonAdapter::StandardJsonAdapter
|
29
|
+
end
|
data/revix.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/revix/version"
|
4
|
+
|
5
|
+
all_files_in_git = Dir.chdir(File.expand_path(__dir__)) do
|
6
|
+
`git ls-files -z`.split("\x0")
|
7
|
+
end
|
8
|
+
|
9
|
+
Gem::Specification.new do |spec|
|
10
|
+
spec.name = "revix"
|
11
|
+
spec.version = Revix::VERSION
|
12
|
+
spec.authors = ["Ribose"]
|
13
|
+
spec.email = ["open.source@ribose.com"]
|
14
|
+
|
15
|
+
spec.summary = "Library to work with Metanorma document revision history."
|
16
|
+
spec.homepage = "https://github.com/metanorma/revix"
|
17
|
+
spec.license = "BSD-2-Clause"
|
18
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
19
|
+
|
20
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
21
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
22
|
+
spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
|
23
|
+
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
25
|
+
spec.files = all_files_in_git
|
26
|
+
.reject { |f| f.match(%r{\A(?:test|features|bin|\.)/}) }
|
27
|
+
|
28
|
+
spec.bindir = "exe"
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_dependency "lutaml-model", "~> 0.6"
|
33
|
+
spec.add_dependency "nokogiri"
|
34
|
+
spec.add_dependency "xml-c14n"
|
35
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
revisions:
|
2
|
+
- date:
|
3
|
+
- type: published
|
4
|
+
value: 2012-04
|
5
|
+
edition: 1.0.0
|
6
|
+
contributor:
|
7
|
+
- organization:
|
8
|
+
name: International Hydrographic Organization
|
9
|
+
subdivision: Transfer Standard Maintenance and Application Development
|
10
|
+
abbreviation: TSMAD
|
11
|
+
amend:
|
12
|
+
- description: Approved edition of S-102
|
13
|
+
- date:
|
14
|
+
- type: published
|
15
|
+
value: 2017-03
|
16
|
+
edition: 2.0.0
|
17
|
+
contributor:
|
18
|
+
- organization:
|
19
|
+
name: International Hydrographic Organization
|
20
|
+
subdivision: S-102 Project Team
|
21
|
+
abbreviation: S-102PT
|
22
|
+
amend:
|
23
|
+
- description: >
|
24
|
+
Updated clause 4.0 and 12.0.
|
25
|
+
|
26
|
+
Populated clause 9.0 and Annex B.
|
27
|
+
location:
|
28
|
+
- type: clause
|
29
|
+
value: 4.0
|
30
|
+
- type: clause
|
31
|
+
value: 12.0
|
32
|
+
- type: clause
|
33
|
+
value: 9.0
|
34
|
+
- type: annex
|
35
|
+
value: B
|
36
|
+
- date:
|
37
|
+
- type: updated
|
38
|
+
value: 2017-05
|
39
|
+
edition: 2.0.0
|
40
|
+
contributor:
|
41
|
+
- organization:
|
42
|
+
name: International Hydrographic Organization
|
43
|
+
subdivision: S-102 Project Team
|
44
|
+
abbreviation: S-102PT
|
45
|
+
amend:
|
46
|
+
- description: >
|
47
|
+
Modified clause 9.0 based on feedback at S-100WG2 meeting.
|
48
|
+
location:
|
49
|
+
- type: clause
|
50
|
+
value: 9.0
|
51
|
+
- date:
|
52
|
+
- type: updated
|
53
|
+
value: 2018-02
|
54
|
+
edition: 2.0.0
|
55
|
+
contributor:
|
56
|
+
- person:
|
57
|
+
name:
|
58
|
+
completename: Cliff Kottman
|
59
|
+
abbreviation: CK
|
60
|
+
amend:
|
61
|
+
- description: >
|
62
|
+
Modified clause 9.0. Deleted contents of Annex B in preparation for updated S-100 Part 10C guidance. Added Annex F: S-102 Dataset Size and Production, Annex G: Gridding Example, Annex H: Statement added for Multi-Resolution Gridding, Annex I: Statement for future S-102 Tiling.
|
63
|
+
location:
|
64
|
+
- type: clause
|
65
|
+
value: 9.0
|
66
|
+
- type: annex
|
67
|
+
value: B
|
68
|
+
- type: annex
|
69
|
+
value: F
|
70
|
+
- type: annex
|
71
|
+
value: G
|
72
|
+
- type: annex
|
73
|
+
value: H
|
74
|
+
- type: annex
|
75
|
+
value: I
|
@@ -0,0 +1,31 @@
|
|
1
|
+
revisions:
|
2
|
+
- date:
|
3
|
+
- type: published
|
4
|
+
value: 2020-06-04
|
5
|
+
edition: 0.9.0
|
6
|
+
contributor:
|
7
|
+
- person:
|
8
|
+
name:
|
9
|
+
completename: C. Heazel
|
10
|
+
abbreviation: CH
|
11
|
+
amend:
|
12
|
+
- description: Draft for review
|
13
|
+
location:
|
14
|
+
- type: whole
|
15
|
+
- date:
|
16
|
+
- type: published
|
17
|
+
value: 2020-06-07
|
18
|
+
edition: 0.9.1
|
19
|
+
contributor:
|
20
|
+
- person:
|
21
|
+
name:
|
22
|
+
completename: T. H. Kolbe
|
23
|
+
abbreviation: THK
|
24
|
+
amend:
|
25
|
+
- description: Bibliography was added
|
26
|
+
location:
|
27
|
+
- type: clause
|
28
|
+
value: 10
|
29
|
+
classification:
|
30
|
+
- tag: type
|
31
|
+
value: editorial
|
@@ -0,0 +1,54 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<revision-history>
|
3
|
+
<revision>
|
4
|
+
<date>
|
5
|
+
<type>published</type>
|
6
|
+
<value>2012-04</value>
|
7
|
+
</date>
|
8
|
+
<edition>1.0.0</edition>
|
9
|
+
<contributor>
|
10
|
+
<person>
|
11
|
+
<name>
|
12
|
+
<abbreviation>JMS</abbreviation>
|
13
|
+
<completename>J. Michael Straczynski</completename>
|
14
|
+
</name>
|
15
|
+
</person>
|
16
|
+
</contributor>
|
17
|
+
<amend>
|
18
|
+
<description>Approved edition of S-102</description>
|
19
|
+
</amend>
|
20
|
+
</revision>
|
21
|
+
<revision>
|
22
|
+
<date>
|
23
|
+
<type>updated</type>
|
24
|
+
<value>2017-03</value>
|
25
|
+
</date>
|
26
|
+
<edition>2.0.0</edition>
|
27
|
+
<contributor>
|
28
|
+
<organization>
|
29
|
+
<name>S-102PT</name>
|
30
|
+
</organization>
|
31
|
+
</contributor>
|
32
|
+
<amend>
|
33
|
+
<description>Updated clause 4.0 and 12.0.
|
34
|
+
|
35
|
+
Populated clause 9.0.</description>
|
36
|
+
<location type="clause">4.0</location>
|
37
|
+
<location type="clause">12.0</location>
|
38
|
+
<location type="clause">9.0</location>
|
39
|
+
<location type="whole"></location>
|
40
|
+
<classification>
|
41
|
+
<tag>severity</tag>
|
42
|
+
<value>major</value>
|
43
|
+
</classification>
|
44
|
+
<classification>
|
45
|
+
<tag>type</tag>
|
46
|
+
<value>editorial</value>
|
47
|
+
</classification>
|
48
|
+
</amend>
|
49
|
+
<amend>
|
50
|
+
<description>Deleted contents of Annex B in preparation for updated S-100 Part 10C guidance.</description>
|
51
|
+
<location type="annex">B</location>
|
52
|
+
</amend>
|
53
|
+
</revision>
|
54
|
+
</revision-history>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
revisions:
|
2
|
+
- date:
|
3
|
+
- type: published
|
4
|
+
value: 2012-04
|
5
|
+
edition: 1.0.0
|
6
|
+
contributor:
|
7
|
+
- person:
|
8
|
+
name:
|
9
|
+
abbreviation: JMS
|
10
|
+
completename: J. Michael Straczynski
|
11
|
+
amend:
|
12
|
+
- description: Approved edition of S-102
|
13
|
+
- date:
|
14
|
+
- type: updated
|
15
|
+
value: 2017-03
|
16
|
+
edition: 2.0.0
|
17
|
+
contributor:
|
18
|
+
- organization:
|
19
|
+
name: S-102PT
|
20
|
+
amend:
|
21
|
+
- description: |
|
22
|
+
Updated clause 4.0 and 12.0.
|
23
|
+
|
24
|
+
Populated clause 9.0.
|
25
|
+
location:
|
26
|
+
- type: clause
|
27
|
+
value: 4.0
|
28
|
+
- type: clause
|
29
|
+
value: 12.0
|
30
|
+
- type: clause
|
31
|
+
value: 9.0
|
32
|
+
- type: whole
|
33
|
+
classification:
|
34
|
+
- tag: severity
|
35
|
+
value: major
|
36
|
+
- tag: type
|
37
|
+
value: editorial
|
38
|
+
- description: Deleted contents of Annex B in preparation for updated S-100 Part 10C guidance.
|
39
|
+
location:
|
40
|
+
- type: annex
|
41
|
+
value: B
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe Revix::Amendment do
|
6
|
+
let(:simple_amendment_data) do
|
7
|
+
Revix::Amendment.new(description: "Approved edition of S-102")
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:complex_amendment_data) do
|
11
|
+
locations = [
|
12
|
+
Revix::Location.new(type: "clause", value: "4.0"),
|
13
|
+
Revix::Location.new(type: "clause", value: "12.0"),
|
14
|
+
Revix::Location.new(type: "clause", value: "9.0"),
|
15
|
+
Revix::Location.new(type: "whole", value: nil)
|
16
|
+
]
|
17
|
+
|
18
|
+
classifications = [
|
19
|
+
Revix::Classification.new(tag: "severity", value: "major"),
|
20
|
+
Revix::Classification.new(tag: "type", value: "editorial")
|
21
|
+
]
|
22
|
+
|
23
|
+
Revix::Amendment.new(
|
24
|
+
description: "Updated clause 4.0 and 12.0.\n\nPopulated clause 9.0.",
|
25
|
+
location: locations,
|
26
|
+
classification: classifications,
|
27
|
+
change: "modify"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
describe ".new" do
|
32
|
+
it "creates a simple Amendment object" do
|
33
|
+
amendment = simple_amendment_data
|
34
|
+
expect(amendment).to be_a(Revix::Amendment)
|
35
|
+
expect(amendment.description).to eq("Approved edition of S-102")
|
36
|
+
expect(amendment.location).to be_empty
|
37
|
+
expect(amendment.classification).to be_empty
|
38
|
+
expect(amendment.change).to eq("modify") # Default value
|
39
|
+
end
|
40
|
+
|
41
|
+
it "creates a complex Amendment object" do
|
42
|
+
amendment = complex_amendment_data
|
43
|
+
expect(amendment).to be_a(Revix::Amendment)
|
44
|
+
expect(amendment.description).to eq("Updated clause 4.0 and 12.0.\n\nPopulated clause 9.0.")
|
45
|
+
expect(amendment.location.size).to eq(4)
|
46
|
+
expect(amendment.location.first.type).to eq("clause")
|
47
|
+
expect(amendment.location.first.value).to eq("4.0")
|
48
|
+
expect(amendment.location.last.type).to eq("whole")
|
49
|
+
expect(amendment.location.last.value).to be_nil
|
50
|
+
expect(amendment.classification.size).to eq(2)
|
51
|
+
expect(amendment.classification.first.tag).to eq("severity")
|
52
|
+
expect(amendment.classification.first.value).to eq("major")
|
53
|
+
expect(amendment.change).to eq("modify")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#to_xml" do
|
58
|
+
it "converts a complex Amendment object to XML" do
|
59
|
+
amendment = complex_amendment_data
|
60
|
+
xml = amendment.to_xml
|
61
|
+
expect(xml).to be_a(String)
|
62
|
+
expect(xml).to include("<amend>")
|
63
|
+
expect(xml).to include("<description>Updated clause 4.0 and 12.0.\n\nPopulated clause 9.0.</description>")
|
64
|
+
expect(xml).to include('<location type="clause">4.0</location>')
|
65
|
+
expect(xml).to include('<location type="clause">12.0</location>')
|
66
|
+
expect(xml).to include('<location type="clause">9.0</location>')
|
67
|
+
expect(xml).to include('<location type="whole"></location>')
|
68
|
+
expect(xml).to include("<tag>severity</tag>")
|
69
|
+
expect(xml).to include("<value>major</value>")
|
70
|
+
expect(xml).to include("<tag>type</tag>")
|
71
|
+
expect(xml).to include("<value>editorial</value>")
|
72
|
+
expect(xml).to include("<change>modify</change>")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "performs round-trip conversion from XML to object and back" do
|
76
|
+
original = complex_amendment_data
|
77
|
+
xml1 = original.to_xml
|
78
|
+
|
79
|
+
# Parse back to object and generate XML again
|
80
|
+
parsed = Revix::Amendment.from_xml(xml1)
|
81
|
+
xml2 = parsed.to_xml
|
82
|
+
|
83
|
+
# Canonicalize both XMLs and compare using xml-c14n
|
84
|
+
c14n1 = Xml::C14n.format(xml1)
|
85
|
+
c14n2 = Xml::C14n.format(xml2)
|
86
|
+
|
87
|
+
expect(c14n2).to eq(c14n1)
|
88
|
+
expect(c14n2).to be_analogous_with(c14n1)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe Revix::RevisionHistory do
|
6
|
+
fixture_path = File.join(__dir__, "..", "fixtures")
|
7
|
+
let(:yaml_content) { File.read(File.join(fixture_path, "sample.yaml")) }
|
8
|
+
let(:xml_content) { File.read(File.join(fixture_path, "sample.xml")) }
|
9
|
+
let(:iho_yaml_content) { File.read(File.join(fixture_path, "iho_sample.yaml")) }
|
10
|
+
let(:ogc_yaml_content) { File.read(File.join(fixture_path, "ogc_sample.yaml")) }
|
11
|
+
|
12
|
+
describe ".from_yaml" do
|
13
|
+
it "parses YAML content into a RevisionHistory object" do
|
14
|
+
history = Revix::RevisionHistory.from_yaml(yaml_content)
|
15
|
+
expect(history).to be_a(Revix::RevisionHistory)
|
16
|
+
expect(history.revisions.size).to eq(2)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "parses IHO YAML content into a RevisionHistory object" do
|
20
|
+
history = Revix::RevisionHistory.from_yaml(iho_yaml_content)
|
21
|
+
expect(history).to be_a(Revix::RevisionHistory)
|
22
|
+
expect(history.revisions.size).to eq(4)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "parses OGC YAML content into a RevisionHistory object" do
|
26
|
+
history = Revix::RevisionHistory.from_yaml(ogc_yaml_content)
|
27
|
+
expect(history).to be_a(Revix::RevisionHistory)
|
28
|
+
expect(history.revisions.size).to eq(2)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ".from_xml" do
|
33
|
+
it "parses XML content into a RevisionHistory object" do
|
34
|
+
history = Revix::RevisionHistory.from_xml(xml_content)
|
35
|
+
expect(history).to be_a(Revix::RevisionHistory)
|
36
|
+
expect(history.revisions.size).to eq(2)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#to_yaml" do
|
41
|
+
it "converts a RevisionHistory object to YAML" do
|
42
|
+
history = Revix::RevisionHistory.from_yaml(yaml_content)
|
43
|
+
yaml = history.to_yaml
|
44
|
+
expect(yaml).to be_a(String)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#to_xml" do
|
49
|
+
it "converts a RevisionHistory object to XML" do
|
50
|
+
history = Revix::RevisionHistory.from_yaml(yaml_content)
|
51
|
+
xml = history.to_xml
|
52
|
+
expect(xml).to be_a(String)
|
53
|
+
expect(xml).to include("<revision-history>")
|
54
|
+
expect(xml).to include("<revision>")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "performs round-trip conversion from XML to object and back" do
|
58
|
+
# Start with the static XML sample
|
59
|
+
original_xml = xml_content
|
60
|
+
|
61
|
+
# Parse to object
|
62
|
+
history = Revix::RevisionHistory.from_xml(original_xml)
|
63
|
+
|
64
|
+
# Convert back to XML
|
65
|
+
generated_xml = history.to_xml
|
66
|
+
|
67
|
+
# Canonicalize both XMLs and compare using xml-c14n
|
68
|
+
c14n_original = Xml::C14n.format(original_xml)
|
69
|
+
c14n_generated = Xml::C14n.format(generated_xml)
|
70
|
+
|
71
|
+
expect(c14n_generated).to eq(c14n_original)
|
72
|
+
expect(c14n_generated).to be_analogous_with(c14n_original)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe Revix::Revision do
|
6
|
+
let(:revision_data) do
|
7
|
+
date = [
|
8
|
+
Revix::DateInfo.new(type: "published", value: "2012-04")
|
9
|
+
]
|
10
|
+
name = Revix::Name.new(abbreviation: "JMS", completename: "J. Michael Straczynski")
|
11
|
+
person = Revix::Person.new(name: name)
|
12
|
+
contributor = Revix::Contributor.new(person: person)
|
13
|
+
amendment = Revix::Amendment.new(description: "Approved edition of S-102")
|
14
|
+
|
15
|
+
Revix::Revision.new(
|
16
|
+
date: date,
|
17
|
+
edition: "1.0.0",
|
18
|
+
contributor: [contributor],
|
19
|
+
amend: [amendment]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe ".new" do
|
24
|
+
it "creates a new Revision object" do
|
25
|
+
revision = revision_data
|
26
|
+
expect(revision).to be_a(Revix::Revision)
|
27
|
+
expect(revision.edition).to eq("1.0.0")
|
28
|
+
expect(revision.date.size).to eq(1)
|
29
|
+
expect(revision.date.first.type).to eq("published")
|
30
|
+
expect(revision.date.first.value).to eq("2012-04")
|
31
|
+
expect(revision.contributor.size).to eq(1)
|
32
|
+
expect(revision.contributor.first.person).not_to be_nil
|
33
|
+
expect(revision.contributor.first.person.name.abbreviation).to eq("JMS")
|
34
|
+
expect(revision.contributor.first.person.name.completename).to eq("J. Michael Straczynski")
|
35
|
+
expect(revision.amend.size).to eq(1)
|
36
|
+
expect(revision.amend.first.description).to eq("Approved edition of S-102")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#to_xml" do
|
41
|
+
it "converts a Revision object to XML and back" do
|
42
|
+
original = revision_data
|
43
|
+
xml1 = original.to_xml
|
44
|
+
|
45
|
+
# Parse back to object and generate XML again
|
46
|
+
parsed = Revix::Revision.from_xml(xml1)
|
47
|
+
xml2 = parsed.to_xml
|
48
|
+
|
49
|
+
# Canonicalize both XMLs and compare using xml-c14n
|
50
|
+
c14n1 = Xml::C14n.format(xml1)
|
51
|
+
c14n2 = Xml::C14n.format(xml2)
|
52
|
+
|
53
|
+
expect(c14n2).to eq(c14n1)
|
54
|
+
expect(c14n2).to be_analogous_with(c14n1)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/revix_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "revix"
|
5
|
+
require "xml/c14n"
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
# Enable flags like --only-failures and --next-failure
|
9
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
10
|
+
|
11
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
12
|
+
config.disable_monkey_patching!
|
13
|
+
|
14
|
+
config.expect_with :rspec do |c|
|
15
|
+
c.syntax = :expect
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: revix
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ribose
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-02-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: lutaml-model
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: nokogiri
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: xml-c14n
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- open.source@ribose.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE
|
65
|
+
- README.adoc
|
66
|
+
- Rakefile
|
67
|
+
- lib/revix.rb
|
68
|
+
- lib/revix/amendment.rb
|
69
|
+
- lib/revix/classification.rb
|
70
|
+
- lib/revix/contributor.rb
|
71
|
+
- lib/revix/date_info.rb
|
72
|
+
- lib/revix/location.rb
|
73
|
+
- lib/revix/name.rb
|
74
|
+
- lib/revix/organization.rb
|
75
|
+
- lib/revix/person.rb
|
76
|
+
- lib/revix/revision.rb
|
77
|
+
- lib/revix/revision_history.rb
|
78
|
+
- lib/revix/version.rb
|
79
|
+
- revix.gemspec
|
80
|
+
- spec/fixtures/iho_sample.yaml
|
81
|
+
- spec/fixtures/ogc_sample.yaml
|
82
|
+
- spec/fixtures/sample.xml
|
83
|
+
- spec/fixtures/sample.yaml
|
84
|
+
- spec/models/amendment_spec.rb
|
85
|
+
- spec/models/revision_history_spec.rb
|
86
|
+
- spec/models/revision_spec.rb
|
87
|
+
- spec/revix_spec.rb
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
homepage: https://github.com/metanorma/revix
|
90
|
+
licenses:
|
91
|
+
- BSD-2-Clause
|
92
|
+
metadata:
|
93
|
+
homepage_uri: https://github.com/metanorma/revix
|
94
|
+
source_code_uri: https://github.com/metanorma/revix
|
95
|
+
bug_tracker_uri: https://github.com/metanorma/revix/issues
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 2.6.0
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubygems_version: 3.5.22
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Library to work with Metanorma document revision history.
|
115
|
+
test_files: []
|