unitsml 0.6.5 → 0.6.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 259201a79075b2582ec667b6e6aa248c73bad6ca3ac8cc459e97132fd0caa185
4
- data.tar.gz: ad0f345f72489cc4bde6de16662487952ec4d69dda6ada63fc6db6807e2ec41c
3
+ metadata.gz: e322bdcbc4d88923eb7a82c77d492e9adfa22bd6bbde18d597dcb4ebd31b27b9
4
+ data.tar.gz: dab029431c9ba4393680944b2b4ba8f0cf3943bf0b004f2a8338a9efff856a3a
5
5
  SHA512:
6
- metadata.gz: 6fb49ee8588876bd5447b72d88fc1d5a9aa59863c4f147f75db8b2fc9e7a7a52c1edb95d94679e8f135935c5683d6986b4b02ad39e80362b19a4226d4b55c81b
7
- data.tar.gz: 258c8491a3072e86cb4004060fc1dd4ef22f0a8959164882ebfa1c8323123926e869e1167c178e8ecc9d7d73c3d8f2d97d24b9511a4b04f363f02d0780cff151
6
+ metadata.gz: 55c5698138fd5c5b0bc2dce065374688485b7cff2f8622acb64407876bd5c207def0939df6284fa47afb468e8656ce14d72905566f9266c8167b22cb925aa8ea
7
+ data.tar.gz: b81e21da16dfc6797901147c7223209973e9050163b766e21f2a4a6422659337be9c339e51b7fd9979c560044573011a05af24f106290b7b7aa27e2fcf50bd01
@@ -0,0 +1,42 @@
1
+ name: opal
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ opal-verification:
13
+ name: Opal boot file and payload verification
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: '3.3'
22
+ bundler-cache: true
23
+
24
+ - name: Set up Node.js
25
+ uses: actions/setup-node@v4
26
+ with:
27
+ node-version: '18'
28
+
29
+ - name: Run Opal specs
30
+ # Verifies the Opal toolchain for unitsml:
31
+ # - the boot file (lib/unitsml/opal.rb) eager-requires every
32
+ # autoloaded entry point so Opal users see no NameError,
33
+ # - the committed database_payload.rb is in sync with the
34
+ # PayloadGenerator output for the current unitsdb gem,
35
+ # - the PayloadGenerator produces evaluable Ruby that round-trips
36
+ # through Unitsml::Unitsdb::Database.from_hash,
37
+ # - Opal::Builder can compile the boot file end-to-end with
38
+ # native-only deps stubbed (the consumer provides them).
39
+ run: |
40
+ bundle exec rspec spec/unitsml/opal_boot_spec.rb \
41
+ spec/unitsml/payload_sync_spec.rb \
42
+ spec/unitsml/opal/payload_generator_spec.rb
data/.gitignore CHANGED
@@ -9,5 +9,14 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ # Local planning / scratch files — never ship in the gem
14
+ TODO*
15
+ NOTES*
16
+
17
+ # Editor / OS noise
18
+ .DS_Store
19
+ /.ruby-lsp/
20
+
12
21
  Gemfile.lock
13
22
  /vendor/bundle/
data/.rubocop.yml CHANGED
@@ -16,3 +16,4 @@ AllCops:
16
16
  Exclude:
17
17
  - 'unitsdb/**/*'
18
18
  - 'vendor/**/*'
19
+ - 'lib/unitsml/opal/database_payload.rb'
data/.rubocop_todo.yml CHANGED
@@ -1,31 +1,84 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-04-15 09:29:09 UTC using RuboCop version 1.86.1.
3
+ # on 2026-06-29 02:49:40 UTC using RuboCop version 1.88.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
+ # Offense count: 2
10
+ # This cop supports safe autocorrection (--autocorrect).
11
+ # Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation.
12
+ Gemspec/OrderedDependencies:
13
+ Exclude:
14
+ - 'unitsml.gemspec'
15
+
9
16
  # Offense count: 1
10
17
  Gemspec/RequiredRubyVersion:
11
18
  Exclude:
12
19
  - 'unitsml.gemspec'
13
20
 
