proformaxml 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 606acc3bf478e597146722128fa681af0e50985af661a74d302de9c3ab2b5b37
4
- data.tar.gz: 474a73f7e5a09f850d9c8b9e5a4fb90b93953d2ceece434750f91f5a8581b633
3
+ metadata.gz: 4662b9372d02e7ffaf3c7ff7c444732c723d4f84109be5c82fc06a3cabf0cc0b
4
+ data.tar.gz: bc74cbb0142da68f39aa70a9e5c06ef7a2d1313540f120f1e393094c2cf84a81
5
5
  SHA512:
6
- metadata.gz: d482b1a2a9ad647fe971577eeb6e5d19210e08b51bcdab7cc2daecea68cd1cc1389b80ff9da2d75cf628dd36999241655549a29ad41c9c666a9db4c698a7216d
7
- data.tar.gz: d5b0f74efc13fda6dbf91d55799321d694db0961b9d80d07bed395e6f202a0dc8ba935a2437fac82f51d455623af7b208df0b2e3f9e3fc264f1763488ec42031
6
+ metadata.gz: 4ca4104cb636e4ea93c5c6456d5637919895f9ce616b05dc2f4564b17a5a70b9f441f62729025279b15a8b7ac1385d13a7165508bf7bec841bc4d788fc19e0a0
7
+ data.tar.gz: e24fe2ab9db3a08407e35f9ae01da9521e05e6a71c71c4f341de032428582e3cc0d7b4dca9db7f723f27a9789e28a6a7b2b552ad0f30b06835ba04901fa88b0c
data/.rubocop.yml CHANGED
@@ -13,7 +13,7 @@ inherit_from:
13
13
  - .rubocop/style.yml
14
14
 
15
15
  AllCops:
16
- TargetRubyVersion: 3.2
16
+ TargetRubyVersion: 3.3
17
17
  TargetRailsVersion: 7.0 # for ActiveSupport
18
18
  UseCache: True
19
19
  NewCops: enable
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- proformaxml (1.2.0)
4
+ proformaxml (1.3.0)
5
5
  activemodel (>= 5.2.3, < 8.0.0)
6
6
  activesupport (>= 5.2.3, < 8.0.0)
7
7
  dachsfisch (~> 1.0.0)
@@ -11,9 +11,9 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- activemodel (7.1.1)
15
- activesupport (= 7.1.1)
16
- activesupport (7.1.1)
14
+ activemodel (7.1.3.2)
15
+ activesupport (= 7.1.3.2)
16
+ activesupport (7.1.3.2)
17
17
  base64
18
18
  bigdecimal
19
19
  concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -24,21 +24,21 @@ GEM
24
24
  mutex_m
25
25
  tzinfo (~> 2.0)
26
26
  ast (2.4.2)
27
- base64 (0.1.1)
28
- bigdecimal (3.1.4)
27
+ base64 (0.2.0)
28
+ bigdecimal (3.1.6)
29
29
  byebug (11.1.3)
30
30
  coderay (1.1.3)
31
- concurrent-ruby (1.2.2)
31
+ concurrent-ruby (1.2.3)
32
32
  connection_pool (2.4.1)
33
33
  dachsfisch (1.0.0)
34
34
  nokogiri (>= 1.14.1, < 2.0.0)
35
- diff-lcs (1.5.0)
35
+ diff-lcs (1.5.1)
36
36
  docile (1.4.0)
37
- drb (2.1.1)
37
+ drb (2.2.0)
38
38
  ruby2_keywords
39
- factory_bot (6.3.0)
39
+ factory_bot (6.4.6)
40
40
  activesupport (>= 5.0.0)
41
- ffi (1.16.1)
41
+ ffi (1.16.3)
42
42
  formatador (1.1.0)
43
43
  guard (2.18.1)
44
44
  formatador (>= 0.2.4)
@@ -56,24 +56,24 @@ GEM
56
56
  rspec (>= 2.99.0, < 4.0)
57
57
  i18n (1.14.1)
58
58
  concurrent-ruby (~> 1.0)
59
- json (2.6.3)
59
+ json (2.7.1)
60
60
  language_server-protocol (3.17.0.3)
61
61
  listen (3.8.0)
62
62
  rb-fsevent (~> 0.10, >= 0.10.3)
63
63
  rb-inotify (~> 0.9, >= 0.9.10)
64
- lumberjack (1.2.9)
64
+ lumberjack (1.2.10)
65
65
  method_source (1.0.0)
