moxml 0.1.21 → 0.1.22

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/opal.yml +37 -0
  3. data/.rspec-opal +5 -0
  4. data/Gemfile +6 -0
  5. data/Rakefile +67 -0
  6. data/lib/compat/opal/rexml/namespace.rb +56 -0
  7. data/lib/compat/opal/rexml/parsers/baseparser.rb +952 -0
  8. data/lib/compat/opal/rexml/source.rb +213 -0
  9. data/lib/compat/opal/rexml/text.rb +418 -0
  10. data/lib/compat/opal/rexml/xmltokens.rb +45 -0
  11. data/lib/compat/opal/rexml_compat.rb +76 -0
  12. data/lib/moxml/adapter/customized_rexml/formatter.rb +11 -10
  13. data/lib/moxml/adapter/headed_ox.rb +2 -6
  14. data/lib/moxml/adapter/libxml.rb +5 -20
  15. data/lib/moxml/adapter/nokogiri.rb +7 -18
  16. data/lib/moxml/adapter/oga.rb +4 -22
  17. data/lib/moxml/adapter/ox.rb +8 -23
  18. data/lib/moxml/adapter/rexml.rb +29 -33
  19. data/lib/moxml/adapter.rb +38 -8
  20. data/lib/moxml/config.rb +1 -1
  21. data/lib/moxml/entity_registry.rb +36 -31
  22. data/lib/moxml/entity_registry_opal_data.rb +2137 -0
  23. data/lib/moxml/node.rb +19 -26
  24. data/lib/moxml/sax/namespace_splitter.rb +54 -0
  25. data/lib/moxml/version.rb +1 -1
  26. data/lib/moxml/xml_utils.rb +9 -1
  27. data/spec/consistency/adapter_parity_spec.rb +1 -1
  28. data/spec/integration/all_adapters_spec.rb +1 -1
  29. data/spec/integration/w3c_namespace_spec.rb +1 -1
  30. data/spec/moxml/adapter/ox_spec.rb +8 -0
  31. data/spec/moxml/adapter/platform_spec.rb +69 -0
  32. data/spec/moxml/adapter/shared_examples/adapter_contract.rb +0 -6
  33. data/spec/moxml/entity_registry_spec.rb +10 -0
  34. data/spec/moxml/native_attachment/opal_spec.rb +39 -2
  35. data/spec/moxml/node_type_map_spec.rb +43 -0
  36. data/spec/moxml/opal_rexml_adapter_spec.rb +14 -0
  37. data/spec/moxml/opal_smoke_spec.rb +61 -0
  38. data/spec/moxml/sax/namespace_splitter_spec.rb +67 -0
  39. data/spec/moxml/text_spec.rb +1 -1
  40. data/spec/spec_helper.rb +32 -13
  41. data/spec/support/opal.rb +16 -0
  42. metadata +17 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd873f36f1ee8d7799299cedbc4bfa7da00d588e311693be8b6e718b9e09fa8d
4
- data.tar.gz: 2597df5af105dfcfdc84586b98473e99af95681fbf1ef24b0c2c6698280e6dbb
3
+ metadata.gz: 60a73965c593149af81d6f6119fbdc7854a980a4a0979091efd2e763c304354b
4
+ data.tar.gz: 7ba2d518b5faf0dc6bd2a69cb17c5f104e3a9a3e64e22ca308932997908aca34
5
5
  SHA512:
6
- metadata.gz: b39f087ced4fc9ea76722e32c8b036ee7e4819798bec248af520f51bb20039cb76459837e1b5a65540f46bf7112ee5922eece22cac763ef25b3235a0c5ca60f6
7
- data.tar.gz: 75847baca549e9cb0902203f2d8b9f8e4e764c048dc0cd57260d6995f1aa233c5db6ecdb6786344cdfb097b4ec73a088d1c12b4d79b2fcb5217c936ba4605ec1
6
+ metadata.gz: 2ecd5ef09dfccc20ec6fc9ae74aa4cb18bab571db5b99965335e2b07632d779ca4e747dd81eb4ee98bc87b2675120b126c818b7e501c96a244d6853714ce81aa
7
+ data.tar.gz: dea93a39f7645daaee7b835ba871bbfbf85d221a892cd7e8da49472f2421709ec8252526f4222f8ab399ac482a5f3249fca745d0802e9fe7dd9b745d80b4ad02
@@ -0,0 +1,37 @@
1
+ name: opal
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: [ v* ]
7
+ pull_request:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+ with:
18
+ submodules: "recursive"
19
+
20
+ - name: Set up Ruby
21
+ uses: ruby/setup-ruby@v1
22
+ with:
23
+ ruby-version: "3.4"
24
+ bundler-cache: true
25
+
26
+ - name: Set up Node.js
27
+ uses: actions/setup-node@v4
28
+ with:
29
+ node-version: "18"
30
+
31
+ - name: Install Opal dependencies
32
+ run: |
33
+ npm list -g opal-compiler || npm install -g opal-compiler
34
+ bundle exec rake opal:generate_entity_data
35
+
36
+ - name: Run Opal tests
37
+ run: bundle exec rake spec:opal
data/.rspec-opal ADDED
@@ -0,0 +1,5 @@
1
+ --default-path=spec
2
+ -I lib
3
+ -I spec
4
+ --require=spec_helper
5
+ --require=support/opal
data/Gemfile CHANGED
@@ -27,3 +27,9 @@ gem "tempfile"
27
27
 
28
28
  # Needed by get_process_mem on Windows
29
29
  gem "sys-proctable" if Gem.win_platform?
