proformaxml 0.10.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2230a680b6a36b22867d4c9749199e5ab0e601567998e343e3281a838867f6c7
4
- data.tar.gz: 9e8486a4ed110915ff0e9ce4b6e4cf87df3ad02c8c0c94c02824ddd8696a56fc
3
+ metadata.gz: 81e1724c3c9498d52025b18b5f3e2830fa10c499bcc9a064470f265d6ed9ba34
4
+ data.tar.gz: 4b7499f6e605ba8dae8ad23e149a06e7e78fa08f91a14f3e8803e70140b02cdc
5
5
  SHA512:
6
- metadata.gz: 20e9ee57cc1071bf2b8612f3397aeed1a98648f0fc363ddb8e3b22251c77e265208b6fbce75c9fe19cafd5a454fcf97d5f8dd90312a7758a2f86c673db9596ea
7
- data.tar.gz: 1c9d253c304209ba0026b766585d851d99e4ea3a626c402d92feb78a245b9ffc7633130ccea1bfe7916315a9118eff54b092b0252c8b88487fccf0547aa70313
6
+ metadata.gz: c47047c96d5fb1c23233c67bd165a6b088e643bc9b6032c8107afd1e32d8d3cb9c4d2342661bd0b5b2b9da38fee368a058dc2fdfa2aabd34889f49c3e9817c21
7
+ data.tar.gz: 18e38170e845ad6e148ce0de1f621e57c3b360a19c7e3a875d8be90e1dfaf94fc085aacdd18ab16d6a587116261426e1f6de6939a351d5fdb0a683e218c7ed1d
@@ -0,0 +1,5 @@
1
+ # factory bot cop settings
2
+
3
+ # We need to define own IDs, since we do not store objects in a database with ActiveRecord.
4
+ FactoryBot/IdSequence:
5
+ Enabled: false
data/.rubocop/rspec.yml CHANGED
@@ -25,3 +25,11 @@ RSpec/NestedGroups:
25
25
 
26
26
  RSpec/IndexedLet:
27
27
  Max: 2
28
+
29
+ RSpec/FilePath:
30
+ CustomTransform:
31
+ ProformaXML: proformaxml
32
+
33
+ RSpec/SpecFilePathFormat:
34
+ CustomTransform:
35
+ ProformaXML: proformaxml
data/.rubocop.yml CHANGED
@@ -5,6 +5,7 @@ require:
5
5
  - rubocop-rspec
6
6
 
7
7
  inherit_from:
8
+ - .rubocop/factory-bot.yml
8
9
  - .rubocop/layout.yml
9
10
  - .rubocop/lint.yml
10
11
  - .rubocop/metrics.yml
@@ -24,7 +25,3 @@ AllCops:
24
25
  - 'tmp/**/*'
25
26
  - 'out/**/*'
26
27
  - 'coverage/**/*'
27
-
28
- RSpec/FilePath:
29
- CustomTransform:
30
- ProformaXML: proformaxml
data/Gemfile CHANGED
@@ -16,7 +16,6 @@ gem 'rspec'
16
16
  gem 'rspec-collection_matchers'
17
17
  gem 'rspec-github'
18
18
  gem 'rubocop'
19
- gem 'rubocop-factory_bot'
20
19
  gem 'rubocop-performance'
21
20
  gem 'rubocop-rails'
22
21
  gem 'rubocop-rspec'
data/Gemfile.lock CHANGED
@@ -1,19 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- proformaxml (0.10.0)
4
+ proformaxml (1.1.0)
5
5
  activemodel (>= 5.2.3, < 8.0.0)
6
6
  activesupport (>= 5.2.3, < 8.0.0)
7
- dachsfisch (>= 0.1.0, < 1.0.0)
7
+ dachsfisch (>= 0.2.0, < 1.0.0)
8
8
  nokogiri (>= 1.10.2, < 2.0.0)
9
9
  rubyzip (>= 1.2.2, < 3.0.0)
10
10
 
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- activemodel (7.0.7.2)
15
- activesupport (= 7.0.7.2)
16
- activesupport (7.0.7.2)
14
+ activemodel (7.0.8)
15
+ activesupport (= 7.0.8)
16
+ activesupport (7.0.8)
17
17
  concurrent-ruby (~> 1.0, >= 1.0.2)