14
- # Offense count: 1
21
+ # Offense count: 3
15
22
  # This cop supports safe autocorrection (--autocorrect).
16
23
  # Configuration parameters: EnforcedStyle, IndentationWidth.
17
24
  # SupportedStyles: with_first_argument, with_fixed_indentation
18
25
  Layout/ArgumentAlignment:
19
26
  Exclude:
20
- - 'lib/unitsml/unit.rb'
27
+ - 'lib/unitsml/formula.rb'
28
+ - 'lib/unitsml/utility.rb'
29
+
30
+ # Offense count: 2
31
+ # This cop supports safe autocorrection (--autocorrect).
32
+ # Configuration parameters: EnforcedStyleAlignWith.
33
+ # SupportedStylesAlignWith: either, start_of_block, start_of_line
34
+ Layout/BlockAlignment:
35
+ Exclude:
36
+ - 'lib/unitsml/utility.rb'
21
37
 
22
- # Offense count: 76
38
+ # Offense count: 1
39
+ # This cop supports safe autocorrection (--autocorrect).
40
+ Layout/BlockEndNewline:
41
+ Exclude:
42
+ - 'lib/unitsml/utility.rb'
43
+
44
+ # Offense count: 1
45
+ # This cop supports safe autocorrection (--autocorrect).
46
+ Layout/ElseAlignment:
47
+ Exclude:
48
+ - 'lib/unitsml/utility.rb'
49
+
50
+ # Offense count: 1
51
+ # This cop supports safe autocorrection (--autocorrect).
52
+ # Configuration parameters: EnforcedStyleAlignWith.
53
+ # SupportedStylesAlignWith: keyword, variable, start_of_line
54
+ Layout/EndAlignment:
55
+ Exclude:
56
+ - 'lib/unitsml/utility.rb'
57
+
58
+ # Offense count: 2
59
+ # This cop supports safe autocorrection (--autocorrect).
60
+ # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
61
+ # SupportedHashRocketStyles: key, separator, table
62
+ # SupportedColonStyles: key, separator, table
63
+ # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
64
+ Layout/HashAlignment:
65
+ Exclude:
66
+ - 'lib/unitsml/utility.rb'
67
+
68
+ # Offense count: 4
69
+ # This cop supports safe autocorrection (--autocorrect).
70
+ # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
71
+ # SupportedStylesAlignWith: start_of_line, relative_to_receiver
72
+ Layout/IndentationWidth:
73
+ Exclude:
74
+ - 'lib/unitsml/utility.rb'
75
+
76
+ # Offense count: 78
23
77
  # This cop supports safe autocorrection (--autocorrect).
24
78
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
25
79
  # URISchemes: http, https
26
80
  Layout/LineLength:
27
81
  Exclude:
28
- - 'lib/unitsml/fenced.rb'
29
82
  - 'lib/unitsml/formula.rb'
30
83
  - 'lib/unitsml/intermediate_exp_rules.rb'
31
84
  - 'lib/unitsml/parse.rb'
@@ -41,20 +94,15 @@ Layout/LineLength:
41
94
  - 'spec/unitsml/conv/xml_spec.rb'
42
95
  - 'unitsml.gemspec'
43
96
 
44
- # Offense count: 1
97
+ # Offense count: 2
45
98
  # This cop supports safe autocorrection (--autocorrect).
46
99
  # Configuration parameters: AllowInHeredoc.
47
100
  Layout/TrailingWhitespace:
48
101
  Exclude:
49
- - 'lib/unitsml/unit.rb'
50
-
51
- # Offense count: 3
52
- Lint/ReturnInVoidContext:
53
- Exclude:
54
- - 'lib/unitsml/unitsdb/si_derived_base.rb'
55
- - 'lib/unitsml/unitsdb/unit.rb'
102
+ - 'lib/unitsml/formula.rb'
103
+ - 'lib/unitsml/utility.rb'
56
104
 
57
- # Offense count: 19
105
+ # Offense count: 17
58
106
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
59
107
  Metrics/AbcSize:
60
108
  Exclude:
@@ -74,7 +122,7 @@ Metrics/CyclomaticComplexity:
74
122
  - 'lib/unitsml/parser.rb'
