sciolyff 0.9.1 → 0.10.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.
@@ -21,13 +21,13 @@ module SciolyFF
21
21
  @checkers = {}
22
22
  end
23
23
 
24
- def valid?(rep_or_file)
24
+ def valid?(rep_or_yaml)
25
25
  @logger.flush
26
26
 
27
- if rep_or_file.instance_of? String
28
- valid_file?(rep_or_file, @logger)
27
+ if rep_or_yaml.instance_of? String
28
+ valid_yaml?(rep_or_yaml, @logger)
29
29
  else
30
- valid_rep?(rep_or_file, @logger)
30
+ valid_rep?(rep_or_yaml, @logger)
31
31
  end
32
32
  end
33
33
 
@@ -49,14 +49,14 @@ module SciolyFF
49
49
  result
50
50
  end
51
51
 
52
- def valid_file?(path, logger)
53
- rep = YAML.safe_load(
54
- File.read(path),
52
+ def valid_yaml?(yaml, logger)
53
+ rep = Psych.safe_load(
54
+ yaml,
55
55
  permitted_classes: [Date],
56
56
  symbolize_names: true
57
57
  )
58
58
  rescue StandardError => e
59
- logger.error "could not read file as YAML:\n#{e.message}"
59
+ logger.error "could not read input as YAML:\n#{e.message}"
60
60
  else
61
61
  valid_rep?(rep, logger)
62
62
  end
@@ -80,7 +80,7 @@ module SciolyFF
80
80
  end
81
81
 
82
82
  def check(klass, top_level_rep, rep, logger)
83
- @checkers[klass] ||= klass.new top_level_rep
83
+ @checkers[klass] ||= klass.new top_level_rep, logger
84
84
  checks = klass.instance_methods - Checker.instance_methods
85
85
  checks.map { |im| @checkers[klass].send im, rep, logger }.all?
86
86
  end
@@ -6,6 +6,19 @@ module SciolyFF
6
6
  class Validator::Checker
7
7
  def initialize(rep); end
8
8
 
9
+ # Wraps initialize for child classes
10
+ module SafeInitialize
11
+ def initialize(rep, logger)
12
+ super rep
13
+ rescue StandardError => e
14
+ logger.debug "#{e}\n #{e.backtrace.first}"
15
+ end
16
+ end
17
+
18
+ def self.inherited(subclass)
19
+ subclass.prepend SafeInitialize
20
+ end
21
+
9
22
  # wraps method calls (always using send in Validator) so that exceptions
10
23
  # in the check cause check to pass, as what caused the exception should
11
24
  # cause some other check to fail if the SciolyFF is truly invalid
@@ -32,7 +32,7 @@ module SciolyFF
32
32
  end
33
33
 
34
34
  def placings_for_all_teams?(event, logger)
35
- count = @placings[event[:name]].count
35
+ count = @placings[event[:name]]&.count || 0
36
36
  return true if count == @teams
37
37
 
38
38
  logger.error "'event: #{event[:name]}' has incorrect number of "\
@@ -78,6 +78,13 @@ module SciolyFF
78
78
  "#{placing_log(placing)}"
79
79
  end
80
80
 
81
+ def having_a_tie_makes_sense?(placing, logger)
82
+ return true unless placing.key?(:tie) && placing[:raw]
83
+
84
+ logger.error 'having a tie value does make sense for '\
85
+ "#{placing_log(placing)}"
86
+ end
87
+
81
88
  def possible_participated_disqualified_combination?(placing, logger)
82
89
  return true unless placing[:participated] == false &&
83
90
  placing[:disqualified]
@@ -13,6 +13,7 @@ module SciolyFF
13
13
  }.freeze
14
14
 
15
15
  OPTIONAL = {
16
+ 'tier': Integer,
16
17
  'tiebreaker rank': Integer
17
18
  }.freeze
18
19
  end
@@ -4,6 +4,12 @@ module SciolyFF
4
4
  # Generic tests for (sub-)sections and types. Including classes must have two
5
5
  # hashes REQUIRED and OPTIONAL (see other files in this dir for examples)
6
6
  module Validator::Sections
7
+ def rep_is_hash?(rep, logger)
8
+ return true if rep.instance_of? Hash
9
+
10
+ logger.error "entry in #{section_name} is not a Hash"
11
+ end
12
+
7
13
  def all_required_sections?(rep, logger)
8
14
  missing = self.class::REQUIRED.keys - rep.keys
9
15
  return true if missing.empty?
@@ -22,11 +28,25 @@ module SciolyFF
22
28
  correct_types = self.class::REQUIRED.merge self.class::OPTIONAL
23
29
  rep.all? do |key, value|
24
30
  correct = correct_types[key]
25
- next true if (correct.instance_of?(Array) && correct.include?(value)) ||
26
- (value.instance_of? correct)
31
+ next true if
32
+ (correct.instance_of?(Array) && correct.include?(value)) ||
33
+ (correct.instance_of?(Class) && value.instance_of?(correct)) ||
34
+ correct_date?(correct, value)
27
35
 
28
36
  logger.error "#{key}: #{value} is not #{correct}"
29
37
  end
30
38
  end
39
+
40
+ private
41
+
42
+ def correct_date?(correct, value)
43
+ correct == Date && Date.parse(value)
44
+ rescue StandardError
45
+ false
46
+ end
47
+
48
+ def section_name
49
+ self.class.to_s.split('::').last
50
+ end
31
51
  end
32
52
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |s|
4
+ s.authors = ['Em Zhan']
5
+ s.homepage = 'https://github.com/zqianem/sciolyff'
6
+ s.files = `git ls-files -z`.split("\x0").reject do |f|
7
+ f.start_with? 'examples/', '.'
8
+ end
9
+ s.license = 'MIT'
10
+ s.name = 'sciolyff'
11
+ s.summary = 'A file format for Science Olympiad tournament results.'
12
+ s.version = '0.10.0'
13
+ s.executables << 'sciolyff'
14
+ s.add_runtime_dependency 'erubi', '~> 1.9'
15
+ s.add_runtime_dependency 'optimist', '~> 3.0'
16
+ s.add_runtime_dependency 'psych', '~> 3.1'
17
+ s.required_ruby_version = '>= 2.5'
18
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sciolyff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Em Zhan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-08 00:00:00.000000000 Z
11
+ date: 2020-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: erubi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: optimist
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -25,19 +39,19 @@ dependencies:
25
39
  - !ruby/object:Gem::Version
26
40
  version: '3.0'
27
41
  - !ruby/object:Gem::Dependency
28
- name: rake
42
+ name: psych
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '12.3'
34
- type: :development
47
+ version: '3.1'
48
+ type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '12.3'
54
+ version: '3.1'
41
55
  description:
42
56
  email:
43
57
  executables:
@@ -45,6 +59,8 @@ executables:
45
59
  extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
62
+ - LICENSE
63
+ - README.md
48
64
  - bin/sciolyff
49
65
  - lib/sciolyff.rb
50
66
  - lib/sciolyff/interpreter.rb
@@ -71,6 +87,7 @@ files:
71
87
  - lib/sciolyff/validator/teams.rb
72
88
  - lib/sciolyff/validator/top_level.rb
73
89
  - lib/sciolyff/validator/tournament.rb
90
+ - sciolyff.gemspec
74
91
  homepage: https://github.com/zqianem/sciolyff
75
92
  licenses:
76
93
  - MIT
@@ -83,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
83
100
  requirements:
84
101
  - - ">="
85
102
  - !ruby/object:Gem::Version
86
- version: 2.6.0
103
+ version: '2.5'
87
104
  required_rubygems_version: !ruby/object:Gem::Requirement
88
105
  requirements:
89
106
  - - ">="