18
18
  i18n (>= 1.6, < 2)
19
19
  minitest (>= 5.1)
@@ -23,15 +23,15 @@ GEM
23
23
  byebug (11.1.3)
24
24
  coderay (1.1.3)
25
25
  concurrent-ruby (1.2.2)
26
- dachsfisch (0.1.0)
26
+ dachsfisch (0.2.0)
27
27
  nokogiri (>= 1.14.1, < 2.0.0)
28
28
  diff-lcs (1.5.0)
29
29
  docile (1.4.0)
30
- factory_bot (6.2.1)
30
+ factory_bot (6.3.0)
31
31
  activesupport (>= 5.0.0)
32
- ffi (1.15.5)
32
+ ffi (1.16.1)
33
33
  formatador (1.1.0)
34
- guard (2.18.0)
34
+ guard (2.18.1)
35
35
  formatador (>= 0.2.4)
36
36
  listen (>= 2.7, < 4.0)
37
37
  lumberjack (>= 1.0.12, < 2.0)
@@ -55,7 +55,7 @@ GEM
55
55
  lumberjack (1.2.9)
56
56
  method_source (1.0.0)
57
57
  mini_portile2 (2.8.4)
58
- minitest (5.19.0)
58
+ minitest (5.20.0)
59
59
  nenv (0.3.0)
60
60
  nokogiri (1.15.4)
61
61
  mini_portile2 (~> 2.8.2)
@@ -86,7 +86,7 @@ GEM
86
86
  rspec-core (~> 3.12.0)
87
87
  rspec-expectations (~> 3.12.0)
88
88
  rspec-mocks (~> 3.12.0)
89
- rspec-collection_matchers (1.2.0)
89
+ rspec-collection_matchers (1.2.1)
90
90
  rspec-expectations (>= 2.99.0.beta1)
91
91
  rspec-core (3.12.2)
92
92
  rspec-support (~> 3.12.0)
@@ -99,7 +99,7 @@ GEM
99
99
  diff-lcs (>= 1.2.0, < 2.0)
100
100
  rspec-support (~> 3.12.0)
101
101
  rspec-support (3.12.1)
102
- rubocop (1.56.1)
102
+ rubocop (1.56.4)
103
103
  base64 (~> 0.1.1)
104
104
  json (~> 2.3)
105
105
  language_server-protocol (>= 3.17.0)
@@ -113,18 +113,18 @@ GEM
113
113
  unicode-display_width (>= 2.4.0, < 3.0)
114
114
  rubocop-ast (1.29.0)
115
115
  parser (>= 3.2.1.0)
116
- rubocop-capybara (2.18.0)
116
+ rubocop-capybara (2.19.0)
117
117
  rubocop (~> 1.41)
118
- rubocop-factory_bot (2.23.1)
118
+ rubocop-factory_bot (2.24.0)
119
119
  rubocop (~> 1.33)
120
- rubocop-performance (1.19.0)
120
+ rubocop-performance (1.19.1)
121
121
  rubocop (>= 1.7.0, < 2.0)
122
122
  rubocop-ast (>= 0.4.0)
123
- rubocop-rails (2.20.2)
123
+ rubocop-rails (2.21.2)
124
124
  activesupport (>= 4.2.0)
125
125
  rack (>= 1.1)
126
126
  rubocop (>= 1.33.0, < 2.0)
127
- rubocop-rspec (2.23.2)
127
+ rubocop-rspec (2.24.1)
128
128
  rubocop (~> 1.33)
129
129
  rubocop-capybara (~> 2.17)
130
130
  rubocop-factory_bot (~> 2.22)
@@ -140,7 +140,7 @@ GEM
140
140
  thor (1.2.2)
141
141
  tzinfo (2.0.6)
142
142
  concurrent-ruby (~> 1.0)
143
- unicode-display_width (2.4.2)
143
+ unicode-display_width (2.5.0)
144
144
 
145
145
  PLATFORMS
146
146
  ruby
@@ -158,7 +158,6 @@ DEPENDENCIES
158
158
  rspec-collection_matchers
159
159
  rspec-github
160
160
  rubocop
161
- rubocop-factory_bot
162
161
  rubocop-performance