66
- mini_portile2 (2.8.4)
67
- minitest (5.20.0)
68
- mutex_m (0.1.2)
66
+ mini_portile2 (2.8.5)
67
+ minitest (5.22.2)
68
+ mutex_m (0.2.0)
69
69
  nenv (0.3.0)
70
- nokogiri (1.15.4)
70
+ nokogiri (1.16.4)
71
71
  mini_portile2 (~> 2.8.2)
72
72
  racc (~> 1.4)
73
73
  notiffany (0.1.3)
74
74
  nenv (~> 0.1)
75
75
  shellany (~> 0.0)
76
- parallel (1.23.0)
76
+ parallel (1.24.0)
77
77
  parser (3.2.2.4)
78
78
  ast (~> 2.4.1)
79
79
  racc
@@ -83,34 +83,33 @@ GEM
83
83
  pry-byebug (3.10.1)
84
84
  byebug (~> 11.0)
85
85
  pry (>= 0.13, < 0.15)
86
- racc (1.7.1)
87
- rack (3.0.8)
86
+ racc (1.7.3)
87
+ rack (3.0.9.1)
88
88
  rainbow (3.1.1)
89
- rake (13.0.6)
89
+ rake (13.2.1)
90
90
  rb-fsevent (0.11.2)
91
91
  rb-inotify (0.10.1)
92
92
  ffi (~> 1.0)
93
- regexp_parser (2.8.2)
93
+ regexp_parser (2.8.3)
94
94
  rexml (3.2.6)
95
- rspec (3.12.0)
96
- rspec-core (~> 3.12.0)
97
- rspec-expectations (~> 3.12.0)
98
- rspec-mocks (~> 3.12.0)
95
+ rspec (3.13.0)
96
+ rspec-core (~> 3.13.0)
97
+ rspec-expectations (~> 3.13.0)
98
+ rspec-mocks (~> 3.13.0)
99
99
  rspec-collection_matchers (1.2.1)
100
100
  rspec-expectations (>= 2.99.0.beta1)
101
- rspec-core (3.12.2)
102
- rspec-support (~> 3.12.0)
103
- rspec-expectations (3.12.3)
101
+ rspec-core (3.13.0)
102
+ rspec-support (~> 3.13.0)
103
+ rspec-expectations (3.13.0)
104
104
  diff-lcs (>= 1.2.0, < 2.0)
105
- rspec-support (~> 3.12.0)
105
+ rspec-support (~> 3.13.0)
106
106
  rspec-github (2.4.0)
107
107
  rspec-core (~> 3.0)
108
- rspec-mocks (3.12.6)
108
+ rspec-mocks (3.13.0)
109
109
  diff-lcs (>= 1.2.0, < 2.0)
110
- rspec-support (~> 3.12.0)
111
- rspec-support (3.12.1)
112
- rubocop (1.57.1)
113
- base64 (~> 0.1.1)
110
+ rspec-support (~> 3.13.0)
111
+ rspec-support (3.13.0)
112
+ rubocop (1.59.0)
114
113
  json (~> 2.3)
115
114
  language_server-protocol (>= 3.17.0)
116
115
  parallel (~> 1.10)
@@ -118,24 +117,25 @@ GEM
118
117
  rainbow (>= 2.2.2, < 4.0)
119
118
  regexp_parser (>= 1.8, < 3.0)
120
119
  rexml (>= 3.2.5, < 4.0)
121
- rubocop-ast (>= 1.28.1, < 2.0)
120
+ rubocop-ast (>= 1.30.0, < 2.0)
122
121
  ruby-progressbar (~> 1.7)
123
122
  unicode-display_width (>= 2.4.0, < 3.0)
124
- rubocop-ast (1.29.0)
123
+ rubocop-ast (1.30.0)
125
124
  parser (>= 3.2.1.0)
126
125
  rubocop-capybara (2.19.0)
127
126
  rubocop (~> 1.41)
128
127
  rubocop-factory_bot (2.24.0)
129
128
  rubocop (~> 1.33)
130
- rubocop-performance (1.19.1)
131
- rubocop (>= 1.7.0, < 2.0)
132
- rubocop-ast (>= 0.4.0)
133
- rubocop-rails (2.21.2)
129
+ rubocop-performance (1.20.1)
130
+ rubocop (>= 1.48.1, < 2.0)
131
+ rubocop-ast (>= 1.30.0, < 2.0)
132
+ rubocop-rails (2.23.1)
134
133
  activesupport (>= 4.2.0)
