anodator 1.0.0.pre1 → 1.0.0.pre2
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 +5 -5
- data/.codeclimate.yml +3 -0
- data/.gitignore +3 -0
- data/.travis.yml +11 -0
- data/Gemfile +2 -2
- data/README.md +9 -4
- data/Rakefile +3 -3
- data/anodator.gemspec +17 -14
- data/bin/console +3 -3
- data/bin/console-on-docker +4 -0
- data/bin/docker-console +2 -0
- data/bin/docker-prompt +2 -0
- data/bin/prompt-on-docker +4 -0
- data/bin/setup +0 -0
- data/example/example_01.rb +88 -61
- data/lib/anodator.rb +3 -2
- data/lib/anodator/anodator_error.rb +1 -1
- data/lib/anodator/check_result.rb +7 -7
- data/lib/anodator/checker.rb +33 -26
- data/lib/anodator/common.rb +15 -0
- data/lib/anodator/data_source.rb +87 -0
- data/lib/anodator/data_source_set.rb +36 -0
- data/lib/anodator/input_spec.rb +105 -111
- data/lib/anodator/input_spec_item.rb +8 -8
- data/lib/anodator/message.rb +14 -14
- data/lib/anodator/output_spec.rb +40 -43
- data/lib/anodator/rule.rb +26 -32
- data/lib/anodator/rule_set.rb +6 -12
- data/lib/anodator/utils.rb +36 -42
- data/lib/anodator/validator.rb +9 -9
- data/lib/anodator/validator/base.rb +44 -27
- data/lib/anodator/validator/blank_validator.rb +2 -2
- data/lib/anodator/validator/complex_validator.rb +12 -12
- data/lib/anodator/validator/configuration_error.rb +1 -2
- data/lib/anodator/validator/date_validator.rb +93 -103
- data/lib/anodator/validator/format_validator.rb +8 -11
- data/lib/anodator/validator/inclusion_validator.rb +3 -3
- data/lib/anodator/validator/length_validator.rb +6 -6
- data/lib/anodator/validator/numeric_validator.rb +13 -13
- data/lib/anodator/validator/presence_validator.rb +2 -2
- data/lib/anodator/validator/value_proxy.rb +31 -9
- data/lib/anodator/version.rb +1 -1
- metadata +41 -6
- data/VERSION +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 88afc8c4be0245be213736ca03962c8a295078d39ebf01dd2259c23ab983fed9
|
4
|
+
data.tar.gz: 5217365791c9662f20702edbafdd28aa87e0323768c2de80e5e2102a27862e71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b51714773f6cbee5555583cb194ff67d99313b4b8ec6d5ca1cf02cd7ab26872d5a779c1f724d9247d8ae971853ad4986a9cab15d05d19a9648c6ed6237804e1
|
7
|
+
data.tar.gz: e930643140e7a022c97de0202fb3c6c0381c160802661f1fce16882677906a2478209475331be94a40dfe33826ebe38cafd484daef50ce3a9921c846028c0367
|
data/.codeclimate.yml
ADDED
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
sudo: false
|
2
|
+
env:
|
3
|
+
global:
|
4
|
+
- CC_TEST_REPORTER_ID=4f3ec44c8cb12d2b87fd85a92e04928698ce5eb8b8cb9f8802cf7bea4160b690
|
2
5
|
language: ruby
|
3
6
|
rvm:
|
7
|
+
- 2.4.0
|
8
|
+
- 2.4.1
|
4
9
|
- 2.4.2
|
5
10
|
before_install: gem install bundler -v 1.15.4
|
11
|
+
before_script:
|
12
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
13
|
+
- chmod +x ./cc-test-reporter
|
14
|
+
- ./cc-test-reporter before-build
|
15
|
+
after_script:
|
16
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in anodator.gemspec
|
6
6
|
gemspec
|
data/README.md
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# Anodator
|
2
2
|
|
3
|
-
|
3
|
+
[](https://badge.fury.io/rb/anodator)
|
4
|
+
|
5
|
+
[](https://beta.gemnasium.com/projects/github.com/maki-tetsu/anodator)
|
6
|
+
[](https://travis-ci.org/maki-tetsu/anodator)
|
7
|
+
[](https://codeclimate.com/github/maki-tetsu/anodator/maintainability)
|
8
|
+
[](https://codeclimate.com/github/maki-tetsu/anodator/test_coverage)
|
4
9
|
|
5
|
-
|
10
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/anodator`. To experiment with that code, run `bin/console` for an interactive prompt.
|
6
11
|
|
7
12
|
## Installation
|
8
13
|
|
@@ -18,7 +23,7 @@ And then execute:
|
|
18
23
|
|
19
24
|
Or install it yourself as:
|
20
25
|
|
21
|
-
$ gem install anodator
|
26
|
+
$ gem install anodator -v=1.0.0.pre2
|
22
27
|
|
23
28
|
## Usage
|
24
29
|
|
@@ -32,7 +37,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
37
|
|
33
38
|
## Contributing
|
34
39
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
40
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/maki-tetus/anodator.
|
36
41
|
|
37
42
|
## License
|
38
43
|
|
data/Rakefile
CHANGED
data/anodator.gemspec
CHANGED
@@ -1,26 +1,29 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path("../lib", __FILE__)
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require 'anodator/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'anodator'
|
8
7
|
spec.version = Anodator::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
8
|
+
spec.authors = ['Tetsuhisa MAKINO']
|
9
|
+
spec.email = ['tim.makino at gmail.com']
|
11
10
|
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
11
|
+
spec.summary = 'anodator is Anonymous Data Validator.'
|
12
|
+
spec.homepage = 'https://github.com/maki-tetsu/anodator'
|
13
|
+
spec.license = 'MIT'
|
15
14
|
|
16
15
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
16
|
f.match(%r{^(test|spec|features)/})
|
18
17
|
end
|
19
|
-
spec.bindir =
|
18
|
+
spec.bindir = 'exe'
|
20
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
-
spec.require_paths = [
|
20
|
+
spec.require_paths = ['lib']
|
22
21
|
|
23
|
-
spec.
|
24
|
-
|
25
|
-
spec.add_development_dependency
|
22
|
+
spec.required_ruby_version = '~> 2.4'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.15'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
spec.add_development_dependency 'rubocop'
|
28
|
+
spec.add_development_dependency 'simplecov'
|
26
29
|
end
|
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'anodator'
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require "anodator"
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require 'irb'
|
14
14
|
IRB.start(__FILE__)
|
data/bin/docker-console
ADDED
data/bin/docker-prompt
ADDED
data/bin/setup
CHANGED
File without changes
|
data/example/example_01.rb
CHANGED
@@ -1,43 +1,44 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
# Simple check example by anodator
|
2
|
+
lib = File.expand_path('../../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
4
|
|
4
|
-
require
|
5
|
+
require 'anodator'
|
5
6
|
include Anodator
|
6
7
|
|
7
8
|
### target data columns
|
8
|
-
# ID, Family name, First name, Sex, Phone number, Birthday, Blood type, Regist date
|
9
|
+
# ID, Family name, First name, Sex, Phone number, Birthday, Blood type, Regist date, Score
|
9
10
|
input_spec_array_definition =
|
10
11
|
[
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
{ number: '1', name: 'ID' },
|
13
|
+
{ number: '2', name: 'Family name' },
|
14
|
+
{ number: '3', name: 'First name' },
|
15
|
+
{ number: '4', name: 'Sex' },
|
16
|
+
{ number: '5', name: 'Phone number' },
|
17
|
+
{ number: '6', name: 'Birthday' },
|
18
|
+
{ number: '7', name: 'Blood type' },
|
19
|
+
{ number: '8', name: 'Regist date' },
|
20
|
+
{ number: '9', name: 'Score' }
|
19
21
|
]
|
20
22
|
input_spec = InputSpec.new(input_spec_array_definition)
|
21
23
|
|
22
|
-
|
23
24
|
### check rules
|
24
25
|
rule_set = RuleSet.new
|
25
26
|
## ID
|
26
27
|
# ID must be integer number
|
27
|
-
validator = Validator::NumericValidator.new(
|
28
|
-
rule_set << Rule.new(
|
28
|
+
validator = Validator::NumericValidator.new('1', only_integer: true)
|
29
|
+
rule_set << Rule.new('1', Message.new('[[1::name]] must be integer number.([[1::value]])'), validator)
|
29
30
|
|
30
31
|
## Family name
|
31
32
|
# Family name must not be blank
|
32
33
|
# Family name length must be 2..20
|
33
34
|
# Family name must be include a-z or A-Z and "'"
|
34
35
|
validators = []
|
35
|
-
validators << Validator::PresenceValidator.new(
|
36
|
-
validators << Validator::LengthValidator.new(
|
37
|
-
validators << Validator::FormatValidator.new(
|
38
|
-
validator = Validator::ComplexValidator.new(:
|
39
|
-
:
|
40
|
-
rule_set << Rule.new(
|
36
|
+
validators << Validator::PresenceValidator.new('2')
|
37
|
+
validators << Validator::LengthValidator.new('2', in: 2..20)
|
38
|
+
validators << Validator::FormatValidator.new('2', format: /^[a-z']+$/i)
|
39
|
+
validator = Validator::ComplexValidator.new(validators: validators,
|
40
|
+
logic: Validator::ComplexValidator::LOGIC_AND)
|
41
|
+
rule_set << Rule.new('2',
|
41
42
|
Message.new("[[2::name]] must be alphabets or \"'\", maximum length 20 and cannot be blank.([[2::value]])"),
|
42
43
|
validator)
|
43
44
|
|
@@ -46,91 +47,117 @@ rule_set << Rule.new("2",
|
|
46
47
|
# Family name length must be 2..20
|
47
48
|
# Family name must be include a-z or A-Z and "'"
|
48
49
|
validators = []
|
49
|
-
validators << Validator::PresenceValidator.new(
|
50
|
-
validators << Validator::LengthValidator.new(
|
51
|
-
validators << Validator::FormatValidator.new(
|
52
|
-
validator = Validator::ComplexValidator.new(:
|
53
|
-
:
|
54
|
-
rule_set << Rule.new(
|
50
|
+
validators << Validator::PresenceValidator.new('3')
|
51
|
+
validators << Validator::LengthValidator.new('3', in: 2..20)
|
52
|
+
validators << Validator::FormatValidator.new('3', format: /^[a-z']+$/i)
|
53
|
+
validator = Validator::ComplexValidator.new(validators: validators,
|
54
|
+
logic: Validator::ComplexValidator::LOGIC_AND)
|
55
|
+
rule_set << Rule.new('3',
|
55
56
|
Message.new("[[3::name]] must be alphabets or \"'\", maximum length 20 and cannot be blank.([[3::value]])"),
|
56
57
|
validator)
|
57
58
|
|
58
59
|
## Sex
|
59
60
|
# Sex is 'M' or 'F'
|
60
|
-
validator = Validator::InclusionValidator.new(
|
61
|
-
rule_set << Rule.new(
|
61
|
+
validator = Validator::InclusionValidator.new('4', in: %w[M F])
|
62
|
+
rule_set << Rule.new('4',
|
62
63
|
Message.new("[[4::name]] must be 'M' or 'F'.([[4::value]])"),
|
63
64
|
validator)
|
65
|
+
valid_sex = validator
|
64
66
|
|
65
67
|
## Phone number
|
66
68
|
# Phone number is only number
|
67
69
|
# Phone number length must be maximum 12
|
68
70
|
validators = []
|
69
|
-
validators << Validator::LengthValidator.new(
|
70
|
-
validators << Validator::FormatValidator.new(
|
71
|
-
validator = Validator::ComplexValidator.new(:
|
72
|
-
:
|
73
|
-
rule_set << Rule.new(
|
74
|
-
Message.new(
|
71
|
+
validators << Validator::LengthValidator.new('5', maximum: 12, allow_blank: true)
|
72
|
+
validators << Validator::FormatValidator.new('5', format: /^[0-9]+$/, allow_blank: true)
|
73
|
+
validator = Validator::ComplexValidator.new(validators: validators,
|
74
|
+
logic: Validator::ComplexValidator::LOGIC_AND)
|
75
|
+
rule_set << Rule.new('5',
|
76
|
+
Message.new('[[5::name]] must be include only integer number and mixumum length is 12.([[5::value]])'),
|
75
77
|
validator)
|
76
78
|
|
77
79
|
## Birthday
|
78
80
|
# Birthday must be YYYY-MM-DD format
|
79
|
-
validator = Validator::DateValidator.new(
|
80
|
-
rule_set << Rule.new(
|
81
|
-
Message.new(
|
81
|
+
validator = Validator::DateValidator.new('6')
|
82
|
+
rule_set << Rule.new('6',
|
83
|
+
Message.new('[[6::name]] must be date expression.([[6::value]])'),
|
82
84
|
validator)
|
83
85
|
|
84
86
|
## Blood type
|
85
87
|
# Blood type must be include 'A', 'B', 'O' or 'AB'
|
86
|
-
validator = Validator::InclusionValidator.new(
|
87
|
-
rule_set << Rule.new(
|
88
|
+
validator = Validator::InclusionValidator.new('7', in: %w[A B O AB])
|
89
|
+
rule_set << Rule.new('7',
|
88
90
|
Message.new("[[7::name]] must be 'A', 'B', 'O' or 'AB'.(([[7::value]]))"),
|
89
91
|
validator)
|
90
92
|
|
91
93
|
## Regist date
|
92
94
|
# Regist date must be YYYY-MM-DD format
|
93
|
-
validator = Validator::DateValidator.new(
|
94
|
-
rule_set << Rule.new(
|
95
|
-
Message.new(
|
95
|
+
validator = Validator::DateValidator.new('8')
|
96
|
+
rule_set << Rule.new('8',
|
97
|
+
Message.new('[[8::name]] must be date expression.([[8::value]])'),
|
96
98
|
validator)
|
97
99
|
|
98
100
|
## Complex rule
|
99
101
|
# Birthday < Regist date
|
100
|
-
validator = Validator::DateValidator.new(
|
101
|
-
rule_set << Rule.new(
|
102
|
-
Message.new(
|
102
|
+
validator = Validator::DateValidator.new('6', to: '[[8]]')
|
103
|
+
rule_set << Rule.new('6',
|
104
|
+
Message.new('[[6::name]] must be less than [[8::name]].([[6::value]] < [[8::value]])'),
|
103
105
|
validator)
|
104
106
|
|
107
|
+
## Score
|
108
|
+
validator = Validator::NumericValidator.new('9',
|
109
|
+
only_integer: true,
|
110
|
+
greater_than_or_equal_to: '{{scores:[[4]]:min}}',
|
111
|
+
less_than_or_equal_to: '{{scores:[[4]]:max}}')
|
112
|
+
rule_set << Rule.new('9',
|
113
|
+
Message.new('[[9::name]] must be greater than or equal to configuration score'),
|
114
|
+
validator, valid_sex)
|
115
|
+
|
105
116
|
### output spec
|
106
117
|
## error list
|
107
118
|
items =
|
108
119
|
[
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
120
|
+
'1',
|
121
|
+
:target_numbers,
|
122
|
+
:error_message,
|
123
|
+
:error_level
|
113
124
|
]
|
114
125
|
output_spec = OutputSpec.new(items,
|
115
|
-
:
|
116
|
-
:
|
126
|
+
target: OutputSpec::TARGET_ERROR,
|
127
|
+
include_no_error: false)
|
117
128
|
|
118
129
|
### Checker
|
119
130
|
checker = Checker.new(input_spec, rule_set, output_spec)
|
120
131
|
|
132
|
+
### DataSource
|
133
|
+
data_source_values = {
|
134
|
+
M: {
|
135
|
+
max: 90,
|
136
|
+
min: 65
|
137
|
+
},
|
138
|
+
F: {
|
139
|
+
max: 95,
|
140
|
+
min: 70
|
141
|
+
}
|
142
|
+
}
|
143
|
+
ds = DataSource.new('scores', data_source_values)
|
144
|
+
checker.add_data_source(ds)
|
145
|
+
|
146
|
+
puts checker.rule_info
|
147
|
+
|
121
148
|
### target datas
|
122
149
|
datas =
|
123
150
|
[
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
151
|
+
['1', 'Murayama', 'Honoka', 'F', '08050967141', '1971-10-01', 'B', '2014-12-31', '96'],
|
152
|
+
['2', 'Izawa', 'Kazuma', 'M', '09070028635', '1968-03-24', 'O', '2014-12-31', '91'],
|
153
|
+
['3', 'Hasebe', 'Miyu', 'F', '08087224562', '1991-01-21', 'A', '2014-12-31', '95'],
|
154
|
+
['4', 'Furusawa', 'Eri', 'F', '08017372898', '1965-02-14', 'O', '2014-12-31', '70'],
|
155
|
+
['5', 'Hiramoto', 'Yutaka', 'M', '', '1986-09-14', 'AB', '2014-12-31', '90'],
|
156
|
+
['6', 'Matsuzaki', 'Runa', 'F', '', '1960-03-27', 'O', '2014-12-31', '69'],
|
157
|
+
['7', 'Inagaki', 'Kouichi', 'M', '', '1961-01-04', 'B', '2014-12-31', '65'],
|
158
|
+
['8', 'Kase', 'Sueji', '', '', '1969-03-19', 'B', '2014-12-31', '92'],
|
159
|
+
['9', 'Kawanishi', 'Hinako', 'F', '08029628506', '1970-05-29', 'B', '2014-12-31', '92'],
|
160
|
+
['10', 'Sakurai', 'Eijirou', 'M', '', '2015-01-01', 'A', '2014-12-31', '64']
|
134
161
|
]
|
135
162
|
|
136
163
|
### run check for all datas
|
data/lib/anodator.rb
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'anodator/version'
|
2
|
+
require 'anodator/common'
|
3
|
+
require 'anodator/checker'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'anodator/rule'
|
2
2
|
|
3
3
|
module Anodator
|
4
4
|
class CheckResult
|
@@ -10,25 +10,25 @@ module Anodator
|
|
10
10
|
@level = level
|
11
11
|
|
12
12
|
if @target_numbers.size.zero?
|
13
|
-
raise ArgumentError
|
13
|
+
raise ArgumentError, 'target numbers cannot be blank'
|
14
14
|
end
|
15
15
|
if @message.split(//).size.zero?
|
16
|
-
raise ArgumentError
|
16
|
+
raise ArgumentError, 'message cannot be blank'
|
17
17
|
end
|
18
18
|
unless Rule::ERROR_LEVELS.values.include?(level)
|
19
|
-
raise ArgumentError
|
19
|
+
raise ArgumentError, "level must be #{Rule::ERROR_LEVEL_NAMES.join(', ')}"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def to_s
|
24
24
|
buf = "[#{Rule.level_expression(@level)}]\t"
|
25
|
-
buf += @message + " |#{@target_numbers.join(
|
25
|
+
buf += @message + " |#{@target_numbers.join(', ')}|"
|
26
26
|
end
|
27
27
|
|
28
28
|
def method_missing(message, *args)
|
29
29
|
if message.to_s =~ /(\A[a-zA-Z_]+)\?\Z/
|
30
|
-
if Rule::ERROR_LEVELS.keys.include?(
|
31
|
-
return Rule::ERROR_LEVELS[
|
30
|
+
if Rule::ERROR_LEVELS.keys.include?(Regexp.last_match(1).to_sym)
|
31
|
+
return Rule::ERROR_LEVELS[Regexp.last_match(1).to_sym] == @level
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|