dc-kwalify 0.7.2
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.
- data/CHANGES.txt +252 -0
- data/MIT-LICENSE +20 -0
- data/README.txt +61 -0
- data/bin/kwalify +13 -0
- data/contrib/inline-require +179 -0
- data/contrib/kwalify +4160 -0
- data/doc/docstyle.css +188 -0
- data/doc/img/fig01.png +0 -0
- data/doc/users-guide.html +2050 -0
- data/doc-api/classes/CommandOptionError.html +184 -0
- data/doc-api/classes/CommandOptionParser.html +325 -0
- data/doc-api/classes/Kwalify/AssertionError.html +148 -0
- data/doc-api/classes/Kwalify/BaseError.html +297 -0
- data/doc-api/classes/Kwalify/BaseParser.html +461 -0
- data/doc-api/classes/Kwalify/CommandOptionError.html +168 -0
- data/doc-api/classes/Kwalify/ErrorHelper.html +223 -0
- data/doc-api/classes/Kwalify/HashInterface.html +118 -0
- data/doc-api/classes/Kwalify/Json.html +105 -0
- data/doc-api/classes/Kwalify/KwalifyError.html +111 -0
- data/doc-api/classes/Kwalify/Main.html +339 -0
- data/doc-api/classes/Kwalify/MetaValidator.html +448 -0
- data/doc-api/classes/Kwalify/Parser.html +155 -0
- data/doc-api/classes/Kwalify/PlainYamlParser/Alias.html +165 -0
- data/doc-api/classes/Kwalify/PlainYamlParser.html +523 -0
- data/doc-api/classes/Kwalify/Rule.html +433 -0
- data/doc-api/classes/Kwalify/SchemaError.html +148 -0
- data/doc-api/classes/Kwalify/SyntaxError.html +185 -0
- data/doc-api/classes/Kwalify/Types.html +302 -0
- data/doc-api/classes/Kwalify/Util/HashLike.html +246 -0
- data/doc-api/classes/Kwalify/Util/OrderedHash.html +330 -0
- data/doc-api/classes/Kwalify/Util.html +390 -0
- data/doc-api/classes/Kwalify/ValidationError.html +148 -0
- data/doc-api/classes/Kwalify/Validator.html +381 -0
- data/doc-api/classes/Kwalify/Yaml/Parser.html +1538 -0
- data/doc-api/classes/Kwalify/Yaml.html +194 -0
- data/doc-api/classes/Kwalify/YamlParser.html +542 -0
- data/doc-api/classes/Kwalify/YamlSyntaxError.html +119 -0
- data/doc-api/classes/Kwalify.html +292 -0
- data/doc-api/classes/Test/Unit.html +101 -0
- data/doc-api/classes/Test.html +107 -0
- data/doc-api/created.rid +1 -0
- data/doc-api/files/__/README_txt.html +172 -0
- data/doc-api/files/kwalify/errors_rb.html +114 -0
- data/doc-api/files/kwalify/main_rb.html +118 -0
- data/doc-api/files/kwalify/messages_rb.html +107 -0
- data/doc-api/files/kwalify/meta-validator_rb.html +117 -0
- data/doc-api/files/kwalify/parser/base_rb.html +116 -0
- data/doc-api/files/kwalify/parser/yaml_rb.html +117 -0
- data/doc-api/files/kwalify/rule_rb.html +116 -0
- data/doc-api/files/kwalify/types_rb.html +114 -0
- data/doc-api/files/kwalify/util/assert-text-equal_rb.html +115 -0
- data/doc-api/files/kwalify/util/hash-interface_rb.html +114 -0
- data/doc-api/files/kwalify/util/hashlike_rb.html +107 -0
- data/doc-api/files/kwalify/util/option-parser_rb.html +107 -0
- data/doc-api/files/kwalify/util/ordered-hash_rb.html +107 -0
- data/doc-api/files/kwalify/util/testcase-helper_rb.html +115 -0
- data/doc-api/files/kwalify/util_rb.html +107 -0
- data/doc-api/files/kwalify/validator_rb.html +117 -0
- data/doc-api/files/kwalify/yaml-parser_rb.html +117 -0
- data/doc-api/files/kwalify_rb.html +121 -0
- data/doc-api/fr_class_index.html +57 -0
- data/doc-api/fr_file_index.html +45 -0
- data/doc-api/fr_method_index.html +168 -0
- data/doc-api/index.html +24 -0
- data/doc-api/rdoc-style.css +208 -0
- data/examples/address-book/Makefile +10 -0
- data/examples/address-book/address-book.schema.yaml +45 -0
- data/examples/address-book/address-book.yaml +36 -0
- data/examples/data-binding/BABEL.data.yaml +63 -0
- data/examples/data-binding/BABEL.schema.yaml +31 -0
- data/examples/data-binding/Makefile +8 -0
- data/examples/data-binding/Rakefile +13 -0
- data/examples/data-binding/main.rb +27 -0
- data/examples/invoice/Makefile +9 -0
- data/examples/invoice/invoice.schema.yaml +43 -0
- data/examples/invoice/invoice.yaml +32 -0
- data/examples/tapkit/Makefile +10 -0
- data/examples/tapkit/main.rb +7 -0
- data/examples/tapkit/tapkit.schema.yaml +146 -0
- data/examples/tapkit/tapkit.yaml +85 -0
- data/lib/kwalify/errors.rb +127 -0
- data/lib/kwalify/kwalify.schema.yaml +58 -0
- data/lib/kwalify/main.rb +442 -0
- data/lib/kwalify/messages.rb +173 -0
- data/lib/kwalify/meta-validator.rb +275 -0
- data/lib/kwalify/parser/base.rb +127 -0
- data/lib/kwalify/parser/yaml.rb +841 -0
- data/lib/kwalify/rule.rb +559 -0
- data/lib/kwalify/templates/genclass-java.eruby +222 -0
- data/lib/kwalify/templates/genclass-php.eruby +104 -0
- data/lib/kwalify/templates/genclass-ruby.eruby +113 -0
- data/lib/kwalify/types.rb +156 -0
- data/lib/kwalify/util/assert-text-equal.rb +46 -0
- data/lib/kwalify/util/hash-interface.rb +18 -0
- data/lib/kwalify/util/hashlike.rb +51 -0
- data/lib/kwalify/util/option-parser.rb +220 -0
- data/lib/kwalify/util/ordered-hash.rb +57 -0
- data/lib/kwalify/util/testcase-helper.rb +112 -0
- data/lib/kwalify/util.rb +158 -0
- data/lib/kwalify/validator.rb +282 -0
- data/lib/kwalify/yaml-parser.rb +870 -0
- data/lib/kwalify.rb +67 -0
- data/setup.rb +1585 -0
- data/test/Rookbook.yaml +10 -0
- data/test/data/users-guide/AddressBook.java.expected +40 -0
- data/test/data/users-guide/BABEL.data.yaml +24 -0
- data/test/data/users-guide/BABEL.schema.yaml +30 -0
- data/test/data/users-guide/ExampleAddressBook.java +47 -0
- data/test/data/users-guide/Group.java.expected +24 -0
- data/test/data/users-guide/Person.java.expected +44 -0
- data/test/data/users-guide/address_book.rb +52 -0
- data/test/data/users-guide/address_book.schema.yaml +28 -0
- data/test/data/users-guide/address_book.yaml +27 -0
- data/test/data/users-guide/answers-schema.yaml +12 -0
- data/test/data/users-guide/answers-validator.rb +52 -0
- data/test/data/users-guide/babel_genclass.result +26 -0
- data/test/data/users-guide/config.schema.yaml +7 -0
- data/test/data/users-guide/config.yaml +4 -0
- data/test/data/users-guide/document01a.yaml +3 -0
- data/test/data/users-guide/document01b.yaml +3 -0
- data/test/data/users-guide/document02a.yaml +4 -0
- data/test/data/users-guide/document02b.yaml +4 -0
- data/test/data/users-guide/document03a.yaml +6 -0
- data/test/data/users-guide/document03b.yaml +6 -0
- data/test/data/users-guide/document04a.yaml +9 -0
- data/test/data/users-guide/document04b.yaml +9 -0
- data/test/data/users-guide/document05a.yaml +11 -0
- data/test/data/users-guide/document05b.yaml +12 -0
- data/test/data/users-guide/document06a.yaml +15 -0
- data/test/data/users-guide/document06b.yaml +16 -0
- data/test/data/users-guide/document07a.yaml +9 -0
- data/test/data/users-guide/document07b.yaml +7 -0
- data/test/data/users-guide/document12a.json +10 -0
- data/test/data/users-guide/document12b.json +6 -0
- data/test/data/users-guide/document13a.yaml +17 -0
- data/test/data/users-guide/document14a.yaml +3 -0
- data/test/data/users-guide/document14b.yaml +3 -0
- data/test/data/users-guide/document15a.yaml +6 -0
- data/test/data/users-guide/document15b.yaml +5 -0
- data/test/data/users-guide/example_address_book.rb +10 -0
- data/test/data/users-guide/example_address_book_java.result +32 -0
- data/test/data/users-guide/example_address_book_ruby.result +31 -0
- data/test/data/users-guide/genclass_java.result +4 -0
- data/test/data/users-guide/howto-validation-with-parsing.rb +28 -0
- data/test/data/users-guide/howto-validation.rb +25 -0
- data/test/data/users-guide/howto3.rb +6 -0
- data/test/data/users-guide/howto3.result +5 -0
- data/test/data/users-guide/howto3.yaml +8 -0
- data/test/data/users-guide/howto5_databinding.result +111 -0
- data/test/data/users-guide/invalid01.result +3 -0
- data/test/data/users-guide/invalid02.result +5 -0
- data/test/data/users-guide/invalid03.result +5 -0
- data/test/data/users-guide/invalid04.result +4 -0
- data/test/data/users-guide/invalid05.result +11 -0
- data/test/data/users-guide/invalid06.result +4 -0
- data/test/data/users-guide/invalid07.result +3 -0
- data/test/data/users-guide/invalid08.result +3 -0
- data/test/data/users-guide/invalid12.json +8 -0
- data/test/data/users-guide/invalid14.result +4 -0
- data/test/data/users-guide/invalid15.result +4 -0
- data/test/data/users-guide/loadbabel.rb +27 -0
- data/test/data/users-guide/loadconfig.rb +16 -0
- data/test/data/users-guide/loadconfig.result +6 -0
- data/test/data/users-guide/models.rb +22 -0
- data/test/data/users-guide/option_ha.result +6 -0
- data/test/data/users-guide/option_ha_genclass_java.result +7 -0
- data/test/data/users-guide/schema01.yaml +3 -0
- data/test/data/users-guide/schema02.yaml +12 -0
- data/test/data/users-guide/schema03.yaml +9 -0
- data/test/data/users-guide/schema04.yaml +20 -0
- data/test/data/users-guide/schema05.yaml +29 -0
- data/test/data/users-guide/schema06.yaml +11 -0
- data/test/data/users-guide/schema12.json +12 -0
- data/test/data/users-guide/schema13.yaml +13 -0
- data/test/data/users-guide/schema14.yaml +5 -0
- data/test/data/users-guide/schema15.yaml +21 -0
- data/test/data/users-guide/valid01.result +2 -0
- data/test/data/users-guide/valid02.result +2 -0
- data/test/data/users-guide/valid03.result +2 -0
- data/test/data/users-guide/valid04.result +2 -0
- data/test/data/users-guide/valid05.result +2 -0
- data/test/data/users-guide/valid06.result +2 -0
- data/test/data/users-guide/valid07.result +2 -0
- data/test/data/users-guide/valid08.result +2 -0
- data/test/data/users-guide/valid12.result +2 -0
- data/test/data/users-guide/valid13.result +2 -0
- data/test/data/users-guide/valid14.result +2 -0
- data/test/data/users-guide/valid15.result +2 -0
- data/test/data/users-guide/validate08.rb +37 -0
- data/test/test-action.rb +78 -0
- data/test/test-action.yaml +738 -0
- data/test/test-databinding.rb +83 -0
- data/test/test-databinding.yaml +339 -0
- data/test/test-main.rb +157 -0
- data/test/test-main.yaml +415 -0
- data/test/test-metavalidator.rb +80 -0
- data/test/test-metavalidator.yaml +1179 -0
- data/test/test-parser-yaml.rb +57 -0
- data/test/test-parser-yaml.yaml +1749 -0
- data/test/test-rule.rb +26 -0
- data/test/test-rule.yaml +317 -0
- data/test/test-users-guide.rb +75 -0
- data/test/test-util.rb +125 -0
- data/test/test-validator.rb +95 -0
- data/test/test-validator.yaml +986 -0
- data/test/test-yaml-parser.rb +47 -0
- data/test/test-yaml-parser.yaml +1226 -0
- data/test/test.rb +61 -0
- metadata +274 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
###
|
|
2
|
+
### $Rev$
|
|
3
|
+
### $Release: 0.7.2 $
|
|
4
|
+
### copyright(c) 2005-2010 kuwata-lab all rights reserved.
|
|
5
|
+
###
|
|
6
|
+
|
|
7
|
+
module Kwalify
|
|
8
|
+
|
|
9
|
+
module Util
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
## add hash-like methods
|
|
13
|
+
##
|
|
14
|
+
module HashLike
|
|
15
|
+
|
|
16
|
+
def [](key)
|
|
17
|
+
instance_variable_get("@#{key}")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def []=(key, val)
|
|
21
|
+
instance_variable_set("@#{key}", val)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#--
|
|
25
|
+
#def keys()
|
|
26
|
+
# instance_variables().collect { |name| name[1, name.length-1] }
|
|
27
|
+
#end
|
|
28
|
+
#++
|
|
29
|
+
|
|
30
|
+
def key?(key)
|
|
31
|
+
instance_variables().include?("@#{key}")
|
|
32
|
+
end
|
|
33
|
+
if Object.instance_methods.include?('instance_variable_defined?')
|
|
34
|
+
def key?(key)
|
|
35
|
+
instance_variable_defined?("@#{key}")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def each # not necessary
|
|
40
|
+
instance_variables().each do |name|
|
|
41
|
+
key = name[1, name.length-1]
|
|
42
|
+
val = instance_variable_get(name)
|
|
43
|
+
yield(key, val)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
###
|
|
2
|
+
### $Rev$
|
|
3
|
+
### $Release: 0.7.2 $
|
|
4
|
+
### copyright(c) 2005-2010 kuwata-lab all rights reserved.
|
|
5
|
+
###
|
|
6
|
+
|
|
7
|
+
class CommandOptionError < StandardError
|
|
8
|
+
def initialize(option, error_symbol, message=nil)
|
|
9
|
+
if !message
|
|
10
|
+
case error_symbol
|
|
11
|
+
when :no_argument
|
|
12
|
+
message = "-%s: argument required." % option
|
|
13
|
+
when :unknown_option
|
|
14
|
+
message = "-%s: unknown option." % option
|
|
15
|
+
when :invalid_property
|
|
16
|
+
message = "-%s: invalid property." % option
|
|
17
|
+
else
|
|
18
|
+
message = "*** internal error(optchar=#{option}, error_symbol=#{error_symbol}) ***"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
super(message)
|
|
22
|
+
@option = option
|
|
23
|
+
@error_symbol = error_symbol
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
attr_reader :option, :error_symbol
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
## ex.
|
|
32
|
+
## ## create parser
|
|
33
|
+
## arg_none = "hv" # ex. -h -v
|
|
34
|
+
## arg_required = "xf" # ex. -x suffix -f filename
|
|
35
|
+
## arg_optional = "i" # ex. -i (or -i10)
|
|
36
|
+
## parser = CommandOptionParser.new(arg_none, arg_required, arg_optional)
|
|
37
|
+
##
|
|
38
|
+
## ## parse options
|
|
39
|
+
## argv = %w[-h -v -f filename -i 10 aaa bbb]
|
|
40
|
+
## options, properties = parser.parse(argv)
|
|
41
|
+
## p options #=> { ?h=>true, ?v=>true, ?f=>"filename", ?i=>true }
|
|
42
|
+
## p argv #=> ["10", "aaa", "bbb"]
|
|
43
|
+
##
|
|
44
|
+
## ## parse options #2
|
|
45
|
+
## argv = %w[-hvx.txt -ffilename -i10 aaa bbb]
|
|
46
|
+
## options, properties = parser.parse(argv)
|
|
47
|
+
## p options #=> { ?h=>true, ?v=>true, ?x=>".txt", ?f=>"filename", ?i=>10 }
|
|
48
|
+
## p argv #=> ["aaa", "bbb"]
|
|
49
|
+
##
|
|
50
|
+
## ## parse properties
|
|
51
|
+
## argv = %w[-hi --index=10 --user-name=foo --help]
|
|
52
|
+
## options, properties = parser.parse(argv)
|
|
53
|
+
## p options #=> {?h=>true, ?i=>true}
|
|
54
|
+
## p properties #=> {"index"=>"10", "user-name"=>"foo", "help"=>nil}
|
|
55
|
+
##
|
|
56
|
+
## ## parse properties with auto-convert
|
|
57
|
+
## argv = %w[-hi --index=10 --user-name=foo --help]
|
|
58
|
+
## options, properties = parser.parse(argv, true)
|
|
59
|
+
## p options #=> {?h=>true, ?i=>true}
|
|
60
|
+
## p properties #=> {:index=>10, :user_name=>foo, :help=>true}
|
|
61
|
+
##
|
|
62
|
+
## ## -a: unknown option.
|
|
63
|
+
## argv = %w[-abc]
|
|
64
|
+
## begin
|
|
65
|
+
## options, properties = parser.parse(argv)
|
|
66
|
+
## rescue CommandOptionError => ex
|
|
67
|
+
## $stderr.puts ex.message # -a: unknown option.
|
|
68
|
+
## end
|
|
69
|
+
##
|
|
70
|
+
## ## -f: argument required.
|
|
71
|
+
## argv = %w[-f]
|
|
72
|
+
## begin
|
|
73
|
+
## options, properties = parser.parse(argv)
|
|
74
|
+
## rescue CommandOptionError => ex
|
|
75
|
+
## $stderr.puts ex.message # -f: argument required.
|
|
76
|
+
## end
|
|
77
|
+
##
|
|
78
|
+
## ## --@prop=10: invalid property.
|
|
79
|
+
## argv = %w[--@prop=10]
|
|
80
|
+
## begin
|
|
81
|
+
## options, properties = parser.parse(argv)
|
|
82
|
+
## rescue CommandOptionError => ex
|
|
83
|
+
## $stderr.puts ex.message # --@prop=10: invalid property.
|
|
84
|
+
## end
|
|
85
|
+
##
|
|
86
|
+
|
|
87
|
+
class CommandOptionParser
|
|
88
|
+
|
|
89
|
+
## arg_none: option string which takes no argument
|
|
90
|
+
## arg_required: option string which takes argument
|
|
91
|
+
## arg_otpional: option string which may takes argument optionally
|
|
92
|
+
def initialize(arg_none=nil, arg_required=nil, arg_optional=nil)
|
|
93
|
+
@arg_none = arg_none || ""
|
|
94
|
+
@arg_required = arg_required || ""
|
|
95
|
+
@arg_optional = arg_optional || ""
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def self.to_value(str)
|
|
100
|
+
case str
|
|
101
|
+
when nil, "null", "nil" ; return nil
|
|
102
|
+
when "true", "yes" ; return true
|
|
103
|
+
when "false", "no" ; return false
|
|
104
|
+
when /\A\d+\z/ ; return str.to_i
|
|
105
|
+
when /\A\d+\.\d+\z/ ; return str.to_f
|
|
106
|
+
when /\/(.*)\// ; return Regexp.new($1)
|
|
107
|
+
when /\A'.*'\z/, /\A".*"\z/ ; return eval(str)
|
|
108
|
+
else ; return str
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
## argv:: array of string
|
|
114
|
+
## auto_convert:: if true, convert properties value to int, boolean, string, regexp, ... (default false)
|
|
115
|
+
def parse(argv, auto_convert=false)
|
|
116
|
+
options = {}
|
|
117
|
+
properties = {}
|
|
118
|
+
while argv[0] && argv[0][0] == ?-
|
|
119
|
+
optstr = argv.shift
|
|
120
|
+
optstr = optstr[1, optstr.length-1]
|
|
121
|
+
#
|
|
122
|
+
if optstr[0] == ?- ## property
|
|
123
|
+
unless optstr =~ /\A\-([-\w]+)(?:=(.*))?/
|
|
124
|
+
raise CommandOptionError.new(optstr, :invalid_property)
|
|
125
|
+
end
|
|
126
|
+
prop_name = $1; prop_value = $2
|
|
127
|
+
if auto_convert
|
|
128
|
+
key = prop_name.gsub(/-/, '_').intern
|
|
129
|
+
value = prop_value.nil? ? true : CommandOptionParser.to_value(prop_value)
|
|
130
|
+
properties[key] = value
|
|
131
|
+
else
|
|
132
|
+
properties[prop_name] = prop_value
|
|
133
|
+
end
|
|
134
|
+
#
|
|
135
|
+
else ## options
|
|
136
|
+
while optstr && !optstr.empty?
|
|
137
|
+
optchar = optstr[0]
|
|
138
|
+
optstr[0,1] = ""
|
|
139
|
+
#puts "*** debug: optchar=#{optchar.chr}, optstr=#{optstr.inspect}"
|
|
140
|
+
if @arg_none.include?(optchar)
|
|
141
|
+
options[optchar] = true
|
|
142
|
+
elsif @arg_required.include?(optchar)
|
|
143
|
+
arg = optstr.empty? ? argv.shift : optstr
|
|
144
|
+
raise CommandOptionError.new(optchar.chr, :no_argument) unless arg
|
|
145
|
+
options[optchar] = arg
|
|
146
|
+
optstr = nil
|
|
147
|
+
elsif @arg_optional.include?(optchar)
|
|
148
|
+
arg = optstr.empty? ? true : optstr
|
|
149
|
+
options[optchar] = arg
|
|
150
|
+
optstr = nil
|
|
151
|
+
else
|
|
152
|
+
raise CommandOptionError.new(optchar.chr, :unknown_option)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
#
|
|
157
|
+
end # end of while
|
|
158
|
+
|
|
159
|
+
return options, properties
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
if __FILE__ == $0
|
|
166
|
+
## create parser
|
|
167
|
+
arg_none = "hv" # ex. -h -v
|
|
168
|
+
arg_required = "xf" # ex. -x suffix -f filename
|
|
169
|
+
arg_optional = "i" # ex. -i (or -i10)
|
|
170
|
+
parser = CommandOptionParser.new(arg_none, arg_required, arg_optional)
|
|
171
|
+
|
|
172
|
+
## parse options
|
|
173
|
+
argv = %w[-h -v -f filename -i 10 aaa bbb]
|
|
174
|
+
options, properties = parser.parse(argv)
|
|
175
|
+
p options #=> { ?h=>true, ?v=>true, ?f=>"filename", ?i=>true }
|
|
176
|
+
p argv #=> ["10", "aaa", "bbb"]
|
|
177
|
+
|
|
178
|
+
## parse options #2
|
|
179
|
+
argv = %w[-hvx.txt -ffilename -i10 aaa bbb]
|
|
180
|
+
options, properties = parser.parse(argv)
|
|
181
|
+
p options #=> { ?h=>true, ?v=>true, ?x=>".txt", ?f=>"filename", ?i=>"10" }
|
|
182
|
+
p argv #=> ["aaa", "bbb"]
|
|
183
|
+
|
|
184
|
+
## parse properties
|
|
185
|
+
argv = %w[-hi --index=10 --user-name=foo --help]
|
|
186
|
+
options, properties = parser.parse(argv)
|
|
187
|
+
p options #=> {?h=>true, ?i=>true}
|
|
188
|
+
p properties #=> {"index"=>"10", "user-name"=>"foo", "help"=>nil}
|
|
189
|
+
|
|
190
|
+
## parse properties with auto-convert
|
|
191
|
+
argv = %w[-hi --index=10 --user-name=foo --help]
|
|
192
|
+
options, properties = parser.parse(argv, true)
|
|
193
|
+
p options #=> {?h=>true, ?i=>true}
|
|
194
|
+
p properties #=> {:index=>10, :user_name=>foo, :help=>true}
|
|
195
|
+
|
|
196
|
+
## -a: unknown option.
|
|
197
|
+
argv = %w[-abc]
|
|
198
|
+
begin
|
|
199
|
+
options, properties = parser.parse(argv)
|
|
200
|
+
rescue CommandOptionError => ex
|
|
201
|
+
$stderr.puts ex.message # -a: unknown option.
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
## -f: argument required.
|
|
205
|
+
argv = %w[-f]
|
|
206
|
+
begin
|
|
207
|
+
options, properties = parser.parse(argv)
|
|
208
|
+
rescue CommandOptionError => ex
|
|
209
|
+
$stderr.puts ex.message # -f: argument required.
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
## --@prop=10: invalid property.
|
|
213
|
+
argv = %w[--@prop=10]
|
|
214
|
+
begin
|
|
215
|
+
options, properties = parser.parse(argv)
|
|
216
|
+
rescue CommandOptionError => ex
|
|
217
|
+
$stderr.puts ex.message # --@prop=10: invalid property.
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
###
|
|
2
|
+
### $Rev$
|
|
3
|
+
### 0.7.2
|
|
4
|
+
### $COPYRIGHT$
|
|
5
|
+
###
|
|
6
|
+
|
|
7
|
+
module Kwalify
|
|
8
|
+
|
|
9
|
+
module Util
|
|
10
|
+
|
|
11
|
+
class OrderedHash < Hash
|
|
12
|
+
|
|
13
|
+
def initialize(*args, &block)
|
|
14
|
+
super
|
|
15
|
+
@_keys = []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
alias __set__ []=
|
|
19
|
+
|
|
20
|
+
def put(key, val)
|
|
21
|
+
@_keys << key unless self.key?(key)
|
|
22
|
+
__set__(key, val)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add(key, val)
|
|
26
|
+
@_keys.delete_at(@_keys.index(key)) if self.key?(key)
|
|
27
|
+
@_keys << key
|
|
28
|
+
__set__(key, val)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
alias []= put
|
|
32
|
+
#alias []= add
|
|
33
|
+
|
|
34
|
+
def keys
|
|
35
|
+
return @_keys.dup
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def values
|
|
39
|
+
return @_keys.collect {|key| self[key] }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def delete(key)
|
|
43
|
+
@_keys.delete_at(@_keys.index(key)) if self.key?(key)
|
|
44
|
+
super
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def each
|
|
48
|
+
@_keys.each do |key|
|
|
49
|
+
yield key, self[key]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
###
|
|
2
|
+
### $Rev$
|
|
3
|
+
### $Release: 0.7.2 $
|
|
4
|
+
### copyright(c) 2005-2010 kuwata-lab all rights reserved.
|
|
5
|
+
###
|
|
6
|
+
|
|
7
|
+
require 'yaml'
|
|
8
|
+
require 'test/unit/testcase'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Test::Unit::TestCase # :nodoc:
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def self._untabify(str, width=8) # :nodoc:
|
|
15
|
+
sb = []
|
|
16
|
+
str.scan(/(.*?)\t/m) do |s, |
|
|
17
|
+
len = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length
|
|
18
|
+
sb << s << (" " * (width - len % width))
|
|
19
|
+
end
|
|
20
|
+
str = (sb << $').join if $'
|
|
21
|
+
return str
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def self.load_yaml_documents(filename, options={}) # :nodoc:
|
|
26
|
+
str = File.read(filename)
|
|
27
|
+
if filename =~ /\.rb$/
|
|
28
|
+
str =~ /^__END__$/ or raise "*** error: __END__ is not found in '#{filename}'."
|
|
29
|
+
str = $'
|
|
30
|
+
end
|
|
31
|
+
str = _untabify(str) unless options[:tabify] == false
|
|
32
|
+
#
|
|
33
|
+
identkey = options[:identkey] || 'name'
|
|
34
|
+
list = []
|
|
35
|
+
table = {}
|
|
36
|
+
YAML.load_documents(str) do |ydoc|
|
|
37
|
+
if ydoc.is_a?(Hash)
|
|
38
|
+
list << ydoc
|
|
39
|
+
elsif ydoc.is_a?(Array)
|
|
40
|
+
list += ydoc
|
|
41
|
+
else
|
|
42
|
+
raise "*** invalid ydoc: #{ydoc.inspect}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
#
|
|
46
|
+
list.each do |ydoc|
|
|
47
|
+
ident = ydoc[identkey]
|
|
48
|
+
ident or raise "*** #{identkey} is not found."
|
|
49
|
+
table[ident] and raise "*** #{identkey} '#{ident}' is duplicated."
|
|
50
|
+
table[ident] = ydoc
|
|
51
|
+
yield(ydoc) if block_given?
|
|
52
|
+
end
|
|
53
|
+
#
|
|
54
|
+
return list
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def self.load_yaml_testdata(filename, options={}) # :nodoc:
|
|
59
|
+
identkey = options[:identkey] || 'name'
|
|
60
|
+
testmethod = options[:testmethod] || '_test'
|
|
61
|
+
lang = options[:lang]
|
|
62
|
+
load_yaml_documents(filename, options) do |ydoc|
|
|
63
|
+
ident = ydoc[identkey]
|
|
64
|
+
s = "def test_#{ident}\n"
|
|
65
|
+
ydoc.each do |key, val|
|
|
66
|
+
if key[-1] == ?*
|
|
67
|
+
key = key[0, key.length-1]
|
|
68
|
+
val = val[lang]
|
|
69
|
+
end
|
|
70
|
+
s << " @#{key} = #{val.inspect}\n"
|
|
71
|
+
end
|
|
72
|
+
s << " #{testmethod}\n"
|
|
73
|
+
s << "end\n"
|
|
74
|
+
#$stderr.puts "*** #{method_name()}(): eval_str=<<'END'\n#{s}END" if $DEBUG
|
|
75
|
+
module_eval s # not eval!
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def self.method_name # :nodoc:
|
|
81
|
+
return (caller[0] =~ /in `(.*?)'/) && $1
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def self.load_yaml_testdata_with_each_lang(filename, options={}) # :nodoc:
|
|
86
|
+
identkey = options[:identkey] || 'name'
|
|
87
|
+
testmethod = options[:testmethod] || '_test'
|
|
88
|
+
langs = defined?($lang) && $lang ? [ $lang ] : options[:langs]
|
|
89
|
+
langs or raise "*** #{method_name()}(): option ':langs' is required."
|
|
90
|
+
#
|
|
91
|
+
load_yaml_documents(filename, options) do |ydoc|
|
|
92
|
+
ident = ydoc[identkey]
|
|
93
|
+
langs.each do |lang|
|
|
94
|
+
s = "def test_#{ident}_#{lang}\n"
|
|
95
|
+
s << " @lang = #{lang.inspect}\n"
|
|
96
|
+
ydoc.each do |key, val|
|
|
97
|
+
if key[-1] == ?*
|
|
98
|
+
key = key[0, key.length-1]
|
|
99
|
+
val = val[lang]
|
|
100
|
+
end
|
|
101
|
+
s << " @#{key} = #{val.inspect}\n"
|
|
102
|
+
end
|
|
103
|
+
s << " #{testmethod}\n"
|
|
104
|
+
s << "end\n"
|
|
105
|
+
#$stderr.puts "*** #{method_name()}(): eval_str=<<'END'\n#{s}END" if $DEBUG
|
|
106
|
+
module_eval s # not eval!
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
end
|
data/lib/kwalify/util.rb
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
###
|
|
2
|
+
### $Rev$
|
|
3
|
+
### $Release: 0.7.2 $
|
|
4
|
+
### copyright(c) 2005-2010 kuwata-lab all rights reserved.
|
|
5
|
+
###
|
|
6
|
+
|
|
7
|
+
module Kwalify
|
|
8
|
+
|
|
9
|
+
module Util
|
|
10
|
+
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
## expand tab character to spaces
|
|
15
|
+
##
|
|
16
|
+
## ex.
|
|
17
|
+
## untabified_str = YamlHelper.untabify(tabbed_str)
|
|
18
|
+
##
|
|
19
|
+
def untabify(str, width=8)
|
|
20
|
+
return str if str.nil?
|
|
21
|
+
list = str.split(/\t/, -1) # if 2nd arg is negative then split() doesn't remove tailing empty strings
|
|
22
|
+
last = list.pop
|
|
23
|
+
sb = ''
|
|
24
|
+
list.each do |s|
|
|
25
|
+
column = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length
|
|
26
|
+
n = width - (column % width)
|
|
27
|
+
sb << s << (' ' * n)
|
|
28
|
+
end
|
|
29
|
+
sb << last if last
|
|
30
|
+
return sb
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## traverse schema
|
|
35
|
+
##
|
|
36
|
+
## ex.
|
|
37
|
+
## schema = YAML.load_file('myschema.yaml')
|
|
38
|
+
## Kwalify::Util.traverse_schema(schema) do |rulehash|
|
|
39
|
+
## ## add module prefix to class name
|
|
40
|
+
## if rulehash['class']
|
|
41
|
+
## rulehash['class'] = 'MyModule::' + rulehash['class']
|
|
42
|
+
## end
|
|
43
|
+
## end
|
|
44
|
+
def traverse_schema(schema, &block) #:yield: rulehash
|
|
45
|
+
hash = schema
|
|
46
|
+
_done = {}
|
|
47
|
+
_traverse_schema(hash, _done, &block)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def _traverse_schema(hash, _done={}, &block)
|
|
51
|
+
return if _done.key?(hash.__id__)
|
|
52
|
+
_done[hash.__id__] = hash
|
|
53
|
+
yield hash
|
|
54
|
+
if hash['mapping']
|
|
55
|
+
hash['mapping'].each {|k, v| _traverse_schema(v, _done, &block) }
|
|
56
|
+
elsif hash['sequence']
|
|
57
|
+
_traverse_schema(hash['sequence'][0], _done, &block)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
private :_traverse_schema
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
## traverse rule
|
|
64
|
+
##
|
|
65
|
+
## ex.
|
|
66
|
+
## schema = YAML.load_file('myschema.yaml')
|
|
67
|
+
## validator = Kwalify::Validator.new(schema)
|
|
68
|
+
## Kwalify::Util.traverse_rule(validator) do |rule|
|
|
69
|
+
## p rule if rule.classname
|
|
70
|
+
## end
|
|
71
|
+
def traverse_rule(validator, &block) #:yield: rule
|
|
72
|
+
rule = validator.is_a?(Rule) ? validator : validator.rule
|
|
73
|
+
_done = {}
|
|
74
|
+
_traverse_rule(rule, _done, &block)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def _traverse_rule(rule, _done={}, &block)
|
|
78
|
+
return if _done.key?(rule.__id__)
|
|
79
|
+
_done[rule.__id__] = rule
|
|
80
|
+
yield rule
|
|
81
|
+
rule.sequence.each do |seq_rule|
|
|
82
|
+
_traverse_rule(seq_rule, _done, &block)
|
|
83
|
+
end if rule.sequence
|
|
84
|
+
rule.mapping.each do |name, map_rule|
|
|
85
|
+
_traverse_rule(map_rule, _done, &block)
|
|
86
|
+
end if rule.mapping
|
|
87
|
+
end
|
|
88
|
+
private :_traverse_rule
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
##
|
|
92
|
+
## get class object. if not found, NameError raised.
|
|
93
|
+
##
|
|
94
|
+
def get_class(classname)
|
|
95
|
+
klass = Object
|
|
96
|
+
classname.split('::').each do |name|
|
|
97
|
+
klass = klass.const_get(name)
|
|
98
|
+
end
|
|
99
|
+
return klass
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
##
|
|
104
|
+
## create a hash table from list of hash with primary key.
|
|
105
|
+
##
|
|
106
|
+
## ex.
|
|
107
|
+
## hashlist = [
|
|
108
|
+
## { "name"=>"Foo", "gender"=>"M", "age"=>20, },
|
|
109
|
+
## { "name"=>"Bar", "gender"=>"F", "age"=>25, },
|
|
110
|
+
## { "name"=>"Baz", "gender"=>"M", "age"=>30, },
|
|
111
|
+
## ]
|
|
112
|
+
## hashtable = YamlHelper.create_hashtable(hashlist, "name")
|
|
113
|
+
## p hashtable
|
|
114
|
+
## # => { "Foo" => { "name"=>"Foo", "gender"=>"M", "age"=>20, },
|
|
115
|
+
## # "Bar" => { "name"=>"Bar", "gender"=>"F", "age"=>25, },
|
|
116
|
+
## # "Baz" => { "name"=>"Baz", "gender"=>"M", "age"=>30, }, }
|
|
117
|
+
##
|
|
118
|
+
def create_hashtable(hashlist, primarykey, flag_duplicate_check=true)
|
|
119
|
+
hashtable = {}
|
|
120
|
+
hashlist.each do |hash|
|
|
121
|
+
key = hash[primarykey]
|
|
122
|
+
unless key
|
|
123
|
+
riase "primary key '#{key}' not found."
|
|
124
|
+
end
|
|
125
|
+
if flag_duplicate_check && hashtable.key?(key)
|
|
126
|
+
raise "primary key '#{key}' duplicated (value '#{hashtable[key]}')"
|
|
127
|
+
end
|
|
128
|
+
hashtable[key] = hash
|
|
129
|
+
end if hashlist
|
|
130
|
+
return hashtable
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
##
|
|
135
|
+
## get nested value directly.
|
|
136
|
+
##
|
|
137
|
+
## ex.
|
|
138
|
+
## val = YamlHelper.get_value(obj, ['aaa', 0, 'xxx'])
|
|
139
|
+
##
|
|
140
|
+
## This is equal to the following:
|
|
141
|
+
## begin
|
|
142
|
+
## val = obj['aaa'][0]['xxx']
|
|
143
|
+
## rescue NameError
|
|
144
|
+
## val = nil
|
|
145
|
+
## end
|
|
146
|
+
##
|
|
147
|
+
def get_value(obj, path)
|
|
148
|
+
val = obj
|
|
149
|
+
path.each do |key|
|
|
150
|
+
return nil unless val.is_a?(Hash) || val.is_a?(Array)
|
|
151
|
+
val = val[key]
|
|
152
|
+
end if path
|
|
153
|
+
return val
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
end
|