135
134
  rack (>= 1.1)
136
135
  rubocop (>= 1.33.0, < 2.0)
137
- rubocop-rspec (2.24.1)
138
- rubocop (~> 1.33)
136
+ rubocop-ast (>= 1.30.0, < 2.0)
137
+ rubocop-rspec (2.25.0)
138
+ rubocop (~> 1.40)
139
139
  rubocop-capybara (~> 2.17)
140
140
  rubocop-factory_bot (~> 2.22)
141
141
  ruby-progressbar (1.13.0)
@@ -148,7 +148,7 @@ GEM
148
148
  simplecov_json_formatter (~> 0.1)
149
149
  simplecov-html (0.12.3)
150
150
  simplecov_json_formatter (0.1.4)
151
- thor (1.2.2)
151
+ thor (1.3.0)
152
152
  tzinfo (2.0.6)
153
153
  concurrent-ruby (~> 1.0)
154
154
  unicode-display_width (2.5.0)
@@ -175,4 +175,4 @@ DEPENDENCIES
175
175
  simplecov
176
176
 
177
177
  BUNDLED WITH
178
- 2.4.18
178
+ 2.5.3
@@ -23,7 +23,7 @@ module ProformaXML
23
23
  if object.is_a? Hash
24
24
  object[name] = value
25
25
  else
26
- object.send("#{name}=", value)
26
+ object.send(:"#{name}=", value)
27
27
  end
28
28
  end
29
29
 
@@ -56,10 +56,10 @@ module ProformaXML
56
56
  end
57
57
 
58
58
  def add_test_configuration(test, test_node)
59
- test_configuration_node = test_node.xpath('xmlns:test-configuration')
59
+ test_configuration_node = test_node.xpath("#{@pro_ns}:test-configuration")
60
60
  test.files = test_files_from_test_configuration(test_configuration_node)
61
61
  test.configuration = extra_configuration_from_test_configuration(test_configuration_node)
62
- meta_data_node = test_node.xpath('xmlns:test-configuration').xpath('xmlns:test-meta-data')
62
+ meta_data_node = test_node.xpath("#{@pro_ns}:test-configuration").xpath("#{@pro_ns}:test-meta-data")
63
63
  test.meta_data = convert_xml_node_to_json(meta_data_node) if meta_data_node.present?
64
64
  end
65
65
 
@@ -75,28 +75,35 @@ module ProformaXML
75
75
  end
76
76
 
77
77
  def test_files_from_test_configuration(test_configuration_node)
78
- files_from_filerefs(test_configuration_node.search('filerefs'))
78
+ files_from_filerefs(test_configuration_node.xpath("#{@pro_ns}:filerefs"))
79
79
  end
80
80
 
81
81
  private
82
82
 
83
83
  def convert_xml_node_to_json(any_node)
84
84
  xml_snippet = Nokogiri::XML::DocumentFragment.new(Nokogiri::XML::Document.new, any_node)
85
- all_namespaces(any_node).each do |namespace|
85
+ all_namespaces_without_default(any_node).each do |namespace|
86
86
  xml_snippet.children.first.add_namespace_definition(namespace[:prefix], namespace[:href])
87
87
  end
88
- JSON.parse(Dachsfisch::XML2JSONConverter.perform(xml: xml_snippet.to_xml))
88
+ xml_without_custom_default_ns = xml_snippet.to_xml.gsub(%r{(</?)#{custom_default_namespace_prefix(any_node)}:}, '\1')
89
+ JSON.parse(Dachsfisch::XML2JSONConverter.perform(xml: xml_without_custom_default_ns))
89
90
  end
90
91
 
91
- def all_namespaces(node)
92
+ def all_namespaces_without_default(node)
92
93
  node.xpath('.|.//*').map(&:namespace).reject do |ns|
93
- ns.prefix.nil?
94
+ ns.prefix.nil? || ns.href.match?(/^urn:proforma:v\d.*$/)
94
95
  end.map {|ns| {prefix: ns.prefix, href: ns.href} }.uniq
95
96
  end
96
97
 
98
+ def custom_default_namespace_prefix(node)
99
+ node.xpath('.|.//*').map(&:namespace).filter do |ns|
100
+ ns.href.match?(/^urn:proforma:v\d.*$/)
101
+ end.map(&:prefix).first
102
+ end
103
+
97
104
  def value_from_node(name, node, attribute)
98
105
  xml_name = name.is_a?(Array) ? name[0] : name
99
- attribute ? node.attribute(xml_name)&.value : node.xpath("xmlns:#{xml_name}").text
106
+ attribute ? node.attribute(xml_name)&.value : node.xpath("#{@pro_ns}:#{xml_name}").text
100
107
  end
101
108
 
102
109
  def content_from_file_tag(file_tag, binary)
@@ -18,12 +18,21 @@ module ProformaXML
18
18
  @task = Task.new
19
19
  end
20
20
 
21
+ def proforma_namespace
22
+ namespace_regex = /^urn:proforma:v\d.*$/
23
+ namespaces = @doc.namespaces.filter do |_, href|
24
+ href.match? namespace_regex
25
+ end
26
+ namespaces.first.first.gsub('xmlns:', '')
27
+ end
28
+
21
29
  def perform
22
30
  errors = validate
23
31
 
24
32
  raise PreImportValidationError.new(errors) if errors.any?
25
33
 
26
- @task_node = @doc.xpath('/xmlns:task')
34
+ @pro_ns = proforma_namespace
35
+ @task_node = @doc.xpath("/#{@pro_ns}:task")
27
36
 
28
37
  set_data
29
38
  @task
@@ -37,11 +46,17 @@ module ProformaXML
37
46
  end
38
47
  end
39
48
 
49
+ def remove_referenced_files
50
+ referenced_files = (@task.tests.map(&:files) + @task.model_solutions.map(&:files)).flatten
51
+ @task.files.reject! {|f| referenced_files.include? f }
52
+ end
53
+
40
54
  def set_data
41
55
  set_base_data
42
56
  set_files
43
57
  set_model_solutions
44
58
  set_tests
59
+ remove_referenced_files
45
60
  set_meta_data
46
61
  set_extra_data
47
62
  end
@@ -57,44 +72,44 @@ module ProformaXML
57
72
  end
58
73
 
59
74
  def set_proglang
60
- return if @task_node.xpath('xmlns:proglang').text.blank?
75
+ return if @task_node.xpath("#{@pro_ns}:proglang").text.blank?
61
76
 
62
- @task.proglang = {name: @task_node.xpath('xmlns:proglang').text,
63
- version: @task_node.xpath('xmlns:proglang').attribute('version').value.presence}.compact
77
+ @task.proglang = {name: @task_node.xpath("#{@pro_ns}:proglang").text,
78
+ version: @task_node.xpath("#{@pro_ns}:proglang").attribute('version').value.presence}.compact
64
79
  end
65
80
 
66
81
  def set_files
67
- @task_node.search('files//file').each {|file_node| add_file file_node }
82
+ @task_node.xpath("#{@pro_ns}:files//#{@pro_ns}:file").each {|file_node| add_file file_node }
68
83
  end
69
84
 
70
85
  def set_tests
71
- @task_node.search('tests//test').each {|test_node| add_test test_node }
86
+ @task_node.xpath("#{@pro_ns}:tests//#{@pro_ns}:test").each {|test_node| add_test test_node }
72
87
  end
73
88
 
74
89
  def set_model_solutions
75
- @task_node.search('model-solutions//model-solution').each do |model_solution_node|
90
+ @task_node.xpath("#{@pro_ns}:model-solutions//#{@pro_ns}:model-solution").each do |model_solution_node|
76
91
  add_model_solution model_solution_node
77
92
  end
78
93
  end
79
94
 
80
95
  def set_meta_data
81
- meta_data_node = @task_node.xpath('xmlns:meta-data').first
96
+ meta_data_node = @task_node.xpath("#{@pro_ns}:meta-data").first
82
97
  @task.meta_data = convert_xml_node_to_json(meta_data_node) if meta_data_node.text.present?
83
98
  end
84
99
 
85
100
  def set_extra_data
86
- submission_restrictions_node = @task_node.xpath('xmlns:submission-restrictions').first
101
+ submission_restrictions_node = @task_node.xpath("#{@pro_ns}:submission-restrictions").first
87
102
  @task.submission_restrictions = convert_xml_node_to_json(submission_restrictions_node) unless submission_restrictions_node.nil?
88
- external_resources_node = @task_node.xpath('xmlns:external-resources').first
103
+ external_resources_node = @task_node.xpath("#{@pro_ns}:external-resources").first
89
104
  @task.external_resources = convert_xml_node_to_json(external_resources_node) unless external_resources_node.nil?
90
- grading_hints_node = @task_node.xpath('xmlns:grading-hints').first
105
+ grading_hints_node = @task_node.xpath("#{@pro_ns}:grading-hints").first
91
106
  @task.grading_hints = convert_xml_node_to_json(grading_hints_node) unless grading_hints_node.nil?
92
107
  end
93
108
 
94
109
  def add_model_solution(model_solution_node)
95
110
  model_solution = ModelSolution.new
96
111
  model_solution.id = model_solution_node.attributes['id'].value
97
- model_solution.files = files_from_filerefs(model_solution_node.search('filerefs'))
112
+ model_solution.files = files_from_filerefs(model_solution_node.xpath("#{@pro_ns}:filerefs"))
98
113
  set_value_from_xml(object: model_solution, node: model_solution_node, name: 'description')
99
114
  set_value_from_xml(object: model_solution, node: model_solution_node, name: 'internal-description')
100
115
  @task.model_solutions << model_solution unless model_solution.files.first&.id == 'ms-placeholder-file'
@@ -125,9 +140,9 @@ module ProformaXML
125
140
 
126
141
  def files_from_filerefs(filerefs_node)
127
142
  [].tap do |files|
128
- filerefs_node.search('fileref').each do |fileref_node|
143
+ filerefs_node.xpath("#{@pro_ns}:fileref").each do |fileref_node|
129
144
  fileref = fileref_node.attributes['refid'].value
130
- files << @task.files.delete(@task.files.detect {|file| file.id == fileref })
145
+ files << @task.files.detect {|file| file.id == fileref }
131
146
  end
132
147
  end
133
148
  end
@@ -14,7 +14,14 @@ module ProformaXML
14
14
  private
15
15
 
16
16
  def doc_schema_version
17
- @doc_schema_version ||= /^urn:proforma:v(.*)$/.match(@doc.namespaces['xmlns'])&.captures&.dig(0)
17
+ namespace_regex = /^urn:proforma:v(\d.*)$/
18
+ potential_namespaces = @doc.namespaces.filter do |_, href|
19
+ href.match? namespace_regex
20
+ end
21
+ return nil unless potential_namespaces.length == 1
22
+
23
+ @pro_ns = potential_namespaces.first[0].gsub('xmlns:', '')
24
+ @doc_schema_version ||= namespace_regex.match(potential_namespaces.first[1])&.captures&.dig(0)
18
25
  end
19
26
 
20
27
  def node_as_doc_with_namespace(config_node)
@@ -38,7 +45,7 @@ module ProformaXML
38
45
  end
39
46
 
40
47
  def validate_test_configuration
41
- @doc.xpath('/xmlns:task/xmlns:tests/xmlns:test/xmlns:test-configuration').flat_map do |test_config|
48
+ @doc.xpath("/#{@pro_ns}:task/#{@pro_ns}:tests/#{@pro_ns}:test/#{@pro_ns}:test-configuration").flat_map do |test_config|
42
49
  test_config.children.flat_map do |config_node|
43
50
  next [] unless config_node.namespace&.href&.start_with?('urn:proforma:tests:')
44
51
  next [] unless TEST_TYPE_SCHEMA_NAMES.include? config_node.name
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProformaXML
4
- VERSION = '1.2.0'
4
+ VERSION = '1.3.0'
5
5
  end
data/proformaxml.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'https://github.com/openHPI/proformaxml'
14
14
  spec.license = 'MIT'
15
15
 
16
- spec.required_ruby_version = '>= 3.2'
16
+ spec.required_ruby_version = '>= 3.3'
17
17
 
18
18
  # Specify which files should be added to the gem when it is released.
19
19
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proformaxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karol
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-25 00:00:00.000000000 Z
11
+ date: 2024-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -160,14 +160,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
160
160
  requirements:
161
161
  - - ">="
162
162
  - !ruby/object:Gem::Version
163
- version: '3.2'
163
+ version: '3.3'
164
164
  required_rubygems_version: !ruby/object:Gem::Requirement
165
165
  requirements:
166
166
  - - ">="
167
167
  - !ruby/object:Gem::Version
168
168
  version: '0'
169
169
  requirements: []
170
- rubygems_version: 3.4.1
170
+ rubygems_version: 3.5.3
171
171
  signing_key:
172
172
  specification_version: 4
173
173
  summary: Implements parts of ProFormA-XML specification