30
+
31
+ group :opal do
32
+ gem "opal", "~> 1.8"
33
+ gem "opal-rspec", "~> 1.0"
34
+ gem "opal-sprockets"
35
+ end
data/Rakefile CHANGED
@@ -5,11 +5,40 @@ require "rspec/core/rake_task"
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
+ begin
9
+ require "opal/rspec/rake_task"
10
+
11
+ # REXML is a bundled gem since Ruby 3.4; its source must be on Opal's
12
+ # global load path so the compiler can follow `require "rexml/document"`.
13
+ # Opal-compatible overrides go first so they shadow the gem originals.
14
+ if defined?(Opal)
15
+ Opal.append_path File.expand_path("lib/compat/opal", __dir__)
16
+ rexml_lib = $LOAD_PATH.find { |p| File.exist?(File.join(p, "rexml", "document.rb")) }
17
+ Opal.append_path rexml_lib if rexml_lib
18
+ end
19
+ rescue LoadError
20
+ # Opal not available or incompatible with current Ruby version
21
+ end
22
+
8
23
  require "rubocop/rake_task"
9
24
 
10
25
  RuboCop::RakeTask.new
11
26
 
12
27
  namespace :spec do
28
+ if defined?(Opal::RSpec::RakeTask)
29
+ desc "Run Opal (JavaScript) tests"
30
+ Opal::RSpec::RakeTask.new(:opal) do |server, runner|
31
+ server.append_path "lib"
32
+ server.append_path "spec"
33
+
34
+ runner.default_path = "spec"
35
+ runner.requires = %w[rexml_compat rexml/document rexml/xpath moxml/adapter/rexml spec_helper support/opal]
36
+ runner.files = Dir.glob("spec/moxml/*opal*_spec.rb") +
37
+ Dir.glob("spec/moxml/native_attachment/opal_spec.rb") +
38
+ Dir.glob("spec/moxml/adapter/shared_examples/*.rb")
39
+ end
40
+ end
41
+
13
42
  desc "Validate XML fixtures are well-formed (requires xmllint)"
14
43
  task :validate_fixtures do
15
44
  fixtures = Dir.glob("spec/fixtures/**/*.xml")
@@ -106,4 +135,42 @@ namespace :benchmark do
106
135
  end
107
136
  end
108
137
 
138
+ namespace :opal do
139
+ desc "Regenerate entity data for Opal from w3c_entities.json"
140
+ task :generate_entity_data do
141
+ require "json"
142
+
143
+ source = File.join(__dir__, "data", "w3c_entities.json")
144
+ target = File.join(__dir__, "lib", "moxml", "entity_registry_opal_data.rb")
145
+
146
+ data = JSON.parse(File.read(source))
147
+ chars = data["characters"]
148
+
149
+ lines = []
150
+ lines << "# frozen_string_literal: true"
151
+ lines << "#"
152
+ lines << "# Auto-generated entity data for Opal runtime."
153
+ lines << "# Source: data/w3c_entities.json (#{chars.size} entities)"
154
+ lines << "# Regenerate with: rake opal:generate_entity_data"
155
+ lines << ""
156
+ lines << "module Moxml"
157
+ lines << " class EntityRegistry"
158
+ lines << " OPAL_ENTITY_DATA = {"
159
+ chars.each do |name, char|
160
+ codepoint = if char.start_with?("\\u")
161
+ char.unicode_normalize(:nfc)[2..].to_i(16)
162
+ else
163
+ char.ord
164
+ end
165
+ lines << " #{name.inspect} => #{codepoint},"
166
+ end
167
+ lines << " }.freeze"
168
+ lines << " end"
169
+ lines << "end"
170
+
171
+ File.write(target, lines.join("\n") + "\n")
172
+ puts "Generated #{target} (#{chars.size} entities, #{lines.size} lines)"
173
+ end
174
+ end
175
+
109
176
  task default: %i[spec rubocop]
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rexml/xmltokens'
4
+
5
+ module REXML
6
+ module Namespace
7
+ attr_reader :name, :expanded_name
8
+ attr_accessor :prefix
9
+ include XMLTokens
10
+ NAME_WITHOUT_NAMESPACE = /^#{NCNAME_STR}$/
11
+ NAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u
12
+
13
+ def name=( name )
14
+ @expanded_name = name
15
+ if name.match?(NAME_WITHOUT_NAMESPACE)
16
+ @prefix = ""
17
+ @namespace = ""
18
+ @name = name
19
+ elsif name =~ NAMESPLIT
20
+ if $1
21
+ @prefix = $1
22
+ else
23
+ @prefix = ""
24
+ @namespace = ""
25
+ end
26
+ @name = $2
27
+ elsif name == ""
28
+ @prefix = nil
29
+ @namespace = nil
30
+ @name = nil
31
+ else
32
+ message = "name must be \#{PREFIX}:\#{LOCAL_NAME} or \#{LOCAL_NAME}: "
33
+ message += "<#{name.inspect}>"
34
+ raise ArgumentError, message
35
+ end
36
+ end
37
+
38
+ def has_name?( other, ns=nil )
39
+ if ns
40
+ namespace() == ns and name() == other
41
+ elsif other.include? ":"
42
+ fully_expanded_name == other
43
+ else
44
+ name == other
45
+ end
46
+ end
47
+
48
+ alias :local_name :name
49
+
50
+ def fully_expanded_name
51
+ ns = prefix
52
+ return "#{ns}:#@name" if ns.size > 0
53
+ @name
54
+ end
55
+ end
56
+ end