163
162
  rubocop-rails
164
163
  rubocop-rspec
@@ -26,54 +26,32 @@ module ProformaXML
26
26
  def add_test_configuration(xml, test)
27
27
  xml.send(:'test-configuration') do
28
28
  add_filerefs(xml, test) if test.files
29
- add_configuration(xml, test.configuration) unless test.configuration.nil?
30
- if test.meta_data
31
- xml.send(:'test-meta-data') do
32
- meta_data(xml, test.meta_data)
33
- end
34
- end
29
+ add_dachsfisch_node(xml, test.configuration)
30
+ add_dachsfisch_node(xml, test.meta_data)
35
31
  end
36
32
  end
37
33
 
38
- def inner_meta_data(xml, namespace, data)
39
- data.each do |key, value|
40
- case value.class.name
41
- when 'Hash'
42
- # underscore is used to disambiguate tag names from ruby methods
43
- xml[namespace].send("#{key}_") do |meta_data_xml|
44
- inner_meta_data(meta_data_xml, namespace, value)
45
- end
46
- else
47
- xml[namespace].send("#{key}_", value)
48
- end
49
- end
50
- end
51
-
52
- def meta_data(xml, meta_data)
53
- meta_data.each do |namespace, data|
54
- inner_meta_data(xml, namespace, data)
55
- end
56
- end
57
-
58
- def add_configuration(xml, configuration)
59
- xml_snippet = Dachsfisch::JSON2XMLConverter.perform(json: configuration.to_json)
60
- configuration.flat_map {|_, val| val['@xmlns'].to_a }.uniq.each do |namespace|
61
- xml.doc.root.add_namespace(namespace[0], namespace[1])
34
+ def add_dachsfisch_node(xml, dachsfisch_node, node_name_fallback = nil)
35
+ if dachsfisch_node.blank?
36
+ xml.send(node_name_fallback, '') if node_name_fallback.present?
37
+ return
62
38
  end
39
+ xml_snippet = Dachsfisch::JSON2XMLConverter.perform(json: dachsfisch_node.to_json)
40
+ add_namespaces_for_dachsfisch_node(dachsfisch_node, xml)
63
41
 
64
42
  xml << xml_snippet
65
43
  end
66
44
 
67
- def add_namespaces_to_header(header, custom_namespaces)
68
- custom_namespaces.each do |namespace|
69
- header["xmlns:#{namespace[:prefix]}"] = namespace[:uri]
70
- end
71
- end
72
-
73
45
  def add_parent_uuid_and_lang_to_header(header)
74
46
  header['lang'] = @task.language if @task.language.present?
75
47
  header['parent-uuid'] = @task.parent_uuid if @task.parent_uuid.present?
76
48
  end
49
+
50
+ def add_namespaces_for_dachsfisch_node(dachsfisch_node, xml)
51
+ dachsfisch_node.flat_map {|_, val| val['@xmlns'].to_a }.uniq.each do |namespace|
52
+ xml.doc.root.add_namespace(namespace[0], namespace[1]) unless namespace[0] == '$'
53
+ end
54
+ end
77
55
  end
78
56
  end
79
57
  end
@@ -60,7 +60,7 @@ module ProformaXML
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
62
  meta_data_node = test_node.xpath('xmlns:test-configuration').xpath('xmlns:test-meta-data')
63
- test.meta_data = meta_data(meta_data_node, use_namespace: true) if meta_data_node.present?
63
+ test.meta_data = convert_xml_node_to_json(meta_data_node) if meta_data_node.present?
64
64
  end
65
65
 
66
66
  def extra_configuration_from_test_configuration(test_configuration_node)
@@ -78,29 +78,22 @@ module ProformaXML
78
78
  files_from_filerefs(test_configuration_node.search('filerefs'))
79
79
  end
80
80
 
81
- def meta_data(any_data_node, use_namespace: false)
82
- # use_namespace forces the use of the namespace as hash key - it should only be used at the entry of the recursion
83
- {}.tap do |any_data|
84
- any_data_node.children.each do |node|
85
- key = (use_namespace ? node.namespace.prefix : any_data_node.name).to_sym
86
- any_data[key] = if node.node_type == Nokogiri::XML::Node::TEXT_NODE
87
- node.text
88
- else
89
- # preserve any existing data in the nested hash
90
- (any_data[key] || {}).merge meta_data(node)
91
- end
92
- end
93
- end
94
- end
95
-
96
81
  private
