diff --git a/.rubocop.yml b/.rubocop.yml
index bb8409c..666c599 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,34 +1,14 @@
-inherit_from: .rubocop_todo.yml
+inherit_from:
+ - https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
+ - .rubocop_todo.yml
+
+plugins:
+- rubocop-performance
+- rubocop-rake
+- rubocop-rspec
AllCops:
+ TargetRubyVersion: 3.0
NewCops: enable
- SuggestExtensions: false
- TargetRubyVersion: 2.7
-
-Gemspec/DevelopmentDependencies:
- Enabled: false
-
-Gemspec/RequireMFA:
- Enabled: false
-
-Metrics/BlockLength:
- AllowedMethods:
- - describe
-
-Style/Documentation:
- Enabled: false
-
-Style/StringLiterals:
- EnforcedStyle: double_quotes
-
-Style/StringLiteralsInInterpolation:
- EnforcedStyle: double_quotes
-
-Style/TrailingCommaInArguments:
- EnforcedStyleForMultiline: consistent_comma
-
-Style/TrailingCommaInArrayLiteral:
- EnforcedStyleForMultiline: consistent_comma
-
-Style/TrailingCommaInHashLiteral:
- EnforcedStyleForMultiline: consistent_comma
+ Exclude:
+ - 'vendor/**/*'
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 321f8d6..5e4bf1d 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,66 +1,321 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
-# on 2025-01-11 09:46:54 UTC using RuboCop version 1.70.0.
+# on 2025-12-01 12:15:10 UTC using RuboCop version 1.81.7.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
-# Offense count: 4
+# Offense count: 2
# This cop supports safe autocorrection (--autocorrect).
-# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include.
-# Include: **/*.gemfile, **/Gemfile, **/gems.rb
+# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation.
Bundler/OrderedGems:
Exclude:
- 'Gemfile'
# Offense count: 1
-# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
-Lint/DuplicateBranch:
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Severity.
+Gemspec/RequireMFA:
+ Exclude:
+ - 'genericode.gemspec'
+
+# Offense count: 1
+# Configuration parameters: Severity.
+Gemspec/RequiredRubyVersion:
+ Exclude:
+ - 'genericode.gemspec'
+
+# Offense count: 36
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: with_first_argument, with_fixed_indentation
+Layout/ArgumentAlignment:
+ Exclude:
+ - 'lib/genericode/cli/code_lister.rb'
+ - 'lib/genericode/cli/commands.rb'
+ - 'lib/genericode/cli/converter.rb'
+ - 'lib/genericode/cli/validator.rb'
+ - 'lib/genericode/identification.rb'
+ - 'spec/genericode/cli/code_lookup_spec.rb'
+ - 'spec/genericode/cli/commands_spec.rb'
+ - 'spec/genericode/cli/converter_spec.rb'
+ - 'spec/genericode/cli/validator_spec.rb'
+ - 'spec/genericode/code_list_spec.rb'
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: with_first_element, with_fixed_indentation
+Layout/ArrayAlignment:
+ Exclude:
+ - 'genericode.gemspec'
+ - 'lib/genericode/cli/converter.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: IndentationWidth.
+Layout/AssignmentIndentation:
+ Exclude:
+ - 'lib/genericode/agency.rb'
+ - 'lib/genericode/identification.rb'
+
+# Offense count: 18
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyleAlignWith.
+# SupportedStylesAlignWith: either, start_of_block, start_of_line
+Layout/BlockAlignment:
Exclude:
- 'lib/genericode/code_list.rb'
+ - 'lib/genericode/key.rb'
+ - 'spec/genericode/cli/commands_spec.rb'
+ - 'spec/genericode/cli/validator_spec.rb'
+ - 'spec/genericode/code_list_spec.rb'
+ - 'spec/genericode_spec.rb'
+
+# Offense count: 18
+# This cop supports safe autocorrection (--autocorrect).
+Layout/BlockEndNewline:
+ Exclude:
+ - 'lib/genericode/code_list.rb'
+ - 'lib/genericode/key.rb'
+ - 'spec/genericode/cli/commands_spec.rb'
+ - 'spec/genericode/cli/validator_spec.rb'
+ - 'spec/genericode/code_list_spec.rb'
+ - 'spec/genericode_spec.rb'
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+Layout/ClosingParenthesisIndentation:
+ Exclude:
+ - 'spec/genericode/cli/commands_spec.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
-# Configuration parameters: AutoCorrect, CheckForMethodsWithNoSideEffects.
-Lint/Void:
+Layout/EmptyLineAfterGuardClause:
+ Exclude:
+ - 'lib/genericode/cli/converter.rb'
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
+Layout/FirstArgumentIndentation:
+ Exclude:
+ - 'spec/genericode/cli/commands_spec.rb'
+
+# Offense count: 42
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
+# SupportedHashRocketStyles: key, separator, table
+# SupportedColonStyles: key, separator, table
+# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
+Layout/HashAlignment:
Exclude:
+ - 'genericode.gemspec'
+ - 'lib/genericode/agency.rb'
+ - 'lib/genericode/cli/commands.rb'
- 'lib/genericode/code_list.rb'
+ - 'lib/genericode/code_list_ref.rb'
+ - 'lib/genericode/code_list_set.rb'
+ - 'lib/genericode/code_list_set_ref.rb'
+ - 'lib/genericode/column.rb'
+ - 'lib/genericode/datatype_facet.rb'
+ - 'lib/genericode/identification.rb'
+ - 'lib/genericode/key.rb'
+ - 'spec/genericode/code_list_spec.rb'
-# Offense count: 8
-# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
-Metrics/AbcSize:
- Max: 182
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: normal, indented_internal_methods
+Layout/IndentationConsistency:
+ Exclude:
+ - 'genericode.gemspec'
-# Offense count: 2
-# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
-# AllowedMethods: refine
-Metrics/BlockLength:
- Max: 34
+# Offense count: 36
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Width, AllowedPatterns.
+Layout/IndentationWidth:
+ Exclude:
+ - 'lib/genericode/code_list.rb'
+ - 'lib/genericode/key.rb'
+ - 'spec/genericode/cli/commands_spec.rb'
+ - 'spec/genericode/cli/validator_spec.rb'
+ - 'spec/genericode/code_list_spec.rb'
+ - 'spec/genericode_spec.rb'
+
+# Offense count: 153
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
+# URISchemes: http, https
+Layout/LineLength:
+ Enabled: false
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: symmetrical, new_line, same_line
+Layout/MultilineMethodCallBraceLayout:
+ Exclude:
+ - 'spec/genericode/cli/commands_spec.rb'
+
+# Offense count: 60
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowInHeredoc.
+Layout/TrailingWhitespace:
+ Enabled: false
# Offense count: 1
-# Configuration parameters: CountComments, CountAsOne.
-Metrics/ClassLength:
- Max: 216
+# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
+Lint/DuplicateBranch:
+ Exclude:
+ - 'lib/genericode/code_list.rb'
+
+# Offense count: 11
+# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
+Metrics/AbcSize:
+ Exclude:
+ - 'lib/genericode/cli/code_lister.rb'
+ - 'lib/genericode/cli/commands.rb'
+ - 'lib/genericode/cli/validator.rb'
+ - 'lib/genericode/code_list.rb'
+ - 'lib/genericode/code_list_set.rb'
+ - 'spec/genericode_spec.rb'
-# Offense count: 5
-# Configuration parameters: AllowedMethods, AllowedPatterns.
+# Offense count: 7
+# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
Metrics/CyclomaticComplexity:
- Max: 92
+ Exclude:
+ - 'lib/genericode/cli/code_lister.rb'
+ - 'lib/genericode/cli/validator.rb'
+ - 'lib/genericode/code_list.rb'
+ - 'lib/genericode/code_list_set.rb'
# Offense count: 10
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
Metrics/MethodLength:
- Max: 86
+ Max: 112
-# Offense count: 3
-# Configuration parameters: AllowedMethods, AllowedPatterns.
+# Offense count: 8
+# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
Metrics/PerceivedComplexity:
- Max: 92
+ Exclude:
+ - 'lib/genericode/cli/code_lister.rb'
+ - 'lib/genericode/cli/commands.rb'
+ - 'lib/genericode/cli/validator.rb'
+ - 'lib/genericode/code_list.rb'
+ - 'lib/genericode/code_list_set.rb'
+
+# Offense count: 2
+# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
+# AllowedMethods: call
+# WaywardPredicates: nonzero?
+Naming/PredicateMethod:
+ Exclude:
+ - 'lib/genericode/cli/converter.rb'
+ - 'lib/genericode/cli/validator.rb'
+
+# Offense count: 2
+RSpec/AnyInstance:
+ Exclude:
+ - 'spec/genericode/cli/converter_spec.rb'
+
+# Offense count: 17
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants.
+# SupportedStyles: described_class, explicit
+RSpec/DescribedClass:
+ Exclude:
+ - 'spec/genericode/cli/code_lister_spec.rb'
+ - 'spec/genericode/cli/code_lookup_spec.rb'
+ - 'spec/genericode/cli/converter_spec.rb'
+ - 'spec/genericode/cli/validator_spec.rb'
+
+# Offense count: 17
+# Configuration parameters: CountAsOne.
+RSpec/ExampleLength:
+ Max: 23
+
+# Offense count: 2
+RSpec/LeakyLocalVariable:
+ Exclude:
+ - 'spec/genericode/code_list_spec.rb'
+
+# Offense count: 1
+RSpec/MultipleExpectations:
+ Max: 3
# Offense count: 2
+# Configuration parameters: AllowedPatterns.
+# AllowedPatterns: ^expect_, ^assert_
+RSpec/NoExpectationExample:
+ Exclude:
+ - 'spec/genericode_spec.rb'
+
+# Offense count: 6
+# This cop supports unsafe autocorrection (--autocorrect-all).
+RSpec/ReceiveMessages:
+ Exclude:
+ - 'spec/genericode/cli/validator_spec.rb'
+
+# Offense count: 30
# This cop supports safe autocorrection (--autocorrect).
-# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
-# URISchemes: http, https
-Layout/LineLength:
- Max: 121
+# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
+# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
+# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
+# FunctionalMethods: let, let!, subject, watch
+# AllowedMethods: lambda, proc, it
+Style/BlockDelimiters:
+ Exclude:
+ - 'lib/genericode/code_list.rb'
+ - 'lib/genericode/key.rb'
+ - 'spec/genericode/cli/commands_spec.rb'
+ - 'spec/genericode/cli/validator_spec.rb'
+ - 'spec/genericode/code_list_spec.rb'
+ - 'spec/genericode_spec.rb'
+
+# Offense count: 7
+# This cop supports safe autocorrection (--autocorrect).
+Style/MultilineIfModifier:
+ Exclude:
+ - 'lib/genericode/cli/code_lister.rb'
+ - 'lib/genericode/cli/converter.rb'
+ - 'lib/genericode/cli/validator.rb'
+ - 'lib/genericode/code_list_set.rb'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
+# SupportedStyles: single_quotes, double_quotes
+Style/StringLiterals:
+ Exclude:
+ - 'genericode.gemspec'
+
+# Offense count: 8
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyleForMultiline.
+# SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
+Style/TrailingCommaInArguments:
+ Exclude:
+ - 'spec/genericode/cli/code_lister_spec.rb'
+ - 'spec/genericode/cli/code_lookup_spec.rb'
+ - 'spec/genericode/cli/converter_spec.rb'
+ - 'spec/genericode/code_list_spec.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyleForMultiline.
+# SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
+Style/TrailingCommaInArrayLiteral:
+ Exclude:
+ - 'lib/genericode/code_list.rb'
+
+# Offense count: 11
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyleForMultiline.
+# SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
+Style/TrailingCommaInHashLiteral:
+ Exclude:
+ - 'lib/genericode/code_list.rb'
+ - 'lib/genericode/identification.rb'
diff --git a/Gemfile b/Gemfile
index 93dfa2a..62b56d6 100644
--- a/Gemfile
+++ b/Gemfile
@@ -5,9 +5,13 @@ source "https://rubygems.org"
# Specify your gem's dependencies in genericode.gemspec
gemspec
+gem "canon"
+gem "lutaml-model", github: "lutaml/lutaml-model", branch: "main"
gem "nokogiri"
-gem "rake", "~> 13.0"
-gem "rspec", "~> 3.0"
+gem "openssl"
+gem "rake"
+gem "rspec"
gem "rubocop"
gem "rubocop-performance"
-gem "xml-c14n"
+gem "rubocop-rake"
+gem "rubocop-rspec"
diff --git a/genericode.gemspec b/genericode.gemspec
index db15151..74af68c 100644
--- a/genericode.gemspec
+++ b/genericode.gemspec
@@ -16,12 +16,15 @@ Gem::Specification.new do |spec|
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = spec.homepage
spec.metadata["changelog_uri"] = "https://github.com/lutaml/genericode/releases"
+ spec.metadata["rubygems_mfa_required"] = "true"
gemspec = File.basename(__FILE__)
- spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
+ spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__,
+ err: IO::NULL) do |ls|
ls.readlines("\x0", chomp: true).reject do |f|
(f == gemspec) ||
- f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor
+ Gemfile])
end
end
spec.bindir = "exe"
@@ -29,7 +32,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ["lib"]
spec.add_dependency "csv"
- spec.add_dependency "lutaml-model", "~> 0.7"
- spec.add_dependency "tabulo"
+ spec.add_dependency "lutaml-model", "~>0.8.0"
+ spec.add_dependency "table_tennis", "~>0.0.7"
spec.add_dependency "thor"
end
diff --git a/lib/genericode.rb b/lib/genericode.rb
index ec96a81..ee93eb2 100644
--- a/lib/genericode.rb
+++ b/lib/genericode.rb
@@ -3,11 +3,12 @@
require "lutaml/model"
Lutaml::Model::Config.configure do |config|
- require "lutaml/model/xml_adapter/nokogiri_adapter"
- config.xml_adapter = Lutaml::Model::XmlAdapter::NokogiriAdapter
+ require "lutaml/model/xml/nokogiri_adapter"
+ config.xml_adapter = Lutaml::Model::Xml::NokogiriAdapter
end
require_relative "genericode/version"
+require_relative "genericode/namespace"
require_relative "genericode/code_list"
module Genericode
diff --git a/lib/genericode/agency.rb b/lib/genericode/agency.rb
index f051d9c..c7aa3af 100644
--- a/lib/genericode/agency.rb
+++ b/lib/genericode/agency.rb
@@ -17,9 +17,12 @@ class Agency < Lutaml::Model::Serializable
attribute :identifier, GeneralIdentifier, collection: true
json do
- map "ShortName", to: :short_name, with: { from: :short_name_from_json, to: :short_name_to_json }
- map "LongName", to: :long_name, with: { from: :long_name_from_json, to: :long_name_to_json }
- map "Identifier", to: :identifier, with: { from: :identifier_from_json, to: :identifier_to_json }
+ map "ShortName", to: :short_name,
+ with: { from: :short_name_from_json, to: :short_name_to_json }
+ map "LongName", to: :long_name,
+ with: { from: :long_name_from_json, to: :long_name_to_json }
+ map "Identifier", to: :identifier,
+ with: { from: :identifier_from_json, to: :identifier_to_json }
end
def long_name_from_json(model, value)
@@ -35,16 +38,17 @@ def identifier_from_json(model, value)
end
def identifier_to_json(model, doc)
- doc["Identifier"] = GeneralIdentifier.as_json(Utils.one_or_all(model.identifier))
+ doc["Identifier"] =
+ GeneralIdentifier.as_json(Utils.one_or_all(model.identifier))
end
xml do
- root "Agency"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "Agency"
+ namespace Namespace
- map_element "ShortName", to: :short_name, prefix: nil, namespace: nil
- map_element "LongName", to: :long_name, prefix: nil, namespace: nil
- map_element "Identifier", to: :identifier, prefix: nil, namespace: nil
+ map_element "ShortName", to: :short_name
+ map_element "LongName", to: :long_name
+ map_element "Identifier", to: :identifier
end
end
end
diff --git a/lib/genericode/annotation.rb b/lib/genericode/annotation.rb
index 754226d..21756b5 100644
--- a/lib/genericode/annotation.rb
+++ b/lib/genericode/annotation.rb
@@ -22,11 +22,11 @@ def self.of_json(hash, **)
end
xml do
- root "Annotation"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "Annotation"
+ namespace Namespace
- map_element "Description", to: :description, prefix: nil, namespace: nil
- map_element "AppInfo", to: :app_info, prefix: nil, namespace: nil, value_map: { to: { nil: :empty } }
+ map_element "Description", to: :description
+ map_element "AppInfo", to: :app_info, value_map: { to: { nil: :empty } }
end
end
end
diff --git a/lib/genericode/annotation.rb.orig b/lib/genericode/annotation.rb.orig
new file mode 100644
index 0000000..eebb4b4
--- /dev/null
+++ b/lib/genericode/annotation.rb.orig
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require "lutaml/model"
+
+require_relative "any_other_content"
+require_relative "any_other_language_content"
+
+module Genericode
+ class Annotation < Lutaml::Model::Serializable
+ attribute :description, AnyOtherLanguageContent, collection: true
+ attribute :app_info, AnyOtherContent
+
+ json do
+ map "Description", to: :description
+ map "AppInfo", to: :app_info, render_nil: true
+ end
+
+ def self.of_json(hash, **)
+ hash = { "AppInfo" => hash } if hash.any?
+
+ super
+ end
+
+ xml do
+ element "Annotation"
+ namespace Namespace
+
+<<<<<<< Updated upstream
+ map_element "Description", to: :description, prefix: nil, namespace: nil
+ map_element "AppInfo", to: :app_info, prefix: nil, namespace: nil, value_map: { to: { nil: :empty } }
+=======
+ map_element "Description", to: :description
+ map_element "AppInfo", to: :app_info, render_nil: true
+>>>>>>> Stashed changes
+ end
+ end
+end
diff --git a/lib/genericode/any_other_content.rb b/lib/genericode/any_other_content.rb
index 2e1630d..bfc7e27 100644
--- a/lib/genericode/any_other_content.rb
+++ b/lib/genericode/any_other_content.rb
@@ -5,8 +5,8 @@
module Genericode
class AnyOtherContent < Lutaml::Model::Serializable
xml do
- root "AnyOtherContent"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "AnyOtherContent"
+ namespace Namespace
end
end
end
diff --git a/lib/genericode/any_other_language_content.rb b/lib/genericode/any_other_language_content.rb
index 5971f66..e20ed3e 100644
--- a/lib/genericode/any_other_language_content.rb
+++ b/lib/genericode/any_other_language_content.rb
@@ -11,8 +11,8 @@ class AnyOtherLanguageContent < Lutaml::Model::Serializable
end
xml do
- root "AnyOtherLanguageContent"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "AnyOtherLanguageContent"
+ namespace Namespace
map_attribute "lang", to: :lang, prefix: "xml", namespace: "http://www.w3.org/XML/1998/namespace"
end
diff --git a/lib/genericode/canonical_uri.rb b/lib/genericode/canonical_uri.rb
index 8e393fd..001eec9 100644
--- a/lib/genericode/canonical_uri.rb
+++ b/lib/genericode/canonical_uri.rb
@@ -9,7 +9,7 @@ class CanonicalUri < Lutaml::Model::Serializable
attribute :content, :string
xml do
- root "CanonicalUri"
+ element "CanonicalUri"
map_content to: :content
end
diff --git a/lib/genericode/cli/code_lister.rb b/lib/genericode/cli/code_lister.rb
index 5769731..7c79a55 100644
--- a/lib/genericode/cli/code_lister.rb
+++ b/lib/genericode/cli/code_lister.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require_relative "../code_list"
-require "tabulo"
+require "table_tennis"
require "csv"
module Genericode
@@ -13,10 +13,16 @@ def list_codes(file_path, format: :tsv)
# Validate data types
code_list.validate_verbose.each do |error|
- raise Error, "#{error[:code]}: #{error[:message]}" if error[:code] == "INVALID_DATA_TYPE"
+ if error[:code] == "INVALID_DATA_TYPE"
+ raise Error,
+ "#{error[:code]}: #{error[:message]}"
+ end
# Ensure valid ColumnRefs
- raise Error, "#{error[:code]}: #{error[:message]}" if error[:code] == "INVALID_COLUMN_REF"
+ if error[:code] == "INVALID_COLUMN_REF"
+ raise Error,
+ "#{error[:code]}: #{error[:message]}"
+ end
end
case format
@@ -50,16 +56,15 @@ def list_table(code_list)
columns = code_list.column_set.column
rows = code_list.simple_code_list.row
- table = Tabulo::Table.new(rows) do |t|
- columns.each do |column|
- t.add_column(column.short_name.content) do |row|
- value = row.value.find { |v| v.column_ref == column.id }
- value&.simple_value&.content || ""
- end
+ headers = columns.map { |col| col.short_name.content }
+ data = rows.map do |row|
+ columns.map do |col|
+ value = row.value.find { |v| v.column_ref == col.id }
+ value&.simple_value&.content || ""
end
end
- table.to_s
+ TableTennis.render([headers] + data)
end
end
end
diff --git a/lib/genericode/cli/commands.rb b/lib/genericode/cli/commands.rb
index 269b31b..ff266dd 100644
--- a/lib/genericode/cli/commands.rb
+++ b/lib/genericode/cli/commands.rb
@@ -9,7 +9,8 @@
module Genericode
module Cli
class Commands < Thor
- desc "convert INPUT OUTPUT", "Convert between Genericode XML and JSON formats"
+ desc "convert INPUT OUTPUT",
+ "Convert between Genericode XML and JSON formats"
def convert(input, output)
puts "Conversion successful." if Converter.convert(input, output)
@@ -41,8 +42,10 @@ def validate(file)
puts "Validation failed: #{e.message}"
end
- desc "list_codes FILE", "List all codes and their associated data in a Genericode file"
- option :format, type: :string, default: "tsv", enum: %w[tsv table], desc: "Output format (tsv or table)"
+ desc "list_codes FILE",
+ "List all codes and their associated data in a Genericode file"
+ option :format, type: :string, default: "tsv", enum: %w[tsv table],
+ desc: "Output format (tsv or table)"
option :output, type: :string, desc: "Output file path (default: stdout)"
def list_codes(file)
diff --git a/lib/genericode/cli/converter.rb b/lib/genericode/cli/converter.rb
index 33d315e..6f0c7f3 100644
--- a/lib/genericode/cli/converter.rb
+++ b/lib/genericode/cli/converter.rb
@@ -7,9 +7,15 @@ def self.convert(input_path, output_path)
input_format = File.extname(input_path)
output_format = File.extname(output_path)
- raise Error, "Invalid input format" unless [".gc", ".gcj"].include?(input_format)
- raise Error, "Invalid output format" unless [".gc", ".gcj"].include?(output_format)
- raise Error, "Input and output formats are the same" if input_format == output_format
+ raise Error, "Invalid input format" unless [".gc",
+ ".gcj"].include?(input_format)
+ raise Error, "Invalid output format" unless [".gc",
+ ".gcj"].include?(output_format)
+
+ if input_format == output_format
+ raise Error,
+ "Input and output formats are the same"
+ end
# begin
code_list = CodeList.from_file(input_path)
diff --git a/lib/genericode/cli/validator.rb b/lib/genericode/cli/validator.rb
index fe731d2..6d78fdc 100644
--- a/lib/genericode/cli/validator.rb
+++ b/lib/genericode/cli/validator.rb
@@ -5,12 +5,19 @@ module Cli
class Validator
def self.validate(file_path)
raise Error, "File does not exist" unless File.exist?(file_path)
- raise Error, "Invalid file format" unless file_path.end_with?(".gc", ".gcj")
+ raise Error, "Invalid file format" unless file_path.end_with?(".gc",
+ ".gcj")
code_list = CodeList.from_file(file_path)
- raise Error, "No columns defined" if code_list.column_set.nil? || code_list.column_set.column.empty?
- raise Error, "No rows defined" if code_list.simple_code_list.nil? || code_list.simple_code_list.row.empty?
+ if code_list.column_set.nil? || code_list.column_set.column.empty?
+ raise Error,
+ "No columns defined"
+ end
+ if code_list.simple_code_list.nil? || code_list.simple_code_list.row.empty?
+ raise Error,
+ "No rows defined"
+ end
raise Error, "Invalid Genericode structure" unless code_list.valid?
diff --git a/lib/genericode/code_list.rb b/lib/genericode/code_list.rb
index da22c2f..3e8ec7b 100644
--- a/lib/genericode/code_list.rb
+++ b/lib/genericode/code_list.rb
@@ -31,10 +31,13 @@ def self.from_file(file_path)
json do
map "Annotation", to: :annotation
map "Identification", to: :identification
- map "Columns", to: :column_set, with: { from: :column_set_from_json, to: :column_set_to_json }
+ map "Columns", to: :column_set,
+ with: { from: :column_set_from_json, to: :column_set_to_json }
map "ColumnSetRef", to: :column_set_ref
- map "Keys", to: :key, delegate: :column_set, with: { from: :key_from_json, to: :key_to_json }
- map "Codes", to: :simple_code_list, with: { from: :simple_code_list_from_json, to: :simple_code_list_to_json }
+ map "Keys", to: :key, delegate: :column_set,
+ with: { from: :key_from_json, to: :key_to_json }
+ map "Codes", to: :simple_code_list,
+ with: { from: :simple_code_list_from_json, to: :simple_code_list_to_json }
end
def column_set_from_json(model, value)
@@ -72,14 +75,14 @@ def simple_code_list_to_json(model, doc)
end
xml do
- root "CodeList"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
-
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "Identification", to: :identification, prefix: nil, namespace: nil
- map_element "ColumnSet", to: :column_set, prefix: nil, namespace: nil
- map_element "ColumnSetRef", to: :column_set_ref, prefix: nil, namespace: nil
- map_element "SimpleCodeList", to: :simple_code_list, prefix: nil, namespace: nil
+ element "CodeList"
+ namespace Namespace
+
+ map_element "Annotation", to: :annotation
+ map_element "Identification", to: :identification
+ map_element "ColumnSet", to: :column_set
+ map_element "ColumnSetRef", to: :column_set_ref
+ map_element "SimpleCodeList", to: :simple_code_list
end
def lookup(path)
@@ -89,10 +92,14 @@ def lookup(path)
result = simple_code_list.row.find do |row|
conditions.all? do |col, value|
- column = column_set.column.find { |c| c.short_name.content.downcase == col.downcase }
+ column = column_set.column.find do |c|
+ c.short_name.content.downcase == col.downcase
+ end
raise Error, "Column not found: #{col}" unless column
- row_value = row.value.find { |v| v.column_ref == column.id }&.simple_value&.content
+ row_value = row.value.find do |v|
+ v.column_ref == column.id
+ end&.simple_value&.content
row_value == value
end
end
@@ -100,15 +107,19 @@ def lookup(path)
raise Error, "No matching row found for path: #{path}" unless result
if target_column
- column = column_set.column.find { |c| c.short_name.content.downcase == target_column.downcase }
+ column = column_set.column.find do |c|
+ c.short_name.content.downcase == target_column.downcase
+ end
raise Error, "Target column not found: #{target_column}" unless column
- result.value.find { |v| v.column_ref == column.id }&.simple_value&.content
+ result.value.find do |v|
+ v.column_ref == column.id
+ end&.simple_value&.content
else
result.value.to_h do |v|
[column_set.column.find do |c|
c.id == v.column_ref
- end.short_name.content, v.simple_value.content,]
+ end.short_name.content, v.simple_value.content]
end
end
end
@@ -123,19 +134,20 @@ def validate_verbose
# Rule 1: ColumnSet presence
if column_set.nil? || column_set.column.empty?
errors << { code: "MISSING_COLUMN_SET",
- message: "ColumnSet is missing or empty", }
+ message: "ColumnSet is missing or empty" }
end
# Rule 2: SimpleCodeList presence
if simple_code_list.nil? || simple_code_list.row.empty?
errors << { code: "MISSING_SIMPLE_CODE_LIST",
- message: "SimpleCodeList is missing or empty", }
+ message: "SimpleCodeList is missing or empty" }
end
# Rule 3: Unique column IDs
column_ids = column_set&.column&.map(&:id) || []
if column_ids.uniq.length != column_ids.length
- errors << { code: "DUPLICATE_COLUMN_IDS", message: "Duplicate column IDs found" }
+ errors << { code: "DUPLICATE_COLUMN_IDS",
+ message: "Duplicate column IDs found" }
end
# Rule 4: Verify ColumnRef values
@@ -143,7 +155,7 @@ def validate_verbose
row.value.each do |value|
unless column_ids.include?(value.column_ref)
errors << { code: "INVALID_COLUMN_REF",
- message: "Invalid ColumnRef '#{value.column_ref}' in row #{index + 1}", }
+ message: "Invalid ColumnRef '#{value.column_ref}' in row #{index + 1}" }
end
end
end
@@ -155,17 +167,22 @@ def validate_verbose
end || []).compact
if column_values.uniq.length != column_values.length
- errors << { code: "DUPLICATE_VALUES", message: "Duplicate values found in column '#{col.id}'" }
+ errors << { code: "DUPLICATE_VALUES",
+ message: "Duplicate values found in column '#{col.id}'" }
end
end
# Rule 6: Required column values
- required_columns = column_set&.column&.select { |col| col.use == "required" } || []
+ required_columns = column_set&.column&.select do |col|
+ col.use == "required"
+ end || []
simple_code_list&.row&.each_with_index do |row, index|
required_columns.each do |col|
- unless row.value.any? { |v| v.column_ref == col.id && v.simple_value&.content }
+ unless row.value.any? do |v|
+ v.column_ref == col.id && v.simple_value&.content
+ end
errors << { code: "MISSING_REQUIRED_VALUE",
- message: "Missing value for required column '#{col.short_name&.content}' in row #{index + 1}", }
+ message: "Missing value for required column '#{col.short_name&.content}' in row #{index + 1}" }
end
end
end
@@ -174,43 +191,47 @@ def validate_verbose
column_set&.column&.each do |col|
data_type = col.data&.type
simple_code_list&.row&.each_with_index do |row, index|
- value = row.value.find { |v| v.column_ref == col.id }&.simple_value&.content
+ value = row.value.find do |v|
+ v.column_ref == col.id
+ end&.simple_value&.content
unless value_matches_type?(value, data_type)
errors << { code: "INVALID_DATA_TYPE",
- message: "Invalid data type for column '#{col.short_name&.content}' in row #{index + 1}", }
+ message: "Invalid data type for column '#{col.short_name&.content}' in row #{index + 1}" }
end
end
end
# Rule 8: Valid canonical URIs
if identification&.canonical_uri && !valid_uri?(identification.canonical_uri)
- errors << { code: "INVALID_CANONICAL_URI", message: "Invalid canonical URI" }
+ errors << { code: "INVALID_CANONICAL_URI",
+ message: "Invalid canonical URI" }
end
# Rule 19: Datatype ID validation
column_set&.column&.each do |col|
if col.data&.type && !valid_datatype_id?(col.data.type)
errors << { code: "INVALID_DATATYPE_ID",
- message: "Invalid datatype ID for column '#{col.short_name&.content}'", }
+ message: "Invalid datatype ID for column '#{col.short_name&.content}'" }
end
# Rule 20 and 22: Complex data validation
if col.data&.type == "*" && col.data&.datatype_library != "*"
errors << { code: "INVALID_COMPLEX_DATA",
- message: "Invalid complex data configuration for column '#{col.short_name&.content}'", }
+ message: "Invalid complex data configuration for column '#{col.short_name&.content}'" }
end
# Rule 23: Language attribute validation
if col.data&.lang && col.data_restrictions&.lang
errors << { code: "DUPLICATE_LANG_ATTRIBUTE",
- message: "Duplicate lang attribute for column '#{col.short_name&.content}'", }
+ message: "Duplicate lang attribute for column '#{col.short_name&.content}'" }
end
end
# Rule 38: Implicit column reference
simple_code_list&.row&.each_with_index do |row, index|
unless row.value.all?(&:column_ref)
- errors << { code: "MISSING_COLUMN_REF", message: "Missing explicit column reference in row #{index + 1}" }
+ errors << { code: "MISSING_COLUMN_REF",
+ message: "Missing explicit column reference in row #{index + 1}" }
end
end
@@ -218,7 +239,7 @@ def validate_verbose
column_set&.column&.each do |col|
if col.short_name&.content&.match?(/\s/)
errors << { code: "INVALID_SHORT_NAME",
- message: "ShortName '#{col.short_name&.content}' contains whitespace", }
+ message: "ShortName '#{col.short_name&.content}' contains whitespace" }
end
end
@@ -227,9 +248,11 @@ def validate_verbose
row.value.each do |value|
next unless value.complex_value
- unless valid_complex_value?(value.complex_value, column_set&.column&.find { |c| c.id == value.column_ref })
+ unless valid_complex_value?(value.complex_value, column_set&.column&.find do |c|
+ c.id == value.column_ref
+ end)
errors << { code: "INVALID_COMPLEX_VALUE",
- message: "Invalid ComplexValue in row #{index + 1}, column '#{value.column_ref}'", }
+ message: "Invalid ComplexValue in row #{index + 1}, column '#{value.column_ref}'" }
end
end
end
diff --git a/lib/genericode/code_list_ref.rb b/lib/genericode/code_list_ref.rb
index 631e122..d5fd6c2 100644
--- a/lib/genericode/code_list_ref.rb
+++ b/lib/genericode/code_list_ref.rb
@@ -16,19 +16,20 @@ class CodeListRef < Lutaml::Model::Serializable
json do
map "Annotation", to: :annotation
- map "CanonicalUri", to: :canonical_uri, with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
+ map "CanonicalUri", to: :canonical_uri,
+ with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
map "CanonicalVersionUri", to: :canonical_version_uri
map "LocationUri", to: :location_uri
end
xml do
- root "CodeListRef"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "CodeListRef"
+ namespace Namespace
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "CanonicalUri", to: :canonical_uri, prefix: nil, namespace: nil
- map_element "CanonicalVersionUri", to: :canonical_version_uri, prefix: nil, namespace: nil
- map_element "LocationUri", to: :location_uri, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "CanonicalUri", to: :canonical_uri
+ map_element "CanonicalVersionUri", to: :canonical_version_uri
+ map_element "LocationUri", to: :location_uri
end
end
end
diff --git a/lib/genericode/code_list_set.rb b/lib/genericode/code_list_set.rb
index 3c5c912..dbb31b0 100644
--- a/lib/genericode/code_list_set.rb
+++ b/lib/genericode/code_list_set.rb
@@ -24,14 +24,14 @@ class CodeListSet < Lutaml::Model::Serializable
end
xml do
- root "CodeListSet"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "CodeListSet"
+ namespace Namespace
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "Identification", to: :identification, prefix: nil, namespace: nil
- map_element "CodeListRef", to: :code_list_ref, prefix: nil, namespace: nil
- map_element "CodeListSet", to: :code_list_set, prefix: nil, namespace: nil
- map_element "CodeListSetRef", to: :code_list_set_ref, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "Identification", to: :identification
+ map_element "CodeListRef", to: :code_list_ref
+ map_element "CodeListSet", to: :code_list_set
+ map_element "CodeListSetRef", to: :code_list_set_ref
end
def validate_verbose
@@ -40,19 +40,24 @@ def validate_verbose
# Rule 47: CodeListSet reference validation
code_list_set_ref&.each do |ref|
unless valid_uri?(ref.canonical_uri) && valid_uri?(ref.canonical_version_uri)
- errors << { code: "INVALID_CODELIST_SET_REF", message: "Invalid CodeListSet reference URI" }
+ errors << { code: "INVALID_CODELIST_SET_REF",
+ message: "Invalid CodeListSet reference URI" }
end
end
# Rule 48-51: URI validations
[canonical_uri, canonical_version_uri].each do |uri|
- errors << { code: "INVALID_URI", message: "Invalid URI: #{uri}" } unless valid_uri?(uri)
+ unless valid_uri?(uri)
+ errors << { code: "INVALID_URI",
+ message: "Invalid URI: #{uri}" }
+ end
end
# Rule 52-53: LocationUri validation
location_uri&.each do |uri|
unless valid_genericode_uri?(uri)
- errors << { code: "INVALID_LOCATION_URI", message: "Invalid LocationUri: #{uri}" }
+ errors << { code: "INVALID_LOCATION_URI",
+ message: "Invalid LocationUri: #{uri}" }
end
end
diff --git a/lib/genericode/code_list_set_ref.rb b/lib/genericode/code_list_set_ref.rb
index a73ec41..76abe5b 100644
--- a/lib/genericode/code_list_set_ref.rb
+++ b/lib/genericode/code_list_set_ref.rb
@@ -9,6 +9,7 @@
module Genericode
class CodeListSetRef < Lutaml::Model::Serializable
include Json::CanonicalUriMixin
+
attribute :annotation, Annotation
attribute :canonical_uri, CanonicalUri
attribute :canonical_version_uri, :string
@@ -16,19 +17,20 @@ class CodeListSetRef < Lutaml::Model::Serializable
json do
map "Annotation", to: :annotation
- map "CanonicalUri", to: :canonical_uri, with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
+ map "CanonicalUri", to: :canonical_uri,
+ with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
map "CanonicalVersionUri", to: :canonical_version_uri
map "LocationUri", to: :location_uri
end
xml do
- root "CodeListSetRef"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "CodeListSetRef"
+ namespace Namespace
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "CanonicalUri", to: :canonical_uri, prefix: nil, namespace: nil
- map_element "CanonicalVersionUri", to: :canonical_version_uri, prefix: nil, namespace: nil
- map_element "LocationUri", to: :location_uri, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "CanonicalUri", to: :canonical_uri
+ map_element "CanonicalVersionUri", to: :canonical_version_uri
+ map_element "LocationUri", to: :location_uri
end
end
end
diff --git a/lib/genericode/column.rb b/lib/genericode/column.rb
index b09f014..239b62a 100644
--- a/lib/genericode/column.rb
+++ b/lib/genericode/column.rb
@@ -29,9 +29,12 @@ class Column < Lutaml::Model::Serializable
map "Required", to: :use, with: { from: :use_from_json, to: :use_to_json }
map "Id", to: :id
map "Annotation", to: :annotation
- map "ShortName", to: :short_name, with: { from: :short_name_from_json, to: :short_name_to_json }
- map "LongName", to: :long_name, with: { from: :long_name_from_json, to: :long_name_to_json }
- map "CanonicalUri", to: :canonical_uri, with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
+ map "ShortName", to: :short_name,
+ with: { from: :short_name_from_json, to: :short_name_to_json }
+ map "LongName", to: :long_name,
+ with: { from: :long_name_from_json, to: :long_name_to_json }
+ map "CanonicalUri", to: :canonical_uri,
+ with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
map "CanonicalVersionUri", to: :canonical_version_uri
map "DataType", to: :type, delegate: :data
map "DataLanguage", to: :lang, delegate: :data
@@ -56,17 +59,17 @@ def long_name_to_json(model, doc)
end
xml do
- root "Column"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "Column"
+ namespace Namespace
map_attribute "Id", to: :id
map_attribute "Use", to: :use
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "ShortName", to: :short_name, prefix: nil, namespace: nil
- map_element "LongName", to: :long_name, prefix: nil, namespace: nil
- map_element "CanonicalUri", to: :canonical_uri, prefix: nil, namespace: nil
- map_element "CanonicalVersionUri", to: :canonical_version_uri, prefix: nil, namespace: nil
- map_element "Data", to: :data, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "ShortName", to: :short_name
+ map_element "LongName", to: :long_name
+ map_element "CanonicalUri", to: :canonical_uri
+ map_element "CanonicalVersionUri", to: :canonical_version_uri
+ map_element "Data", to: :data
end
end
end
diff --git a/lib/genericode/column_ref.rb b/lib/genericode/column_ref.rb
index 63bc0ec..3b34dcc 100644
--- a/lib/genericode/column_ref.rb
+++ b/lib/genericode/column_ref.rb
@@ -26,16 +26,16 @@ class ColumnRef < Lutaml::Model::Serializable
end
xml do
- root "ColumnRef"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "ColumnRef"
+ namespace Namespace
map_attribute "Id", to: :id
map_attribute "ExternalRef", to: :external_ref
map_attribute "Use", to: :use
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "CanonicalVersionUri", to: :canonical_version_uri, prefix: nil, namespace: nil
- map_element "LocationUri", to: :location_uri, prefix: nil, namespace: nil
- map_element "Data", to: :data, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "CanonicalVersionUri", to: :canonical_version_uri
+ map_element "LocationUri", to: :location_uri
+ map_element "Data", to: :data
end
end
end
diff --git a/lib/genericode/column_set.rb b/lib/genericode/column_set.rb
index be71f49..6dded1c 100644
--- a/lib/genericode/column_set.rb
+++ b/lib/genericode/column_set.rb
@@ -30,16 +30,16 @@ class ColumnSet < Lutaml::Model::Serializable
end
xml do
- root "ColumnSet"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "ColumnSet"
+ namespace Namespace
map_attribute "DatatypeLibrary", to: :datatype_library
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "Identification", to: :identification, prefix: nil, namespace: nil
- map_element "Column", to: :column, prefix: nil, namespace: nil
- map_element "ColumnRef", to: :column_ref, prefix: nil, namespace: nil
- map_element "Key", to: :key, prefix: nil, namespace: nil
- map_element "KeyRef", to: :key_ref, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "Identification", to: :identification
+ map_element "Column", to: :column
+ map_element "ColumnRef", to: :column_ref
+ map_element "Key", to: :key
+ map_element "KeyRef", to: :key_ref
end
end
end
diff --git a/lib/genericode/column_set_ref.rb b/lib/genericode/column_set_ref.rb
index 01054dd..0e28d03 100644
--- a/lib/genericode/column_set_ref.rb
+++ b/lib/genericode/column_set_ref.rb
@@ -17,12 +17,12 @@ class ColumnSetRef < Lutaml::Model::Serializable
end
xml do
- root "ColumnSetRef"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "ColumnSetRef"
+ namespace Namespace
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "CanonicalVersionUri", to: :canonical_version_uri, prefix: nil, namespace: nil
- map_element "LocationUri", to: :location_uri, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "CanonicalVersionUri", to: :canonical_version_uri
+ map_element "LocationUri", to: :location_uri
end
end
end
diff --git a/lib/genericode/data.rb b/lib/genericode/data.rb
index 7ed4c69..7cb89d6 100644
--- a/lib/genericode/data.rb
+++ b/lib/genericode/data.rb
@@ -22,14 +22,14 @@ class Data < Lutaml::Model::Serializable
end
xml do
- root "Data"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "Data"
+ namespace Namespace
map_attribute "Type", to: :type
map_attribute "DatatypeLibrary", to: :datatype_library
map_attribute "Lang", to: :lang
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "Parameter", to: :parameter, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "Parameter", to: :parameter
end
end
end
diff --git a/lib/genericode/data_restrictions.rb b/lib/genericode/data_restrictions.rb
index 2146b8f..49693c8 100644
--- a/lib/genericode/data_restrictions.rb
+++ b/lib/genericode/data_restrictions.rb
@@ -15,11 +15,11 @@ class DataRestrictions < Lutaml::Model::Serializable
end
xml do
- root "DataRestrictions"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "DataRestrictions"
+ namespace Namespace
map_attribute "Lang", to: :lang
- map_element "Parameter", to: :parameter, prefix: nil, namespace: nil
+ map_element "Parameter", to: :parameter
end
end
end
diff --git a/lib/genericode/datatype_facet.rb b/lib/genericode/datatype_facet.rb
index 12299ba..e2d60ad 100644
--- a/lib/genericode/datatype_facet.rb
+++ b/lib/genericode/datatype_facet.rb
@@ -12,14 +12,15 @@ class DatatypeFacet < Lutaml::Model::Serializable
attribute :long_name, :string
json do
- map "ShortName", to: :short_name, with: { from: :short_name_from_json, to: :short_name_to_json }
+ map "ShortName", to: :short_name,
+ with: { from: :short_name_from_json, to: :short_name_to_json }
map "LongName", to: :long_name
map "_", to: :content
end
xml do
- root "DatatypeFacet"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "DatatypeFacet"
+ namespace Namespace
map_content to: :content
map_attribute "ShortName", to: :short_name
diff --git a/lib/genericode/general_identifier.rb b/lib/genericode/general_identifier.rb
index 0028e48..469a250 100644
--- a/lib/genericode/general_identifier.rb
+++ b/lib/genericode/general_identifier.rb
@@ -15,8 +15,8 @@ class GeneralIdentifier < Lutaml::Model::Serializable
end
xml do
- root "GeneralIdentifier"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "GeneralIdentifier"
+ namespace Namespace
map_content to: :content
map_attribute "Identifier", to: :identifier
diff --git a/lib/genericode/identification.rb b/lib/genericode/identification.rb
index aac32fe..c7531b9 100644
--- a/lib/genericode/identification.rb
+++ b/lib/genericode/identification.rb
@@ -22,19 +22,24 @@ class Identification < Lutaml::Model::Serializable
attribute :canonical_uri, CanonicalUri
attribute :canonical_version_uri, :string
attribute :location_uri, :string, collection: true, initialize_empty: true
- attribute :alternate_format_location_uri, MimeTypedUri, collection: true, initialize_empty: true
+ attribute :alternate_format_location_uri, MimeTypedUri, collection: true,
+ initialize_empty: true
attribute :agency, Agency
json do
- map "ShortName", to: :short_name, with: { from: :short_name_from_json, to: :short_name_to_json }
- map "LongName", to: :long_name, with: { from: :long_name_from_json, to: :long_name_to_json }
+ map "ShortName", to: :short_name,
+ with: { from: :short_name_from_json, to: :short_name_to_json }
+ map "LongName", to: :long_name,
+ with: { from: :long_name_from_json, to: :long_name_to_json }
map "Version", to: :version
- map "CanonicalUri", to: :canonical_uri, with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
+ map "CanonicalUri", to: :canonical_uri,
+ with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
map "CanonicalVersionUri", to: :canonical_version_uri
- map "LocationUri", to: :location_uri, with: { from: :location_uri_from_json, to: :location_uri_to_json }
+ map "LocationUri", to: :location_uri,
+ with: { from: :location_uri_from_json, to: :location_uri_to_json }
map "AlternateFormatLocationUri", to: :alternate_format_location_uri,
with: { from: :alternate_format_location_uri_from_json,
- to: :alternate_format_location_uri_to_json, }
+ to: :alternate_format_location_uri_to_json }
map "Agency", to: :agency
end
@@ -67,21 +72,23 @@ def alternate_format_location_uri_from_json(model, value)
def alternate_format_location_uri_to_json(model, doc)
return if model.alternate_format_location_uri.nil? || model.alternate_format_location_uri.empty?
- doc["AlternateFormatLocationUri"] = MimeTypedUri.as_json(Utils.one_or_all(model.alternate_format_location_uri))
+ doc["AlternateFormatLocationUri"] =
+ MimeTypedUri.as_json(Utils.one_or_all(model.alternate_format_location_uri))
end
xml do
- root "Identification"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
-
- map_element "ShortName", to: :short_name, prefix: nil, namespace: nil
- map_element "LongName", to: :long_name, prefix: nil, namespace: nil
- map_element "Version", to: :version, prefix: nil, namespace: nil
- map_element "CanonicalUri", to: :canonical_uri, prefix: nil, namespace: nil
- map_element "CanonicalVersionUri", to: :canonical_version_uri, prefix: nil, namespace: nil
- map_element "LocationUri", to: :location_uri, prefix: nil, namespace: nil
- map_element "AlternateFormatLocationUri", to: :alternate_format_location_uri, prefix: nil, namespace: nil
- map_element "Agency", to: :agency, prefix: nil, namespace: nil
+ element "Identification"
+ namespace Namespace
+
+ map_element "ShortName", to: :short_name
+ map_element "LongName", to: :long_name
+ map_element "Version", to: :version
+ map_element "CanonicalUri", to: :canonical_uri
+ map_element "CanonicalVersionUri", to: :canonical_version_uri
+ map_element "LocationUri", to: :location_uri
+ map_element "AlternateFormatLocationUri",
+ to: :alternate_format_location_uri
+ map_element "Agency", to: :agency
end
end
end
diff --git a/lib/genericode/key.rb b/lib/genericode/key.rb
index 303dab1..c137e8a 100644
--- a/lib/genericode/key.rb
+++ b/lib/genericode/key.rb
@@ -27,11 +27,15 @@ class Key < Lutaml::Model::Serializable
json do
map "Id", to: :id
map "Annotation", to: :annotation
- map "ShortName", to: :short_name, with: { from: :short_name_from_json, to: :short_name_to_json }
- map "LongName", to: :long_name, with: { from: :long_name_from_json, to: :long_name_to_json }
- map "CanonicalUri", to: :canonical_uri, with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
+ map "ShortName", to: :short_name,
+ with: { from: :short_name_from_json, to: :short_name_to_json }
+ map "LongName", to: :long_name,
+ with: { from: :long_name_from_json, to: :long_name_to_json }
+ map "CanonicalUri", to: :canonical_uri,
+ with: { from: :canonical_uri_from_json, to: :canonical_uri_to_json }
map "CanonicalVersionUri", to: :canonical_version_uri
- map "ColumnRef", to: :column_ref, with: { from: :column_ref_from_json, to: :column_ref_to_json }
+ map "ColumnRef", to: :column_ref,
+ with: { from: :column_ref_from_json, to: :column_ref_to_json }
end
def long_name_from_json(model, value)
@@ -45,7 +49,9 @@ def long_name_to_json(model, doc)
end
def column_ref_from_json(model, value)
- model.column_ref = Utils.array_wrap(value).map { |n| KeyColumnRef.new(ref: n) }
+ model.column_ref = Utils.array_wrap(value).map do |n|
+ KeyColumnRef.new(ref: n)
+ end
end
def column_ref_to_json(model, doc)
@@ -53,16 +59,16 @@ def column_ref_to_json(model, doc)
end
xml do
- root "Key"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "Key"
+ namespace Namespace
map_attribute "Id", to: :id
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "ShortName", to: :short_name, prefix: nil, namespace: nil
- map_element "LongName", to: :long_name, prefix: nil, namespace: nil
- map_element "CanonicalUri", to: :canonical_uri, prefix: nil, namespace: nil
- map_element "CanonicalVersionUri", to: :canonical_version_uri, prefix: nil, namespace: nil
- map_element "ColumnRef", to: :column_ref, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "ShortName", to: :short_name
+ map_element "LongName", to: :long_name
+ map_element "CanonicalUri", to: :canonical_uri
+ map_element "CanonicalVersionUri", to: :canonical_version_uri
+ map_element "ColumnRef", to: :column_ref
end
end
end
diff --git a/lib/genericode/key_column_ref.rb b/lib/genericode/key_column_ref.rb
index 852bf25..c7d0c85 100644
--- a/lib/genericode/key_column_ref.rb
+++ b/lib/genericode/key_column_ref.rb
@@ -15,11 +15,11 @@ class KeyColumnRef < Lutaml::Model::Serializable
end
xml do
- root "KeyColumnRef"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "KeyColumnRef"
+ namespace Namespace
map_attribute "Ref", to: :ref
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
end
end
end
diff --git a/lib/genericode/key_ref.rb b/lib/genericode/key_ref.rb
index c6fccb1..66917cf 100644
--- a/lib/genericode/key_ref.rb
+++ b/lib/genericode/key_ref.rb
@@ -21,14 +21,14 @@ class KeyRef < Lutaml::Model::Serializable
end
xml do
- root "KeyRef"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "KeyRef"
+ namespace Namespace
map_attribute "Id", to: :id
map_attribute "ExternalRef", to: :external_ref
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "CanonicalVersionUri", to: :canonical_version_uri, prefix: nil, namespace: nil
- map_element "LocationUri", to: :location_uri, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "CanonicalVersionUri", to: :canonical_version_uri
+ map_element "LocationUri", to: :location_uri
end
end
end
diff --git a/lib/genericode/long_name.rb b/lib/genericode/long_name.rb
index 95ef406..98439d4 100644
--- a/lib/genericode/long_name.rb
+++ b/lib/genericode/long_name.rb
@@ -25,8 +25,8 @@ def lang_to_json(model, doc)
end
xml do
- root "LongName"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "LongName"
+ namespace Namespace
map_content to: :content
map_attribute "Identifier", to: :identifier
diff --git a/lib/genericode/mime_typed_uri.rb b/lib/genericode/mime_typed_uri.rb
index d611816..24a5e64 100644
--- a/lib/genericode/mime_typed_uri.rb
+++ b/lib/genericode/mime_typed_uri.rb
@@ -13,8 +13,8 @@ class MimeTypedUri < Lutaml::Model::Serializable
end
xml do
- root "MimeTypedUri"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "MimeTypedUri"
+ namespace Namespace
map_content to: :content
map_attribute "MimeType", to: :mime_type
diff --git a/lib/genericode/namespace.rb b/lib/genericode/namespace.rb
new file mode 100644
index 0000000..00fbeca
--- /dev/null
+++ b/lib/genericode/namespace.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require "lutaml/model"
+
+module Genericode
+ class Namespace < Lutaml::Model::XmlNamespace
+ uri "http://docs.oasis-open.org/codelist/ns/genericode/1.0/"
+ prefix_default "gc"
+ end
+end
diff --git a/lib/genericode/row.rb b/lib/genericode/row.rb
index 64702e3..181d2fa 100644
--- a/lib/genericode/row.rb
+++ b/lib/genericode/row.rb
@@ -16,11 +16,11 @@ class Row < Lutaml::Model::Serializable
end
xml do
- root "Row"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "Row"
+ namespace Namespace
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "Value", to: :value, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "Value", to: :value
end
end
end
diff --git a/lib/genericode/short_name.rb b/lib/genericode/short_name.rb
index c223ffe..48540cb 100644
--- a/lib/genericode/short_name.rb
+++ b/lib/genericode/short_name.rb
@@ -13,8 +13,8 @@ class ShortName < Lutaml::Model::Serializable
end
xml do
- root "ShortName"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "ShortName"
+ namespace Namespace
map_content to: :content
map_attribute "lang", to: :lang, prefix: "xml", namespace: "http://www.w3.org/XML/1998/namespace"
diff --git a/lib/genericode/simple_code_list.rb b/lib/genericode/simple_code_list.rb
index 71046fa..b4e8b65 100644
--- a/lib/genericode/simple_code_list.rb
+++ b/lib/genericode/simple_code_list.rb
@@ -16,11 +16,11 @@ class SimpleCodeList < Lutaml::Model::Serializable
end
xml do
- root "SimpleCodeList"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "SimpleCodeList"
+ namespace Namespace
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "Row", to: :row, prefix: nil, namespace: nil
+ map_element "Annotation", to: :annotation
+ map_element "Row", to: :row
end
end
end
diff --git a/lib/genericode/simple_value.rb b/lib/genericode/simple_value.rb
index 36fbae0..7bd2a26 100644
--- a/lib/genericode/simple_value.rb
+++ b/lib/genericode/simple_value.rb
@@ -11,8 +11,8 @@ class SimpleValue < Lutaml::Model::Serializable
end
xml do
- root "SimpleValue"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "SimpleValue"
+ namespace Namespace
map_content to: :content
end
diff --git a/lib/genericode/value.rb b/lib/genericode/value.rb
index 9eaf60c..3de4aea 100644
--- a/lib/genericode/value.rb
+++ b/lib/genericode/value.rb
@@ -22,13 +22,13 @@ class Value < Lutaml::Model::Serializable
end
xml do
- root "Value"
- namespace "http://docs.oasis-open.org/codelist/ns/genericode/1.0/", "gc"
+ element "Value"
+ namespace Namespace
- map_attribute "ColumnRef", to: :column_ref, prefix: nil, namespace: nil
- map_element "Annotation", to: :annotation, prefix: nil, namespace: nil
- map_element "SimpleValue", to: :simple_value, prefix: nil, namespace: nil
- map_element "ComplexValue", to: :complex_value, prefix: nil, namespace: nil
+ map_attribute "ColumnRef", to: :column_ref
+ map_element "Annotation", to: :annotation
+ map_element "SimpleValue", to: :simple_value
+ map_element "ComplexValue", to: :complex_value
end
end
end
diff --git a/spec/genericode/cli/code_lister_spec.rb b/spec/genericode/cli/code_lister_spec.rb
index e5b0253..f3caf13 100644
--- a/spec/genericode/cli/code_lister_spec.rb
+++ b/spec/genericode/cli/code_lister_spec.rb
@@ -33,7 +33,7 @@
allow(File).to receive(:read).and_return(valid_xml)
allow(Genericode::CodeList).to receive(:from_xml).and_call_original
- expect(Genericode::Cli::CodeLister.list_codes("valid.gc")).to eq("Code\nCode1\nCode2")
+ expect(described_class.list_codes("valid.gc")).to eq("Code\nCode1\nCode2")
end
it "raises an error when an invalid ColumnRef is found" do
@@ -57,9 +57,9 @@
allow(Genericode::CodeList).to receive(:from_xml).and_call_original
expect do
- Genericode::Cli::CodeLister.list_codes("invalid.gc")
+ described_class.list_codes("invalid.gc")
end.to raise_error(Genericode::Error,
- /INVALID_COLUMN_REF: Invalid ColumnRef 'invalid' in row 1/,)
+ /INVALID_COLUMN_REF: Invalid ColumnRef 'invalid' in row 1/)
end
it "raises an error when a code value is invalid" do
@@ -84,9 +84,9 @@
allow(Genericode::CodeList).to receive(:from_xml).and_call_original
expect do
- Genericode::Cli::CodeLister.list_codes("invalid.gc")
+ described_class.list_codes("invalid.gc")
end.to raise_error(Genericode::Error,
- /INVALID_DATA_TYPE: Invalid data type for column 'Code' in row 1/,)
+ /INVALID_DATA_TYPE: Invalid data type for column 'Code' in row 1/)
end
end
end
diff --git a/spec/genericode/cli/code_lookup_spec.rb b/spec/genericode/cli/code_lookup_spec.rb
index fe81db6..484d745 100644
--- a/spec/genericode/cli/code_lookup_spec.rb
+++ b/spec/genericode/cli/code_lookup_spec.rb
@@ -38,21 +38,24 @@
end
it "looks up a code successfully" do
- expect(Genericode::Cli::CodeLookup.lookup("file.gc", "code:Code1")).to eq("Code: Code1\nName: Name1")
+ expect(described_class.lookup("file.gc",
+ "code:Code1")).to eq("Code: Code1\nName: Name1")
end
it "looks up a name successfully" do
- expect(Genericode::Cli::CodeLookup.lookup("file.gc", "name:Name1")).to eq("Code: Code1\nName: Name1")
+ expect(described_class.lookup("file.gc",
+ "name:Name1")).to eq("Code: Code1\nName: Name1")
end
it "looks up a simple value successfully" do
- expect(Genericode::Cli::CodeLookup.lookup("file.gc", "code:Code1>name")).to eq("Name1")
+ expect(described_class.lookup("file.gc",
+ "code:Code1>name")).to eq("Name1")
end
it "raises an error for invalid path" do
expect do
- Genericode::Cli::CodeLookup.lookup("file.gc",
- "invalid:path",)
+ described_class.lookup("file.gc",
+ "invalid:path")
end.to raise_error(Genericode::Error, "Column not found: invalid")
end
end
diff --git a/spec/genericode/cli/commands_spec.rb b/spec/genericode/cli/commands_spec.rb
index 8dbaeae..ee130c9 100644
--- a/spec/genericode/cli/commands_spec.rb
+++ b/spec/genericode/cli/commands_spec.rb
@@ -11,12 +11,20 @@
describe "#convert" do
it "converts XML to JSON successfully" do
allow(Genericode::Cli::Converter).to receive(:convert).and_return(true)
- expect { cli.convert("input.gc", "output.gcj") }.to output("Conversion successful.\n").to_stdout
+ expect do
+ cli.convert("input.gc",
+ "output.gcj")
+ end.to output("Conversion successful.\n").to_stdout
end
it "handles conversion errors" do
- allow(Genericode::Cli::Converter).to receive(:convert).and_raise(Genericode::Error, "Conversion failed")
- expect { cli.convert("input.gc", "output.gcj") }.to output("Conversion failed: Conversion failed\n").to_stdout
+ allow(Genericode::Cli::Converter).to receive(:convert).and_raise(
+ Genericode::Error, "Conversion failed"
+ )
+ expect do
+ cli.convert("input.gc",
+ "output.gcj")
+ end.to output("Conversion failed: Conversion failed\n").to_stdout
end
end
@@ -27,8 +35,12 @@
end
it "handles validation errors" do
- allow(Genericode::CodeList).to receive(:from_file).and_raise(Genericode::Error, "Invalid file")
- expect { cli.validate("file.gc") }.to output("Validation failed: Invalid file\n").to_stdout
+ allow(Genericode::CodeList).to receive(:from_file).and_raise(
+ Genericode::Error, "Invalid file"
+ )
+ expect do
+ cli.validate("file.gc")
+ end.to output("Validation failed: Invalid file\n").to_stdout
end
end
@@ -39,8 +51,12 @@
end
it "handles listing errors" do
- allow(Genericode::Cli::CodeLister).to receive(:list_codes).and_raise(Genericode::Error, "Listing failed")
- expect { cli.list_codes("file.gc") }.to output("Listing codes failed: Listing failed\n").to_stdout
+ allow(Genericode::Cli::CodeLister).to receive(:list_codes).and_raise(
+ Genericode::Error, "Listing failed"
+ )
+ expect do
+ cli.list_codes("file.gc")
+ end.to output("Listing codes failed: Listing failed\n").to_stdout
end
end
@@ -51,8 +67,13 @@
end
it "handles lookup errors" do
- allow(Genericode::Cli::CodeLookup).to receive(:lookup).and_raise(Genericode::Error, "Lookup failed")
- expect { cli.lookup("file.gc", "path") }.to output("Lookup failed: Lookup failed\n").to_stdout
+ allow(Genericode::Cli::CodeLookup).to receive(:lookup).and_raise(
+ Genericode::Error, "Lookup failed"
+ )
+ expect do
+ cli.lookup("file.gc",
+ "path")
+ end.to output("Lookup failed: Lookup failed\n").to_stdout
end
end
end
diff --git a/spec/genericode/cli/converter_spec.rb b/spec/genericode/cli/converter_spec.rb
index dd8c5ef..ec702e3 100644
--- a/spec/genericode/cli/converter_spec.rb
+++ b/spec/genericode/cli/converter_spec.rb
@@ -12,7 +12,8 @@
allow(File).to receive(:write)
allow_any_instance_of(Genericode::CodeList).to receive(:to_json).and_return("{}")
- expect(Genericode::Cli::Converter.convert("input.gc", "output.gcj")).to be true
+ expect(described_class.convert("input.gc",
+ "output.gcj")).to be true
end
it "converts JSON to XML" do
@@ -20,28 +21,30 @@
allow(File).to receive(:write)
allow_any_instance_of(Genericode::CodeList).to receive(:to_xml).and_return("")
- expect(Genericode::Cli::Converter.convert("input.gcj", "output.gc")).to be true
+ expect(described_class.convert("input.gcj",
+ "output.gc")).to be true
end
it "raises an error for invalid input format" do
expect do
- Genericode::Cli::Converter.convert("input.txt",
- "output.gcj",)
+ described_class.convert("input.txt",
+ "output.gcj")
end.to raise_error(Genericode::Error, "Invalid input format")
end
it "raises an error for invalid output format" do
expect do
- Genericode::Cli::Converter.convert("input.gc",
- "output.txt",)
+ described_class.convert("input.gc",
+ "output.txt")
end.to raise_error(Genericode::Error, "Invalid output format")
end
it "raises an error when input and output formats are the same" do
expect do
- Genericode::Cli::Converter.convert("input.gc",
- "output.gc",)
- end.to raise_error(Genericode::Error, "Input and output formats are the same")
+ described_class.convert("input.gc",
+ "output.gc")
+ end.to raise_error(Genericode::Error,
+ "Input and output formats are the same")
end
end
end
diff --git a/spec/genericode/cli/validator_spec.rb b/spec/genericode/cli/validator_spec.rb
index 185b963..9450109 100644
--- a/spec/genericode/cli/validator_spec.rb
+++ b/spec/genericode/cli/validator_spec.rb
@@ -27,17 +27,16 @@
end
it "validates a valid XML file" do
- allow(File).to receive(:exist?).and_return(true)
- allow(File).to receive(:read).and_return(valid_xml)
+ allow(File).to receive_messages(exist?: true, read: valid_xml)
- expect(Genericode::Cli::Validator.validate("valid.gc")).to be true
+ expect(described_class.validate("valid.gc")).to be true
end
it "raises an error for non-existent file" do
allow(File).to receive(:exist?).and_return(false)
expect do
- Genericode::Cli::Validator.validate("nonexistent.gc")
+ described_class.validate("nonexistent.gc")
end.to raise_error(Genericode::Error, "File does not exist")
end
@@ -45,26 +44,27 @@
allow(File).to receive(:exist?).and_return(true)
expect do
- Genericode::Cli::Validator.validate("invalid.txt")
+ described_class.validate("invalid.txt")
end.to raise_error(Genericode::Error, "Invalid file format")
end
it "raises an error for empty column set" do
xml_without_columns = "
"
- allow(File).to receive(:exist?).and_return(true)
- allow(File).to receive(:read).and_return(xml_without_columns)
+ allow(File).to receive_messages(exist?: true, read: xml_without_columns)
expect do
- Genericode::Cli::Validator.validate("invalid.gc")
+ described_class.validate("invalid.gc")
end.to raise_error(Genericode::Error, "No columns defined")
end
it "raises an error for empty row set" do
xml_without_rows = ""
- allow(File).to receive(:exist?).and_return(true)
- allow(File).to receive(:read).and_return(xml_without_rows)
+ allow(File).to receive_messages(exist?: true, read: xml_without_rows)
- expect { Genericode::Cli::Validator.validate("invalid.gc") }.to raise_error(Genericode::Error, "No rows defined")
+ expect do
+ described_class.validate("invalid.gc")
+ end.to raise_error(Genericode::Error,
+ "No rows defined")
end
end
end
diff --git a/spec/genericode/code_list_spec.rb b/spec/genericode/code_list_spec.rb
index a0a89e1..514f49b 100644
--- a/spec/genericode/code_list_spec.rb
+++ b/spec/genericode/code_list_spec.rb
@@ -31,14 +31,18 @@
row: [
Genericode::Row.new(
value: [
- Genericode::Value.new(column_ref: "code", simple_value: Genericode::SimpleValue.new(content: "CODE1")),
- Genericode::Value.new(column_ref: "name", simple_value: Genericode::SimpleValue.new(content: "Name 1")),
+ Genericode::Value.new(column_ref: "code",
+ simple_value: Genericode::SimpleValue.new(content: "CODE1")),
+ Genericode::Value.new(column_ref: "name",
+ simple_value: Genericode::SimpleValue.new(content: "Name 1")),
],
),
Genericode::Row.new(
value: [
- Genericode::Value.new(column_ref: "code", simple_value: Genericode::SimpleValue.new(content: "CODE2")),
- Genericode::Value.new(column_ref: "name", simple_value: Genericode::SimpleValue.new(content: "Name 2")),
+ Genericode::Value.new(column_ref: "code",
+ simple_value: Genericode::SimpleValue.new(content: "CODE2")),
+ Genericode::Value.new(column_ref: "name",
+ simple_value: Genericode::SimpleValue.new(content: "Name 2")),
],
),
],
@@ -92,7 +96,7 @@
it "reports duplicate column IDs" do
invalid_column_set = valid_column_set.dup
invalid_column_set.column << Genericode::Column.new(id: "code",
- short_name: Genericode::ShortName.new(content: "Duplicate"),)
+ short_name: Genericode::ShortName.new(content: "Duplicate"))
invalid_code_list = valid_code_list.dup
invalid_code_list.column_set = invalid_column_set
result = invalid_code_list.validate_verbose
@@ -101,7 +105,8 @@
it "reports missing Code column" do
invalid_column_set = Genericode::ColumnSet.new(
- column: [Genericode::Column.new(id: "name", short_name: Genericode::ShortName.new(content: "Name"))],
+ column: [Genericode::Column.new(id: "name",
+ short_name: Genericode::ShortName.new(content: "Name"))],
)
invalid_code_list = valid_code_list.dup
invalid_code_list.column_set = invalid_column_set
@@ -112,7 +117,8 @@
it "reports duplicate code values" do
invalid_simple_code_list = valid_simple_code_list.dup
invalid_simple_code_list.row << Genericode::Row.new(
- value: [Genericode::Value.new(column_ref: "code", simple_value: Genericode::SimpleValue.new(content: "CODE1"))],
+ value: [Genericode::Value.new(column_ref: "code",
+ simple_value: Genericode::SimpleValue.new(content: "CODE1"))],
)
invalid_code_list = valid_code_list.dup
invalid_code_list.simple_code_list = invalid_simple_code_list
@@ -124,7 +130,7 @@
invalid_simple_code_list = valid_simple_code_list.dup
invalid_simple_code_list.row << Genericode::Row.new(
value: [Genericode::Value.new(column_ref: "name",
- simple_value: Genericode::SimpleValue.new(content: "Name 3"),)],
+ simple_value: Genericode::SimpleValue.new(content: "Name 3"))],
)
invalid_code_list = valid_code_list.dup
invalid_code_list.simple_code_list = invalid_simple_code_list
@@ -158,7 +164,9 @@
it "converts XML to JSON correctly" do
code_list = described_class.from_xml(xml_content)
generated_json = JSON.parse(code_list.to_json(except: [:annotation]))
- expected_json = JSON.parse(json_content).tap { |n| n.delete("Annotation") }
+ expected_json = JSON.parse(json_content).tap do |n|
+ n.delete("Annotation")
+ end
expect(generated_json).to eq(expected_json)
end
diff --git a/spec/genericode_spec.rb b/spec/genericode_spec.rb
index 4d9d787..61b6117 100644
--- a/spec/genericode_spec.rb
+++ b/spec/genericode_spec.rb
@@ -2,6 +2,7 @@
require "spec_helper"
require "pathname"
+require "nokogiri"
require_relative "../lib/genericode/code_list"
RSpec.describe Genericode do
@@ -13,6 +14,24 @@ def check_parsed_content(parsed, reparsed)
expect(reparsed.simple_code_list.row.size).to eq(parsed.simple_code_list.row.size)
end
+ def strip_xml_comments(xml_string)
+ doc = Nokogiri::XML(xml_string)
+ doc.xpath("//comment()").remove
+ doc.to_xml
+ end
+
+ def normalize_empty_elements(xml_string)
+ doc = Nokogiri::XML(xml_string)
+ # Find all elements and normalize their text content
+ doc.xpath("//*").each do |node|
+ # If element has no children and only whitespace text, set to empty
+ node.content = "" if node.children.all? do |child|
+ child.text? && child.text.strip.empty?
+ end
+ end
+ doc.to_xml
+ end
+
describe "XML round-trip conversion" do
xml_files = Dir[fixtures_dir.join("xml", "*", "*.gc")]
@@ -40,7 +59,11 @@ def check_parsed_content(parsed, reparsed)
encoding: "utf-8",
)
- expect(generated).to be_analogous_with(xml_string)
+ # Strip XML comments and normalize empty elements before comparison
+ xml_string_cleaned = normalize_empty_elements(strip_xml_comments(xml_string))
+ generated_cleaned = normalize_empty_elements(strip_xml_comments(generated))
+
+ expect(generated_cleaned).to be_xml_equivalent_to(xml_string_cleaned)
end
end
end
@@ -62,7 +85,9 @@ def check_parsed_content(parsed, reparsed)
end
it "performs lossless round-trip conversion" do
- original_to_test = JSON.parse(json_string).tap { |n| n.delete("Annotation") }.to_json
+ original_to_test = JSON.parse(json_string).tap do |n|
+ n.delete("Annotation")
+ end.to_json
parsed = Genericode::CodeList.from_json(original_to_test)
generated = Genericode::CodeList.to_json(parsed)
reparsed = Genericode::CodeList.from_json(generated)
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 6d92c5a..46534b5 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -2,7 +2,7 @@
require "genericode"
require "nokogiri"
-require "xml-c14n"
+require "canon"
RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure