proformaxml 1.4.0 → 1.5.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: 8284cbc28d6d2cabde0247312b5a526ffdb8be758261295757f3b4b132250004
4
- data.tar.gz: 0fa49ec56a760ff164eed881b362bcb4307dcf6d789c9d395e65d67945c9654d
3
+ metadata.gz: a99c650e5288b8e0d9e377a808d4837c2e9f7d54830a52201d03ffc947d25b34
4
+ data.tar.gz: 99088e189b997b80f20d0abe18fa18dc3b113ebfb0db7ecf6b7b1120d811aa33
5
5
  SHA512:
6
- metadata.gz: 16a96f01c9bb5a05008820954da688600b65d01d4733a45204c933d205635977e8e18358b05c20f2d14c898a6fca3b6e005ad84aa20122df8f2f8e3b8471f73e
7
- data.tar.gz: 7b743f6b785d69e549bfb0948e19d90fdec93644aca4ae312c7d27c27c7748def994f1ea11e10084fc061567db47e2b14e2e7a7b026378448d7bcbbdb2a5268b
6
+ metadata.gz: dd7648193e3408806e11c069ebf7c86e14ff456ecf0d7050a6d4c9caf4ed6895e477421c22c23e61ff82ae644c5fb175f15632a443a324fbba50686e5ca9e2b0
7
+ data.tar.gz: 667600bb7fc60f57345d25609fd80f9d5c352a7f21e52672413e7aa9986df8b4b5353db7ad09d446974a3200e459a537e8a75255c1a17f184d544f448786fd7a
@@ -0,0 +1,4 @@
1
+ # factory bot cop settings
2
+
3
+ Naming/VariableNumber:
4
+ EnforcedStyle: snake_case
data/.rubocop/rspec.yml CHANGED
@@ -26,10 +26,6 @@ RSpec/NestedGroups:
26
26
  RSpec/IndexedLet:
27
27
  Max: 2
28
28
 
29
- RSpec/FilePath:
30
- CustomTransform:
31
- ProformaXML: proformaxml
32
-
33
29
  RSpec/SpecFilePathFormat:
34
30
  CustomTransform:
35
31
  ProformaXML: proformaxml
data/.rubocop.yml CHANGED
@@ -3,12 +3,14 @@ require:
3
3
  - rubocop-performance
4
4
  - rubocop-rails
5
5
  - rubocop-rspec
6
+ - rubocop-rspec_rails
6
7
 
7
8
  inherit_from:
8
9
  - .rubocop/factory-bot.yml
9
10
  - .rubocop/layout.yml
10
11
  - .rubocop/lint.yml
11
12
  - .rubocop/metrics.yml
13
+ - .rubocop/naming.yml
12
14
  - .rubocop/rspec.yml
13
15
  - .rubocop/style.yml
14
16
 
data/Gemfile CHANGED
@@ -16,7 +16,9 @@ gem 'rspec'
16
16
  gem 'rspec-collection_matchers'
17
17
  gem 'rspec-github'
18
18
  gem 'rubocop'
19
+ gem 'rubocop-factory_bot'
19
20
  gem 'rubocop-performance'
20
21
  gem 'rubocop-rails'
21
22
  gem 'rubocop-rspec'
23
+ gem 'rubocop-rspec_rails'
22
24
  gem 'simplecov'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- proformaxml (1.4.0)
4
+ proformaxml (1.5.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)
@@ -28,7 +28,7 @@ GEM
28
28
  bigdecimal (3.1.8)
29
29
  byebug (11.1.3)
30
30
  coderay (1.1.3)
31
- concurrent-ruby (1.3.1)
31
+ concurrent-ruby (1.3.3)
32
32
  connection_pool (2.4.1)
33
33
  dachsfisch (1.0.0)
34
34
  nokogiri (>= 1.14.1, < 2.0.0)
@@ -37,7 +37,7 @@ GEM
37
37
  drb (2.2.1)
38
38
  factory_bot (6.4.6)
39
39
  activesupport (>= 5.0.0)
40
- ffi (1.16.3)
40
+ ffi (1.17.0)
41
41
  formatador (1.1.0)
42
42
  guard (2.18.1)
43
43
  formatador (>= 0.2.4)
@@ -63,7 +63,7 @@ GEM
63
63
  lumberjack (1.2.10)
64
64
  method_source (1.1.0)
65
65
  mini_portile2 (2.8.7)
66
- minitest (5.23.1)
66
+ minitest (5.24.1)
67
67
  mutex_m (0.2.0)
68
68
  nenv (0.3.0)
69
69
  nokogiri (1.16.6)
@@ -72,8 +72,8 @@ GEM
72
72
  notiffany (0.1.3)
73
73
  nenv (~> 0.1)
74
74
  shellany (~> 0.0)
75
- parallel (1.24.0)
76
- parser (3.3.1.0)
75
+ parallel (1.25.1)
76
+ parser (3.3.4.0)
77
77
  ast (~> 2.4.1)
78
78
  racc
79
79
  pry (0.14.2)
@@ -83,15 +83,15 @@ GEM
83
83
  byebug (~> 11.0)
84
84
  pry (>= 0.13, < 0.15)
85
85
  racc (1.8.0)
86
- rack (3.0.11)
86
+ rack (3.1.6)
87
87
  rainbow (3.1.1)
88
88
  rake (13.2.1)
89
89
  rb-fsevent (0.11.2)
90
- rb-inotify (0.10.1)
90
+ rb-inotify (0.11.1)
91
91
  ffi (~> 1.0)
92
- regexp_parser (2.9.1)
93
- rexml (3.2.8)
94
- strscan (>= 3.0.9)
92
+ regexp_parser (2.9.2)
93
+ rexml (3.3.2)
94
+ strscan
95
95
  rspec (3.13.0)
96
96
  rspec-core (~> 3.13.0)
97
97
  rspec-expectations (~> 3.13.0)
@@ -100,7 +100,7 @@ GEM
100
100
  rspec-expectations (>= 2.99.0.beta1)
101
101
  rspec-core (3.13.0)
102
102
  rspec-support (~> 3.13.0)
103
- rspec-expectations (3.13.0)
103
+ rspec-expectations (3.13.1)
104
104
  diff-lcs (>= 1.2.0, < 2.0)
105
105
  rspec-support (~> 3.13.0)
106
106
  rspec-github (2.4.0)
@@ -109,38 +109,34 @@ GEM
109
109
  diff-lcs (>= 1.2.0, < 2.0)
110
110
  rspec-support (~> 3.13.0)
111
111
  rspec-support (3.13.1)
112
- rubocop (1.63.5)
112
+ rubocop (1.65.0)
113
113
  json (~> 2.3)
114
114
  language_server-protocol (>= 3.17.0)
115
115
  parallel (~> 1.10)
116
116
  parser (>= 3.3.0.2)
117
117
  rainbow (>= 2.2.2, < 4.0)
118
- regexp_parser (>= 1.8, < 3.0)
118
+ regexp_parser (>= 2.4, < 3.0)
119
119
  rexml (>= 3.2.5, < 4.0)
120
120
  rubocop-ast (>= 1.31.1, < 2.0)
121
121
  ruby-progressbar (~> 1.7)
122
122
  unicode-display_width (>= 2.4.0, < 3.0)
123
123
  rubocop-ast (1.31.3)
124
124
  parser (>= 3.3.1.0)
125
- rubocop-capybara (2.20.0)
126
- rubocop (~> 1.41)
127
- rubocop-factory_bot (2.25.1)
128
- rubocop (~> 1.41)
129
- rubocop-performance (1.21.0)
125
+ rubocop-factory_bot (2.26.1)
126
+ rubocop (~> 1.61)
127
+ rubocop-performance (1.21.1)
130
128
  rubocop (>= 1.48.1, < 2.0)
131
129
  rubocop-ast (>= 1.31.1, < 2.0)
132
- rubocop-rails (2.24.1)
130
+ rubocop-rails (2.25.1)
133
131
  activesupport (>= 4.2.0)
134
132
  rack (>= 1.1)
135
133
  rubocop (>= 1.33.0, < 2.0)
136
134
  rubocop-ast (>= 1.31.1, < 2.0)
137
- rubocop-rspec (2.29.2)
138
- rubocop (~> 1.40)
139
- rubocop-capybara (~> 2.17)
140
- rubocop-factory_bot (~> 2.22)
141
- rubocop-rspec_rails (~> 2.28)
142
- rubocop-rspec_rails (2.28.3)
143
- rubocop (~> 1.40)
135
+ rubocop-rspec (3.0.3)
136
+ rubocop (~> 1.61)
137
+ rubocop-rspec_rails (2.30.0)
138
+ rubocop (~> 1.61)
139
+ rubocop-rspec (~> 3, >= 3.0.1)
144
140
  ruby-progressbar (1.13.0)
145
141
  rubyzip (2.3.2)
146
142
  shellany (0.0.1)
@@ -172,10 +168,12 @@ DEPENDENCIES
172
168
  rspec-collection_matchers
173
169
  rspec-github
174
170
  rubocop
171
+ rubocop-factory_bot
175
172
  rubocop-performance
176
173
  rubocop-rails
177
174
  rubocop-rspec
175
+ rubocop-rspec_rails
178
176
  simplecov
179
177
 
180
178
  BUNDLED WITH
181
- 2.5.11
179
+ 2.5.15
@@ -3,14 +3,17 @@
3
3
  require 'proformaxml/helpers/export_helpers'
4
4
 
5
5
  module ProformaXML
6
- class Exporter
6
+ class Exporter < ServiceBase
7
7
  include ProformaXML::Helpers::ExportHelpers
8
8
 
9
9
  def initialize(task:, version: nil)
10
+ super()
10
11
  @files = {}
11
12
  @task = task
12
13
  @version = version || SCHEMA_VERSIONS.first
13
- add_placeholders if @version == '2.0'
14
+ if @version != SCHEMA_VERSION_LATEST
15
+ ProformaXML::TransformTask.call(task: @task, from_version: SCHEMA_VERSION_LATEST, to_version: @version)
16
+ end
14
17
  end
15
18
 
16
19
  def perform
@@ -49,7 +52,7 @@ module ProformaXML
49
52
  add_dachsfisch_node(xml, @task.submission_restrictions)
50
53
  xml.files { files(xml) }
51
54
  add_dachsfisch_node(xml, @task.external_resources)
52
- xml.send(:'model-solutions') { model_solutions(xml) } if @task.model_solutions.any? || @version == '2.0'
55
+ xml.send(:'model-solutions') { model_solutions(xml) } if @task.model_solutions.any?
53
56
  xml.tests { tests(xml) }
54
57
  add_dachsfisch_node(xml, @task.grading_hints)
55
58
  end
@@ -98,15 +101,6 @@ module ProformaXML
98
101
  end
99
102
  end
100
103
 
101
- # ms-placeholder only necessary for version 2.0 where model-solutions were mandatory
102
- def add_placeholders
103
- return if @task.model_solutions&.any?
104
-
105
- file = TaskFile.new(content: '', id: 'ms-placeholder-file', used_by_grader: false, visible: 'no', binary: false)
106
- model_solution = ModelSolution.new(id: 'ms-placeholder', files: [file])
107
- @task.model_solutions = [model_solution]
108
- end
109
-
110
104
  def headers
111
105
  {
112
106
  'xmlns' => "urn:proforma:v#{@version}",
@@ -117,8 +111,7 @@ module ProformaXML
117
111
  end
118
112
 
119
113
  def validate(doc)
120
- validator = ProformaXML::Validator.new doc, @version
121
- validator.perform
114
+ ProformaXML::Validator.call(doc:, expected_version: @version)
122
115
  end
123
116
 
124
117
  def write_to_zip(xmldoc)
@@ -4,10 +4,11 @@ require 'active_support/core_ext/string'
4
4
  require 'proformaxml/helpers/import_helpers'
5
5
 
6
6
  module ProformaXML
7
- class Importer
7
+ class Importer < ServiceBase
8
8
  include ProformaXML::Helpers::ImportHelpers
9
9
 
10
10
  def initialize(zip:, expected_version: nil)
11
+ super()
11
12
  @zip = zip
12
13
  @expected_version = expected_version
13
14
 
@@ -18,22 +19,19 @@ module ProformaXML
18
19
  @task = Task.new
19
20
  end
20
21
 
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
-
29
22
  def perform
23
+ version_name_extractor = VersionAndNamespaceExtractor.new doc: @doc
24
+ @pro_ns, @doc_schema_version = version_name_extractor.perform&.values_at(:namespace, :version)
25
+
30
26
  errors = validate
31
27
  raise PreImportValidationError.new(errors.map(&:message)) if errors.any?
32
28
 
33
- @pro_ns = proforma_namespace
34
29
  @task_node = @doc.xpath("/#{@pro_ns}:task")
35
30
 
36
31
  set_data
32
+ if @doc_schema_version != SCHEMA_VERSION_LATEST
33
+ ProformaXML::TransformTask.call(task: @task, from_version: @doc_schema_version, to_version: SCHEMA_VERSION_LATEST)
34
+ end
37
35
  @task
38
36
  end
39
37
 
@@ -111,7 +109,7 @@ module ProformaXML
111
109
  model_solution.files = files_from_filerefs(model_solution_node.xpath("#{@pro_ns}:filerefs"))
112
110
  set_value_from_xml(object: model_solution, node: model_solution_node, name: 'description')
113
111
  set_value_from_xml(object: model_solution, node: model_solution_node, name: 'internal-description')
114
- @task.model_solutions << model_solution unless model_solution.files.first&.id == 'ms-placeholder-file'
112
+ @task.model_solutions << model_solution
115
113
  end
116
114
 
117
115
  def add_file(file_node)
@@ -147,8 +145,7 @@ module ProformaXML
147
145
  end
148
146
 
149
147
  def validate
150
- validator = ProformaXML::Validator.new @doc, @expected_version
151
- validator.perform
148
+ ProformaXML::Validator.call(doc: @doc, expected_version: @expected_version)
152
149
  end
153
150
  end
154
151
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ProformaXML
4
+ class ServiceBase
5
+ def self.call(**)
6
+ new(**).perform
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'proformaxml/helpers/export_helpers'
4
+
5
+ module ProformaXML
6
+ class TransformTask < ServiceBase
7
+ def initialize(task:, from_version:, to_version:)
8
+ super()
9
+ @task = task
10
+ @from_version = from_version
11
+ @to_version = to_version
12
+ end
13
+
14
+ def perform
15
+ if SCHEMA_VERSIONS.include?(@from_version) && SCHEMA_VERSIONS.include?(@to_version)
16
+
17
+ method_name = "transform_from_#{@from_version.tr('.', '_')}_to_#{@to_version.tr('.', '_')}"
18
+
19
+ send(method_name) if defined? method_name
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def transform_from_2_0_to_2_1
26
+ if @task.submission_restrictions.present?
27
+ @task.submission_restrictions['submission-restrictions']['file-restriction'].each do |fr|
28
+ fr['@use'] = fr.delete('@required') == 'true' ? 'required' : 'optional'
29
+ end
30
+ end
31
+
32
+ @task.model_solutions.filter! {|model_solution| model_solution.id != 'ms-placeholder' }
33
+ end
34
+
35
+ def transform_from_2_1_to_2_0
36
+ unless @task.submission_restrictions.nil?
37
+ @task.submission_restrictions['submission-restrictions']['file-restriction'].each do |fr|
38
+ fr['@required'] = (fr.delete('@use') == 'required').to_s
39
+ end
40
+ @task.submission_restrictions['submission-restrictions'].delete('description')
41
+ @task.submission_restrictions['submission-restrictions'].delete('internal-description')
42
+ end
43
+ add_model_solution_placeholder
44
+ end
45
+
46
+ def add_model_solution_placeholder
47
+ return if @task.model_solutions&.any?
48
+
49
+ file = TaskFile.new(content: '', id: 'ms-placeholder-file', used_by_grader: false, visible: 'no', binary: false)
50
+ model_solution = ModelSolution.new(id: 'ms-placeholder', files: [file])
51
+ @task.model_solutions = [model_solution]
52
+ end
53
+ end
54
+ end
@@ -1,29 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProformaXML
4
- class Validator
5
- def initialize(doc, expected_version = nil)
4
+ class Validator < ServiceBase
5
+ def initialize(doc:, expected_version: nil)
6
+ super()
6
7
  @doc = doc
7
8
  @expected_version = expected_version
8
9
  end
9
10
 
10
11
  def perform
12
+ version_name_extractor = VersionAndNamespaceExtractor.new doc: @doc
13
+ @pro_ns, @doc_schema_version = version_name_extractor.perform&.values_at(:namespace, :version)
14
+
11
15
  validate
12
16
  end
13
17
 
14
18
  private
15
19
 
16
- def doc_schema_version
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)
25
- end
26
-
27
20
  def node_as_doc_with_namespace(config_node)