97
82
 
98
83
  def convert_xml_node_to_json(any_node)
99
84
  xml_snippet = Nokogiri::XML::DocumentFragment.new(Nokogiri::XML::Document.new, any_node)
100
- xml_snippet.children.first.add_namespace_definition(any_node.namespace.prefix, any_node.namespace.href)
85
+ all_namespaces(any_node).each do |namespace|
86
+ xml_snippet.children.first.add_namespace_definition(namespace[:prefix], namespace[:href])
87
+ end
101
88
  JSON.parse(Dachsfisch::XML2JSONConverter.perform(xml: xml_snippet.to_xml))
102
89
  end
103
90
 
91
+ def all_namespaces(node)
92
+ node.xpath('.|.//*').map(&:namespace).reject do |ns|
93
+ ns.prefix.nil?
94
+ end.map {|ns| {prefix: ns.prefix, href: ns.href} }.uniq
95
+ end
96
+
104
97
  def value_from_node(name, node, attribute)
105
98
  xml_name = name.is_a?(Array) ? name[0] : name
106
99
  attribute ? node.attribute(xml_name)&.value : node.xpath("xmlns:#{xml_name}").text
@@ -8,8 +8,8 @@ require 'proformaxml/errors'
8
8
 
9
9
  module ProformaXML
10
10
  class Task < Base
11
- attr_accessor :title, :description, :internal_description, :proglang, :uuid, :parent_uuid,
12
- :language, :model_solutions, :files, :tests, :meta_data
11
+ attr_accessor :title, :description, :internal_description, :proglang, :uuid, :parent_uuid, :language,
12
+ :model_solutions, :files, :tests, :meta_data, :submission_restrictions, :external_resources, :grading_hints
13
13
 
14
14
  def initialize(attributes = {})
15
15
  super
@@ -6,10 +6,9 @@ module ProformaXML
6
6
  class Exporter
7
7
  include ProformaXML::Helpers::ExportHelpers
8
8
 
9
- def initialize(task:, custom_namespaces: [], version: nil)
9
+ def initialize(task:, version: nil)
10
10
  @files = {}
11
11
  @task = task
12
- @custom_namespaces = custom_namespaces
13
12
  @version = version || SCHEMA_VERSIONS.first
14
13
  add_placeholders if @version == '2.0'
15
14
  end
@@ -22,9 +21,9 @@ module ProformaXML
22
21
  doc = Nokogiri::XML(xmldoc)
23
22
  errors = validate(doc)
24
23
 
24
+ # File.binwrite('../testfile.zip', write_to_zip(xmldoc).string)
25
25
  raise PostGenerateValidationError.new(errors) if errors.any?
26
26
 
27
- # File.open('../testfile.zip', 'wb') { |file| file.write(write_to_zip(xmldoc).string) }
28
27
  write_to_zip(xmldoc)
29
28
  end
30
29
 
@@ -38,7 +37,7 @@ module ProformaXML
38
37
  xml.proglang({version: @task.proglang&.dig(:version)}, @task.proglang&.dig(:name))
39
38
 
40
39
  add_objects_to_xml(xml)
41
- add_meta_data(xml)
40
+ add_dachsfisch_node(xml, @task.meta_data, 'meta-data')
42
41
  end
43
42
  end
44
43
 
@@ -46,14 +45,13 @@ module ProformaXML
46
45
  xml.send(:'internal-description', internal_description) if internal_description.present?
47
46
  end
48
47
 
49
- def add_meta_data(xml)
50
- xml.send(:'meta-data') { meta_data(xml, @task.meta_data) }
51
- end
52
-
53
48
  def add_objects_to_xml(xml)
49
+ add_dachsfisch_node(xml, @task.submission_restrictions)
54
50
  xml.files { files(xml) }
51
+ add_dachsfisch_node(xml, @task.external_resources)
55
52
  xml.send(:'model-solutions') { model_solutions(xml) } if @task.model_solutions.any? || @version == '2.0'
56
53
  xml.tests { tests(xml) }