75
123
  - 'lib/unitsml/utility.rb'
76
124
 
77
- # Offense count: 14
125
+ # Offense count: 18
78
126
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
79
127
  Metrics/MethodLength:
80
128
  Max: 20
@@ -84,11 +132,10 @@ Metrics/MethodLength:
84
132
  Metrics/ParameterLists:
85
133
  Max: 6
86
134
 
87
- # Offense count: 9
135
+ # Offense count: 8
88
136
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
89
137
  Metrics/PerceivedComplexity:
90
138
  Exclude:
91
- - 'lib/unitsml/formula.rb'
92
139
  - 'lib/unitsml/parse.rb'
93
140
  - 'lib/unitsml/parser.rb'
94
141
  - 'lib/unitsml/utility.rb'
@@ -132,12 +179,12 @@ RSpec/ContextWording:
132
179
  - 'spec/unitsml/parse_spec.rb'
133
180
  - 'spec/unitsml/parser_spec.rb'
134
181
 
135
- # Offense count: 5
182
+ # Offense count: 15
136
183
  # Configuration parameters: CountAsOne.
137
184
  RSpec/ExampleLength:
138
185
  Max: 7
139
186
 
140
- # Offense count: 15
187
+ # Offense count: 36
141
188
  RSpec/MultipleExpectations:
142
189
  Max: 6
143
190
 
@@ -170,9 +217,20 @@ RSpec/SpecFilePathFormat:
170
217
 
171
218
  # Offense count: 1
172
219
  # This cop supports safe autocorrection (--autocorrect).
173
- Style/MultilineIfModifier:
220
+ # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
221
+ # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
222
+ # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
223
+ # FunctionalMethods: let, let!, subject, watch
224
+ # AllowedMethods: lambda, proc, it
225
+ Style/BlockDelimiters:
174
226
  Exclude:
175
- - 'lib/unitsml/unit.rb'
227
+ - 'lib/unitsml/utility.rb'
228
+
229
+ # Offense count: 1
230
+ # This cop supports safe autocorrection (--autocorrect).
231
+ Style/MultilineTernaryOperator:
232
+ Exclude:
233
+ - 'lib/unitsml/utility.rb'
176
234
 
177
235
  # Offense count: 2
178
236
  # Configuration parameters: AllowedMethods.
data/Gemfile CHANGED
@@ -6,10 +6,11 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "canon"
9
- gem "lutaml-model", github: "lutaml/lutaml-model", branch: "main"
9
+ gem "nokogiri"
10
10
  gem "oga"
11
+ gem "opal", "~> 1.8"
11
12
  gem "ox"
12
- gem "plurimath", github: "plurimath/plurimath", branch: "main"
13
+ gem "plurimath", "~> 0.11.3"
13
14
  gem "pry"
14
15
  gem "rake"
15
16
  gem "rspec"
data/Rakefile CHANGED
@@ -5,4 +5,14 @@ require "rspec/core/rake_task"
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
+ namespace :unitsml do
9
+ desc "Regenerate lib/unitsml/opal/database_payload.rb from unitsdb YAML"
10
+ task :generate_opal_payload do
11
+ require "unitsml/opal/payload_generator"
12
+ path = Unitsml::Opal::PayloadGenerator::DEFAULT_OUTPUT_PATH
13
+ Unitsml::Opal::PayloadGenerator.new.write_to(path)
14
+ puts "Wrote #{path}"
15
+ end
16
+ end
17
+
8
18
  task default: :spec
@@ -20,6 +20,10 @@ module Unitsml
20
20
  end
21
21
 
22
22
  def register_model(klass, id:)
23
+ unless unitsdb_model_subclass?(klass)
24
+ raise Unitsml::Errors::InvalidModelError, klass
25
+ end
26
+
23
27
  registered_models[id.to_sym] = klass
24
28
  end
25
29
 
@@ -30,11 +34,8 @@ module Unitsml
30
34
  def build_context
31
35
  ::Unitsdb::Config.context # ensure unitsdb context exists
32
36
 
