kwalify 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+
2
+ all:
3
+ kwalify -f address-book.schema.yaml address-book.yaml
4
+
@@ -0,0 +1,43 @@
1
+ ##
2
+ ## Kwalify schema example for address book
3
+ ##
4
+ ## $Release: 0.1.0 $
5
+ ## copyright(c) 2005 kuwata-lab all rights reserved.
6
+ ##
7
+ ##
8
+ ## NOTE: 'type: string' is omitted in this example because 'string' is default type.
9
+ ##
10
+
11
+ type: seq
12
+ required: yes
13
+ sequence:
14
+ - type: map
15
+ required: yes
16
+ mapping:
17
+ "name":
18
+ #type: string
19
+ required: yes
20
+ "email":
21
+ #type: string
22
+ pattern: /@/
23
+ "tel":
24
+ #type: string
25
+ pattern: /^\d+-\d+-\d+$/
26
+ "birth":
27
+ type: date
28
+ "age":
29
+ type: integer
30
+ "zip":
31
+ #type: string
32
+ pattern: /^\d+-\d+$/
33
+ "addr":
34
+ #type: string
35
+ "blood":
36
+ #type: string
37
+ enum:
38
+ - A
39
+ - B
40
+ - O
41
+ - AB
42
+ "memo":
43
+ type: object
@@ -0,0 +1,36 @@
1
+ ##
2
+ ## address book example
3
+ ##
4
+
5
+ - name: Sumire
6
+ email: amethyst@mail.com
7
+ tel: 012-111-1111
8
+ birth: 1985-01-01
9
+ age: 20
10
+ zip: 123-4567
11
+ addr: xxxx xxxx xxxx
12
+ blood: B
13
+ memo: My friend
14
+
15
+ - name: Kasumi
16
+ email: mist@mail.net
17
+ tel: 012-222-2222
18
+ birth: 1980-02-02
19
+ age: 25
20
+ blood: AB
21
+ memo:
22
+ - Home tutor
23
+ - A doctor (university)
24
+
25
+ - name: Nana
26
+ email: seven@mail.com
27
+ tel: 012-333-3333
28
+ birth: 1990-03-03
29
+ age: 15
30
+ blood: O
31
+ memo: My sister
32
+
33
+ - name: Sizuka
34
+ email: quiet@mail.org
35
+ memo: Firend of Sumire
36
+
@@ -0,0 +1,3 @@
1
+ all:
2
+ kwalify -f invoice.schema.yaml invoice.yaml
3
+
@@ -0,0 +1,59 @@
1
+ ###
2
+ ### Kwalify schema example for invoice
3
+ ###
4
+ ### $Rev$
5
+ ### $Release: 0.1.0 $
6
+ ### copyright(c) 2005 kuwata-lab all rights reserved.
7
+ ###
8
+
9
+ type: map
10
+ required: yes
11
+ mapping:
12
+ "invoice":
13
+ type: integer
14
+ required: yes
15
+ "date":
16
+ type: date
17
+ required: yes
18
+ "bill-to": &customer
19
+ type: map
20
+ required: yes
21
+ mapping:
22
+ "given":
23
+ required: yes
24
+ "family":
25
+ required: yes
26
+ "address":
27
+ type: map
28
+ required: yes
29
+ mapping:
30
+ "lines":
31
+ "city":
32
+ "state":
33
+ "postal":
34
+ type: integer
35
+ "ship-to": *customer
36
+ "product":
37
+ type: seq
38
+ required: yes
39
+ sequence:
40
+ - type: map
41
+ required: yes
42
+ mapping:
43
+ "sku":
44
+ required: yes
45
+ pattern: /^[A-Z0-9]+$/
46
+ "quantity":
47
+ type: integer
48
+ required: yes
49
+ "description":
50
+ "price":
51
+ type: float
52
+ "tax":
53
+ type: float
54
+ "total":
55
+ type: float
56
+ required: yes
57
+ "comments":
58
+ type: text
59
+
@@ -0,0 +1,32 @@
1
+ ##
2
+ ## from http://www.yaml.org/start.html
3
+ ##
4
+ --- !clarkevans.com/^invoice
5
+ invoice: 34843
6
+ date : 2001-01-23
7
+ bill-to: &id001
8
+ given : Chris
9
+ family : Dumars
10
+ address:
11
+ lines: |
12
+ 458 Walkman Dr.
13
+ Suite #292
14
+ city : Royal Oak
15
+ state : MI
16
+ postal : 48046
17
+ ship-to: *id001
18
+ product:
19
+ - sku : BL394D
20
+ quantity : 4
21
+ description : Basketball
22
+ price : 450.00
23
+ - sku : BL4438H
24
+ quantity : 1
25
+ description : Super Hoop
26
+ price : 2392.00
27
+ tax : 251.42
28
+ total: 4443.52
29
+ comments: >
30
+ Late afternoon is best.
31
+ Backup contact is Nancy
32
+ Billsmer @ 338-4338.
@@ -0,0 +1,10 @@
1
+ ###
2
+ ### $Rev: 5 $
3
+ ### $Release: 0.1.0 $
4
+ ### copyright(c) 2005 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ require 'kwalify/types'
8
+ require 'kwalify/error-msg'
9
+ require 'kwalify/errors'
10
+ require 'kwalify/validator'
@@ -0,0 +1,41 @@
1
+ ###
2
+ ### $Rev: 8 $
3
+ ### $Release: 0.1.0 $
4
+ ### copyright(c) 2005 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ module Kwalify
8
+
9
+ ERROR_MESSAGES = {}
10
+
11
+ ## validation error
12
+ ERROR_MESSAGES[:missing_value] = "value required but not found."
13
+ ERROR_MESSAGES[:invalid_type] = "%s type expected but got %s."
14
+ ERROR_MESSAGES[:invalid_enum] = "'%s' is invalid enum value."
15
+ ERROR_MESSAGES[:invalid_pattern] = "'%s' is not matched to pattern %s."
16
+ ERROR_MESSAGES[:missing_key] = "key '%s' required but not found."
17
+ ERROR_MESSAGES[:invalid_key] = "key '%s' is not expected."
18
+
19
+ ## ruleset error
20
+ ERROR_MESSAGES[:ruleset_not_hash] = "ruleset is not a hash."
21
+ ERROR_MESSAGES[:type_not_found] = "type '%s' is not found."
22
+ ERROR_MESSAGES[:required_not_boolean] = "'required:' is not 'true' nor 'false'."
23
+ ERROR_MESSAGES[:regexp_error] = "'pattern:' has regexp error (= %s)."
24
+ ERROR_MESSAGES[:enum_not_seq] = "'enum:' is not a sequence."
25
+ ERROR_MESSAGES[:sequence_not_seq] = "'sequence:' should be a sequence."
26
+ ERROR_MESSAGES[:sequence_no_elem] = "'sequence:' requires one element."
27
+ ERROR_MESSAGES[:sequence_too_many] = "'sequence:' requires just one element."
28
+ ERROR_MESSAGES[:mapping_not_map] = "'mapping:' should be a mapping."
29
+ ERROR_MESSAGES[:mapping_no_elem] = "'mapping:' requires at least one element."
30
+ ERROR_MESSAGES[:duplicate_key] = "key '%s' is duplicated."
31
+ ERROR_MESSAGES[:unexpected_key] = "'%s' is not expected."
32
+ ERROR_MESSAGES[:seq_has_enum] = "'enum:' is not available with sequence type."
33
+ ERROR_MESSAGES[:seq_has_pattern] = "'pattern:' is not available with sequence type."
34
+ ERROR_MESSAGES[:seq_has_mapping] = "'mapping:' is not available with sequence type."
35
+ ERROR_MESSAGES[:map_has_enum] = "'enum:' is not available with mapping type."
36
+ ERROR_MESSAGES[:map_has_pattern] = "'pattern:' is not available with mapping type."
37
+ ERROR_MESSAGES[:map_has_sequence] = "'sequence:' is not available with mapping type."
38
+ ERROR_MESSAGES[:scalar_has_sequence] = "scalar cannot take 'sequence:'."
39
+ ERROR_MESSAGES[:scalar_has_mapping] = "scalar cannot take 'mapping:'."
40
+
41
+ end
@@ -0,0 +1,112 @@
1
+ ###
2
+ ### $Rev: 8 $
3
+ ### $Release: 0.1.0 $
4
+ ### copyright(c) 2005 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ module Kwalify
8
+
9
+ class KwalifyError < StandardError
10
+ end
11
+
12
+
13
+ class AssertionError < KwalifyError
14
+ def initialize(msg)
15
+ super("*** assertion error: " + msg)
16
+ end
17
+ end
18
+
19
+
20
+ class BaseError < KwalifyError
21
+ def initialize(message="", path=nil, schema=nil, error_symbol=nil)
22
+ super(message)
23
+ @error_symbol = error_symbol
24
+ @schema = schema
25
+ @path = path
26
+ end
27
+ attr_reader :error_symbol, :schema, :path
28
+
29
+ def to_s
30
+ return super() if @path == nil
31
+ return "[/] #{super()}" if @path.empty?
32
+ return "[#{@path}] #{super()}"
33
+ end
34
+ end
35
+
36
+
37
+ class SchemaError < BaseError
38
+ def initialize(message="", path=nil, schema=nil, error_symbol=nil)
39
+ super(message, path, schema, error_symbol)
40
+ end
41
+ end
42
+
43
+
44
+ class ValidationError < BaseError
45
+ def initialize(message="", path=nil, schema=nil, error_symbol=nil, data=nil)
46
+ super(message, path, schema, error_symbol)
47
+ @data = data
48
+ end
49
+ attr_reader :data
50
+ end
51
+
52
+
53
+ module Errors
54
+
55
+ def assert_error(message="")
56
+ raise AssertionError.new(message)
57
+ end
58
+
59
+
60
+ def error_message(error_symbol, schema, data, arg)
61
+ msg = nil
62
+ case error_symbol
63
+
64
+ ## validation error
65
+ when :missing_value
66
+ msg = ERROR_MESSAGES[error_symbol]
67
+ when :invalid_type
68
+ msg = ERROR_MESSAGES[error_symbol] % [ schema.type, data.class.name ]
69
+ when :invalid_enum
70
+ msg = ERROR_MESSAGES[error_symbol] % [ data.to_s ]
71
+ when :invalid_pattern
72
+ msg = ERROR_MESSAGES[error_symbol] % [ data.to_s, schema.pattern.inspect ]
73
+ when :missing_key
74
+ msg = ERROR_MESSAGES[error_symbol] % [ arg ] # arg is keyname
75
+ when :invalid_key
76
+ msg = ERROR_MESSAGES[error_symbol] % [ arg ] # arg is keyname
77
+
78
+ ## schema error
79
+ when :unexpected_key
80
+ msg = ERROR_MESSAGES[error_symbol] % [ arg ] # arg is keyname
81
+ when :duplicate_key
82
+ msg = ERROR_MESSAGES[error_symbol] % [ arg ] # arg is keyname
83
+ when :type_not_found
84
+ msg = ERROR_MESSAGES[error_symbol] % [ arg ] # arg is typename
85
+ when :regexp_error
86
+ msg = ERROR_MESSAGES[error_symbol] % [ data ]
87
+ else
88
+ msg = ERROR_MESSAGES[error_symbol]
89
+ end
90
+
91
+ ##
92
+ return msg
93
+ end
94
+
95
+
96
+ def validate_error(error_symbol, schema, path, data, arg=nil)
97
+ msg = error_message(error_symbol, schema, data, arg)
98
+ return ValidationError.new(msg, path, schema, error_symbol, data)
99
+ end
100
+
101
+
102
+ def schema_error(error_symbol, schema, path, arg=nil)
103
+ msg = error_message(error_symbol, schema, nil, arg)
104
+ return SchemaError.new(msg, path, schema, error_symbol)
105
+ end
106
+
107
+
108
+ module_function :assert_error, :validate_error, :schema_error, :error_message
109
+
110
+ end
111
+
112
+ end
@@ -0,0 +1,137 @@
1
+ ###
2
+ ### $Rev: 9 $
3
+ ### $Release: 0.1.0 $
4
+ ### copyright(c) 2005 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ require 'kwalify/errors'
8
+ require 'kwalify/validator'
9
+ require 'yaml'
10
+
11
+ module Kwalify
12
+
13
+ META_SCHEMA_DEF = <<'END'
14
+
15
+ name: MAIN
16
+ type: map
17
+ required: yes
18
+ mapping: &main-schema
19
+ "name":
20
+ type: string
21
+ "desc":
22
+ type: text
23
+ "type":
24
+ type: string
25
+ enum:
26
+ - seq
27
+ - sequence
28
+ #- list
29
+ - map
30
+ - mapping
31
+ #- hash
32
+ - string
33
+ - integer
34
+ - float
35
+ - number
36
+ - numeric
37
+ - bool
38
+ - boolean
39
+ - text
40
+ - date
41
+ - time
42
+ - object
43
+ - any
44
+ "required":
45
+ type: boolean
46
+ "enum":
47
+ type: seq
48
+ sequence:
49
+ - type: object
50
+ "pattern":
51
+ type: string
52
+ "sequence":
53
+ name: SEQUENCE
54
+ type: seq
55
+ sequence:
56
+ - type: map
57
+ mapping: *main-schema
58
+ name: MAIN
59
+ "mapping":
60
+ name: MAPPING
61
+ type: map
62
+ mapping:
63
+ '*':
64
+ type: map
65
+ mapping: *main-schema
66
+ name: MAIN
67
+
68
+ END
69
+
70
+
71
+ def self.meta_validator()
72
+ yaml = YAML.load(META_SCHEMA_DEF)
73
+ validator = Kwalify::Validator.new(yaml)
74
+ return validator
75
+ end
76
+
77
+
78
+ def self.meta_validator2()
79
+ yaml = YAML.load(META_SCHEMA_DEF)
80
+ validator = Kwalify::Validator.new(yaml) { |schema, obj, errors, path|
81
+ next if obj == nil ## realy?
82
+ if schema.name == "MAIN"
83
+ hash = obj
84
+ if hash.key?('pattern')
85
+ val = hash['pattern']
86
+ pat = (val =~ /\A\/(.*)\/\z/ ? $1 : val)
87
+ begin
88
+ Regexp.compile(pat)
89
+ rescue RegexpError => ex
90
+ errors << Kwalify::Errors.validate_error(:regexp_error, schema, path, obj)
91
+ end
92
+ end
93
+ type = hash['type']
94
+ if type == nil
95
+ if hash.key?('sequence')
96
+ type = 'seq'
97
+ elsif hash.key?('mapping')
98
+ type = 'map'
99
+ else
100
+ type = Kwalify::DEFAULT_TYPE
101
+ end
102
+ end
103
+ klass = Kwalify.type_table[type]
104
+ if klass == nil
105
+ errors << Kwalify::Errors.validate_error(:invalid_type, schema, path, obj)
106
+ elsif klass == Array
107
+ errors << Kwalify::Errors.validate_error(:seq_has_enum, schema, path, obj) if hash.key?('enum')
108
+ errors << Kwalify::Errors.validate_error(:seq_has_pattern, schema, path, obj) if hash.key?('pattern')
109
+ errors << Kwalify::Errors.validate_error(:seq_has_mapping, schema, path, obj) if hash.key?('mapping')
110
+ elsif klass == Hash
111
+ errors << Kwalify::Errors.validate_error(:map_has_enum, schema, path, obj) if hash.key?('enum')
112
+ errors << Kwalify::Errors.validate_error(:map_has_pattern, schema, path, obj) if hash.key?('pattern')
113
+ errors << Kwalify::Errors.validate_error(:map_has_sequence, schema, path, obj) if hash.key?('sequence')
114
+ else
115
+ errors << Kwalify::Errors.validate_error(:scalar_has_sequence, schema, path, obj) if hash.key?('sequence')
116
+ errors << Kwalify::Errors.validate_error(:scalar_has_mapping, schema, path, obj) if hash.key?('mapping')
117
+ end
118
+ elsif schema.name == "SEQUENCE"
119
+ if !obj.is_a?(Array)
120
+ errors << Kwalify::Errors.validate_error(:sequence_not_seq, schema, path, obj)
121
+ else
122
+ errors << Kwalify::Errors.validate_error(:sequence_no_elem, schema, path, obj) if obj.empty?
123
+ errors << Kwalify::Errors.validate_error(:sequence_too_many, schema, path, obj) if obj.length > 1
124
+ end
125
+ elsif schema.name == "MAPPING"
126
+ if !obj.is_a?(Hash)
127
+ errors << Kwalify::Errors.validate_error(:mapping_not_map, schema, path, obj)
128
+ else
129
+ errors << Kwalify::Errors.validate_error(:mapping_no_elem, schema, path, obj) if obj.empty?
130
+ end
131
+ end
132
+ }
133
+ return validator
134
+ end
135
+
136
+ end
137
+