54
+ add_dachsfisch_node(xml, @task.grading_hints)
57
55
  end
58
56
 
59
57
  def files(xml)
@@ -114,7 +112,6 @@ module ProformaXML
114
112
  'xmlns' => "urn:proforma:v#{@version}",
115
113
  'uuid' => @task.uuid,
116
114
  }.tap do |header|
117
- add_namespaces_to_header(header, @custom_namespaces)
118
115
  add_parent_uuid_and_lang_to_header(header)
119
116
  end
120
117
  end
@@ -26,7 +26,7 @@ module ProformaXML
26
26
  @task_node = @doc.xpath('/xmlns:task')
27
27
 
28
28
  set_data
29
- {task: @task, custom_namespaces: @custom_namespaces}
29
+ @task
30
30
  end
31
31
 
32
32
  private
@@ -38,16 +38,12 @@ module ProformaXML
38
38
  end
39
39
 
40
40
  def set_data
41
- set_namespaces
42
41
  set_base_data
43
42
  set_files
44
43
  set_model_solutions
45
44
  set_tests
46
45
  set_meta_data
47
- end
48
-
49
- def set_namespaces
50
- @custom_namespaces = @doc.namespaces.except('xmlns').map {|k, v| {prefix: k[6..], uri: v} }
46
+ set_extra_data
51
47
  end
52
48
 
53
49
  def set_base_data
@@ -82,8 +78,17 @@ module ProformaXML
82
78
  end
83
79
 
84
80
  def set_meta_data
85
- meta_data_node = @task_node.xpath('xmlns:meta-data')
86
- @task.meta_data = meta_data(meta_data_node, use_namespace: true) if meta_data_node.text.present?
81
+ meta_data_node = @task_node.xpath('xmlns:meta-data').first
82
+ @task.meta_data = convert_xml_node_to_json(meta_data_node) if meta_data_node.text.present?
83
+ end
84
+
85
+ def set_extra_data
86
+ submission_restrictions_node = @task_node.xpath('xmlns:submission-restrictions').first
87
+ @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
89
+ @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
91
+ @task.grading_hints = convert_xml_node_to_json(grading_hints_node) unless grading_hints_node.nil?
87
92
  end
88
93
 
89
94
  def add_model_solution(model_solution_node)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProformaXML
4
- VERSION = '0.10.0'
4
+ VERSION = '1.1.0'
5
5
  end
data/proformaxml.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.add_dependency 'activemodel', '>= 5.2.3', '< 8.0.0'
31
31
  spec.add_dependency 'activesupport', '>= 5.2.3', '< 8.0.0'
32
- spec.add_dependency 'dachsfisch', '>= 0.1.0', '< 1.0.0'
32
+ spec.add_dependency 'dachsfisch', '>= 0.2.0', '< 1.0.0'
33
33
  spec.add_dependency 'nokogiri', '>= 1.10.2', '< 2.0.0'
34
34
  spec.add_dependency 'rubyzip', '>= 1.2.2', '< 3.0.0'
35
35
 
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: 0.10.0
4
+ version: 1.1.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-08-22 00:00:00.000000000 Z
11
+ date: 2023-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -56,7 +56,7 @@ dependencies:
56
56
  requirements:
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: 0.1.0
59
+ version: 0.2.0
60
60
  - - "<"
61
61
  - !ruby/object:Gem::Version
62
62
  version: 1.0.0
@@ -66,7 +66,7 @@ dependencies:
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 0.1.0
69
+ version: 0.2.0
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
72
  version: 1.0.0
@@ -119,6 +119,7 @@ extra_rdoc_files: []
119
119
  files:
120
120
  - ".rspec"
121
121
  - ".rubocop.yml"
122
+ - ".rubocop/factory-bot.yml"
122
123
  - ".rubocop/layout.yml"
123
124
  - ".rubocop/lint.yml"
124
125
  - ".rubocop/metrics.yml"
@@ -172,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
173
  - !ruby/object:Gem::Version
173
174
  version: '0'
174
175
  requirements: []
175
- rubygems_version: 3.4.19
176
+ rubygems_version: 3.4.6
176
177
  signing_key:
177
178
  specification_version: 4
178
179
  summary: Implements parts of ProFormA-XML specification