33
- substitutions = registered_models.each_value.filter_map do |klass|
34
- parent = klass.superclass
35
- next if parent == Object
36
-
37
- { from_type: parent, to_type: klass }
37
+ substitutions = registered_models.each_value.map do |klass|
38
+ { from_type: klass.superclass, to_type: klass }
38
39
  end
39
40
 
40
41
  ::Unitsdb::Config.populate_context(
@@ -43,5 +44,14 @@ module Unitsml
43
44
  substitutions: substitutions,
44
45
  )
45
46
  end
47
+
48
+ def unitsdb_model_subclass?(klass)
49
+ return false unless klass.is_a?(Class)
50
+
51
+ parent = klass.superclass
52
+ return false if parent.nil? || parent == Object
53
+
54
+ parent.name&.start_with?("Unitsdb::")
55
+ end
46
56
  end
47
57
  end
@@ -22,7 +22,7 @@ module Unitsml
22
22
  end
23
23
 
24
24
  def dim_symbols
25
- dim_instance.send(dim_instance.processed_keys.last).symbols.first
25
+ dim_instance.public_send(dim_instance.processed_keys.last).symbols.first
26
26
  end
27
27
 
28
28
  def to_mathml(options)
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unitsml
4
+ module Errors
5
+ class InvalidModelError < Unitsml::Errors::BaseError
6
+ def initialize(klass)
7
+ class_name = display_name(klass)
8
+ parent = klass.is_a?(Class) ? klass.superclass : nil
9
+ super("[unitsml] Error: #{class_name} cannot be registered as a " \
10
+ "UnitsML model. register_model expects a subclass of " \
11
+ "::Unitsdb::*, got superclass #{parent}.")
12
+ end
13
+
14
+ private
15
+
16
+ def display_name(klass)
17
+ return klass.inspect unless klass.is_a?(Class)
18
+ return klass.name unless klass.name.nil?
19
+
20
+ klass.inspect
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unitsml
4
+ module Errors
5
+ class UnsupportedPayloadTypeError < Unitsml::Errors::BaseError
6
+ def initialize(actual_class)
7
+ super("[unitsml] Error: Unsupported Opal payload type " \
8
+ "#{actual_class}. PayloadGenerator only emits Hash, Array, " \
9
+ "String, Symbol, Integer, Float, true, false, and nil.")
10
+ end
11
+ end
12
+ end
13
+ end
@@ -3,8 +3,11 @@
3
3
  module Unitsml
4
4
  module Errors
5
5
  autoload :BaseError, "unitsml/errors/base_error"
6
+ autoload :InvalidModelError, "unitsml/errors/invalid_model_error"
6
7
  autoload :OpalPayloadNotBundledError,
7
8
  "unitsml/errors/opal_payload_not_bundled_error"
8
9
  autoload :PlurimathLoadError, "unitsml/errors/plurimath_load_error"
10
+ autoload :UnsupportedPayloadTypeError,
11
+ "unitsml/errors/unsupported_payload_type_error"
9
12
  end
10
13
  end
@@ -92,7 +92,7 @@ module Unitsml
92
92
  end
93
93
 
94
94
  def fenced_conversion_for(lang:, options:)
95
- lang_value = value.send(:"to_#{lang}", options)
95
+ lang_value = value.public_send(:"to_#{lang}", options)
96
96
  return lang_value unless options[:explicit_parenthesis]
97
97
 
98
98
  "#{open_paren}#{lang_value}#{close_paren}"
@@ -81,7 +81,8 @@ module Unitsml
81
81
  :asciimath)
82
82
  end
83
83
 
84
- Plurimath::Math.parse(compact_mathml_for_plurimath(to_mathml(options)), :mathml)
84
+ Plurimath::Math.parse(compact_mathml_for_plurimath(to_mathml(options)),
85
+ :mathml)
85
86
  end
86
87
 
87
88
  def dimensions_extraction
@@ -36,7 +36,7 @@ module Unitsml
36
36
  private
37
37
 
38
38
  def coerce_mml_v4_collection_attributes!(klass, attributes)