28
21
  doc = Nokogiri::XML::Document.new
29
22
  doc.add_child(config_node.dup)
@@ -31,9 +24,9 @@ module ProformaXML
31
24
  end
32
25
 
33
26
  def validate
34
- return ['no proformaxml version found'] if doc_schema_version.nil?
27
+ return ['no proformaxml version found'] if @doc_schema_version.nil?
35
28
 
36
- version = @expected_version || doc_schema_version
29
+ version = @expected_version || @doc_schema_version
37
30
  return ['version not supported'] unless SCHEMA_VERSIONS.include? version
38
31
 
39
32
  # Both validations return an array of errors, which are empty if the validation was successful.
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'proformaxml/helpers/export_helpers'
4
+
5
+ module ProformaXML
6
+ class VersionAndNamespaceExtractor < ServiceBase
7
+ def initialize(doc:)
8
+ super()
9
+ @doc = doc
10
+ end
11
+
12
+ def perform
13
+ extract_schema_and_version
14
+ end
15
+
16
+ private
17
+
18
+ def extract_schema_and_version
19
+ namespace_regex = /^urn:proforma:v(\d.*)$/
20
+ potential_namespaces = @doc.namespaces.filter do |_, href|
21
+ href.match? namespace_regex
22
+ end
23
+ return unless potential_namespaces.length == 1
24
+
25
+ {
26
+ namespace: potential_namespaces.first[0].gsub('xmlns:', ''),
27
+ version: namespace_regex.match(potential_namespaces.first[1])&.captures&.dig(0),
28
+ }
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProformaXML
4
- VERSION = '1.4.0'
4
+ VERSION = '1.5.0'
5
5
  end
data/lib/proformaxml.rb CHANGED
@@ -9,15 +9,19 @@ require 'dachsfisch'
9
9
 
10
10
  require 'proformaxml/version'
11
11
 
12
+ require 'proformaxml/services/service_base'
12
13
  require 'proformaxml/services/importer'
13
14
  require 'proformaxml/services/exporter'
15
+ require 'proformaxml/services/transform_task'
14
16
  require 'proformaxml/services/validator'
17
+ require 'proformaxml/services/version_and_namespace_extractor'
15
18
  require 'proformaxml/models/task'
16
19
 
17
20
  module ProformaXML
18
21
  SCHEMA_PATH = File.join(File.dirname(File.expand_path(__FILE__)), '../assets/schemas')
19
22
  SCHEMA_FORMAT_PATH = "#{SCHEMA_PATH}/proforma-%s.xsd".freeze
20
23
  SCHEMA_VERSIONS = %w[2.1 2.0].freeze
24
+ SCHEMA_VERSION_LATEST = '2.1'
21
25
 
22
26
  TEST_TYPE_SCHEMA_NAMES = %w[java-checkstyle regexptest unittest].freeze
23
27
  MAX_EMBEDDED_FILE_SIZE_KB = 50
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.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karol
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-19 00:00:00.000000000 Z
11
+ date: 2024-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -117,6 +117,7 @@ files:
117
117
  - ".rubocop/layout.yml"
118
118
  - ".rubocop/lint.yml"
119
119
  - ".rubocop/metrics.yml"
120
+ - ".rubocop/naming.yml"
120
121
  - ".rubocop/rails.yml"
121
122
  - ".rubocop/rspec.yml"
122
123
  - ".rubocop/style.yml"
@@ -144,7 +145,10 @@ files:
144
145
  - lib/proformaxml/models/test.rb
145
146
  - lib/proformaxml/services/exporter.rb
146
147
  - lib/proformaxml/services/importer.rb
148
+ - lib/proformaxml/services/service_base.rb
149
+ - lib/proformaxml/services/transform_task.rb
147
150
  - lib/proformaxml/services/validator.rb
151
+ - lib/proformaxml/services/version_and_namespace_extractor.rb
148
152
  - lib/proformaxml/version.rb
149
153
  - proformaxml.gemspec
150
154
  homepage: https://github.com/openHPI/proformaxml
@@ -167,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
171
  - !ruby/object:Gem::Version
168
172
  version: '0'
169
173
  requirements: []
170
- rubygems_version: 3.5.9
174
+ rubygems_version: 3.5.15
171
175
  signing_key:
172
176
  specification_version: 4
173
177
  summary: Implements parts of ProFormA-XML specification