39
- return unless klass.respond_to?(:attributes)
39
+ return unless klass.is_a?(Class) && klass <= Lutaml::Model::Serializable
40
40
 
41
41
  attributes.each do |name, value|
42
42
  attribute = klass.attributes[name]
@@ -4,18 +4,18 @@ module Unitsml
4
4
  module Model
5
5
  module DimensionQuantities
6
6
  autoload :AmountOfSubstance,
7
- "#{__dir__}/dimension_quantities/amount_of_substance"
7
+ "unitsml/model/dimension_quantities/amount_of_substance"
8
8
  autoload :ElectricCurrent,
9
- "#{__dir__}/dimension_quantities/electric_current"
10
- autoload :Length, "#{__dir__}/dimension_quantities/length"
9
+ "unitsml/model/dimension_quantities/electric_current"
10
+ autoload :Length, "unitsml/model/dimension_quantities/length"
11
11
  autoload :LuminousIntensity,
12
- "#{__dir__}/dimension_quantities/luminous_intensity"
13
- autoload :Mass, "#{__dir__}/dimension_quantities/mass"
14
- autoload :PlaneAngle, "#{__dir__}/dimension_quantities/plane_angle"
15
- autoload :Quantity, "#{__dir__}/dimension_quantities/quantity"
12
+ "unitsml/model/dimension_quantities/luminous_intensity"
13
+ autoload :Mass, "unitsml/model/dimension_quantities/mass"
14
+ autoload :PlaneAngle, "unitsml/model/dimension_quantities/plane_angle"
15
+ autoload :Quantity, "unitsml/model/dimension_quantities/quantity"
16
16
  autoload :ThermodynamicTemperature,
17
- "#{__dir__}/dimension_quantities/thermodynamic_temperature"
18
- autoload :Time, "#{__dir__}/dimension_quantities/time"
17
+ "unitsml/model/dimension_quantities/thermodynamic_temperature"
18
+ autoload :Time, "unitsml/model/dimension_quantities/time"
19
19
  end
20
20
  end
21
21
  end
@@ -3,8 +3,8 @@
3
3
  module Unitsml
4
4
  module Model
5
5
  module Prefixes
6
- autoload :Name, "#{__dir__}/prefixes/name"
7
- autoload :Symbol, "#{__dir__}/prefixes/symbol"
6
+ autoload :Name, "unitsml/model/prefixes/name"
7
+ autoload :Symbol, "unitsml/model/prefixes/symbol"
8
8
  end
9
9
  end
10
10
  end
@@ -3,7 +3,7 @@
3
3
  module Unitsml
4
4
  module Model
5
5
  module Quantities
6
- autoload :Name, "#{__dir__}/quantities/name"
6
+ autoload :Name, "unitsml/model/quantities/name"
7
7
  end
8
8
  end
9
9
  end
data/lib/unitsml/model.rb CHANGED
@@ -2,14 +2,13 @@
2
2
 
3
3
  module Unitsml
4
4
  module Model
5
- autoload :Dimension, "#{__dir__}/model/dimension"
6
- autoload :DimensionQuantities, "#{__dir__}/model/dimension_quantities"
7
- autoload :Namespace, "#{__dir__}/model/namespace"
8
- autoload :Prefix, "#{__dir__}/model/prefix"
9
- autoload :Prefixes, "#{__dir__}/model/prefixes"
10
- autoload :Quantities, "#{__dir__}/model/quantities"
11
- autoload :Quantity, "#{__dir__}/model/quantity"
12
- autoload :Unit, "#{__dir__}/model/unit"
13
- autoload :Units, "#{__dir__}/model/units"
5
+ autoload :Dimension, "unitsml/model/dimension"
6
+ autoload :DimensionQuantities, "unitsml/model/dimension_quantities"
7
+ autoload :Prefix, "unitsml/model/prefix"
8
+ autoload :Prefixes, "unitsml/model/prefixes"
9
+ autoload :Quantities, "unitsml/model/quantities"
10
+ autoload :Quantity, "unitsml/model/quantity"
11
+ autoload :Unit, "unitsml/model/unit"
12
+ autoload :Units, "unitsml/model/units"
14
13
  end
15
14
  end