rkwalify 1.4.0.pre.beta

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.
Files changed (250) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +39 -0
  3. data/.gitignore +63 -0
  4. data/.overcommit.yml +33 -0
  5. data/.rubocop.yml +9 -0
  6. data/.rubocop_todo.yml +1369 -0
  7. data/.ruby-version +1 -0
  8. data/Attic/README-0.7.2.md +61 -0
  9. data/Attic/features/cli.feature +9 -0
  10. data/Attic/features/step_definitions/validation_steps.rb +20 -0
  11. data/Attic/features/support/env.rb +4 -0
  12. data/Attic/features/validate_schema.feature +12 -0
  13. data/Attic/s+h +53 -0
  14. data/Attic/setup.rb +1556 -0
  15. data/Attic/spec/my_cli_tool_spec.rb +52 -0
  16. data/Attic/spec/rspec-ex_spec.rb +10 -0
  17. data/Attic/spec/spec_helper.rb +104 -0
  18. data/Attic/test-15.1.rb +28 -0
  19. data/CHANGELOG.md +339 -0
  20. data/CONTRIBUTING.md +34 -0
  21. data/CONTRIBUTORS.md +16 -0
  22. data/Gemfile +16 -0
  23. data/Gemfile.lock +146 -0
  24. data/MIT-LICENSE +21 -0
  25. data/README.md +70 -0
  26. data/ROLL-OUT-STRATEGY.md +90 -0
  27. data/Rakefile +11 -0
  28. data/bin/kwalify +4167 -0
  29. data/bin/kwalify.rb +4167 -0
  30. data/bin/kwalify.schema.yaml +59 -0
  31. data/contrib/inline-require +181 -0
  32. data/contrib/kwalify +4167 -0
  33. data/contrib/kwalify-0.7.2 +4160 -0
  34. data/devbin/README.md +35 -0
  35. data/devbin/chk-rad-repo.sh +20 -0
  36. data/devbin/chkcopyrights.sh +42 -0
  37. data/devbin/chkspelling.sh +25 -0
  38. data/devbin/got-all-rel-numbers.sh +6 -0
  39. data/devbin/mkbig-rkwalify.sh +7 -0
  40. data/devbin/mkgem_file.sh +5 -0
  41. data/devbin/mktag +3 -0
  42. data/devbin/ruby_rails_wordlist.txt +195 -0
  43. data/devbin/runtests.sh +6 -0
  44. data/devbin/smoke-tests.golden +331 -0
  45. data/devbin/smoke-tests.sh +145 -0
  46. data/devbin/update-rel-numbers.sh +8 -0
  47. data/doc/docstyle.css +188 -0
  48. data/doc/img/fig01.png +0 -0
  49. data/doc/users-guide.html +2051 -0
  50. data/doc-api/classes/CommandOptionError.html +184 -0
  51. data/doc-api/classes/CommandOptionParser.html +325 -0
  52. data/doc-api/classes/Kwalify/AssertionError.html +148 -0
  53. data/doc-api/classes/Kwalify/BaseError.html +297 -0
  54. data/doc-api/classes/Kwalify/BaseParser.html +461 -0
  55. data/doc-api/classes/Kwalify/CommandOptionError.html +168 -0
  56. data/doc-api/classes/Kwalify/ErrorHelper.html +223 -0
  57. data/doc-api/classes/Kwalify/HashInterface.html +118 -0
  58. data/doc-api/classes/Kwalify/Json.html +105 -0
  59. data/doc-api/classes/Kwalify/KwalifyError.html +111 -0
  60. data/doc-api/classes/Kwalify/Main.html +339 -0
  61. data/doc-api/classes/Kwalify/MetaValidator.html +448 -0
  62. data/doc-api/classes/Kwalify/Parser.html +155 -0
  63. data/doc-api/classes/Kwalify/PlainYamlParser/Alias.html +165 -0
  64. data/doc-api/classes/Kwalify/PlainYamlParser.html +523 -0
  65. data/doc-api/classes/Kwalify/Rule.html +433 -0
  66. data/doc-api/classes/Kwalify/SchemaError.html +148 -0
  67. data/doc-api/classes/Kwalify/SyntaxError.html +185 -0
  68. data/doc-api/classes/Kwalify/Types.html +302 -0
  69. data/doc-api/classes/Kwalify/Util/HashLike.html +246 -0
  70. data/doc-api/classes/Kwalify/Util/OrderedHash.html +330 -0
  71. data/doc-api/classes/Kwalify/Util.html +390 -0
  72. data/doc-api/classes/Kwalify/ValidationError.html +148 -0
  73. data/doc-api/classes/Kwalify/Validator.html +381 -0
  74. data/doc-api/classes/Kwalify/Yaml/Parser.html +1538 -0
  75. data/doc-api/classes/Kwalify/Yaml.html +194 -0
  76. data/doc-api/classes/Kwalify/YamlParser.html +542 -0
  77. data/doc-api/classes/Kwalify/YamlSyntaxError.html +119 -0
  78. data/doc-api/classes/Kwalify.html +292 -0
  79. data/doc-api/classes/Test/Unit.html +101 -0
  80. data/doc-api/classes/Test.html +107 -0
  81. data/doc-api/created.rid +1 -0
  82. data/doc-api/files/__/README_txt.html +153 -0
  83. data/doc-api/files/kwalify/errors_rb.html +114 -0
  84. data/doc-api/files/kwalify/main_rb.html +118 -0
  85. data/doc-api/files/kwalify/messages_rb.html +107 -0
  86. data/doc-api/files/kwalify/meta-validator_rb.html +117 -0
  87. data/doc-api/files/kwalify/parser/base_rb.html +116 -0
  88. data/doc-api/files/kwalify/parser/yaml_rb.html +117 -0
  89. data/doc-api/files/kwalify/rule_rb.html +116 -0
  90. data/doc-api/files/kwalify/types_rb.html +114 -0
  91. data/doc-api/files/kwalify/util/assert-text-equal_rb.html +115 -0
  92. data/doc-api/files/kwalify/util/hash-interface_rb.html +114 -0
  93. data/doc-api/files/kwalify/util/hashlike_rb.html +107 -0
  94. data/doc-api/files/kwalify/util/option-parser_rb.html +107 -0
  95. data/doc-api/files/kwalify/util/ordered-hash_rb.html +107 -0
  96. data/doc-api/files/kwalify/util/testcase-helper_rb.html +115 -0
  97. data/doc-api/files/kwalify/util_rb.html +107 -0
  98. data/doc-api/files/kwalify/validator_rb.html +117 -0
  99. data/doc-api/files/kwalify/yaml-parser_rb.html +117 -0
  100. data/doc-api/files/kwalify_rb.html +121 -0
  101. data/doc-api/fr_class_index.html +57 -0
  102. data/doc-api/fr_file_index.html +45 -0
  103. data/doc-api/fr_method_index.html +168 -0
  104. data/doc-api/index.html +24 -0
  105. data/doc-api/rdoc-style.css +208 -0
  106. data/examples/address-book/Makefile +10 -0
  107. data/examples/address-book/address-book.schema.yaml +45 -0
  108. data/examples/address-book/address-book.yaml +36 -0
  109. data/examples/data-binding/BABEL.data.yaml +63 -0
  110. data/examples/data-binding/BABEL.schema.yaml +31 -0
  111. data/examples/data-binding/Makefile +8 -0
  112. data/examples/data-binding/Rakefile +13 -0
  113. data/examples/data-binding/main.rb +25 -0
  114. data/examples/invoice/Makefile +9 -0
  115. data/examples/invoice/invoice.schema.yaml +43 -0
  116. data/examples/invoice/invoice.yaml +32 -0
  117. data/examples/tapkit/Makefile +10 -0
  118. data/examples/tapkit/main.rb +7 -0
  119. data/examples/tapkit/tapkit.schema.yaml +146 -0
  120. data/examples/tapkit/tapkit.yaml +85 -0
  121. data/lib/kwalify/errors.rb +127 -0
  122. data/lib/kwalify/kwalify.schema.yaml +58 -0
  123. data/lib/kwalify/main.rb +442 -0
  124. data/lib/kwalify/messages.rb +173 -0
  125. data/lib/kwalify/meta-validator.rb +276 -0
  126. data/lib/kwalify/parser/base.rb +128 -0
  127. data/lib/kwalify/parser/yaml.rb +841 -0
  128. data/lib/kwalify/rule.rb +562 -0
  129. data/lib/kwalify/templates/genclass-java.eruby +222 -0
  130. data/lib/kwalify/templates/genclass-php.eruby +104 -0
  131. data/lib/kwalify/templates/genclass-ruby.eruby +113 -0
  132. data/lib/kwalify/types.rb +156 -0
  133. data/lib/kwalify/util/assert-text-equal.rb +46 -0
  134. data/lib/kwalify/util/hash-interface.rb +18 -0
  135. data/lib/kwalify/util/hashlike.rb +51 -0
  136. data/lib/kwalify/util/option-parser.rb +220 -0
  137. data/lib/kwalify/util/ordered-hash.rb +57 -0
  138. data/lib/kwalify/util/testcase-helper.rb +112 -0
  139. data/lib/kwalify/util.rb +159 -0
  140. data/lib/kwalify/validator.rb +282 -0
  141. data/lib/kwalify/version.rb +5 -0
  142. data/lib/kwalify/yaml-parser.rb +871 -0
  143. data/lib/kwalify.rb +61 -0
  144. data/rkwalify.gemspec +26 -0
  145. data/test/Rookbook.yaml +15 -0
  146. data/test/data/users-guide/AddressBook.java.expected +40 -0
  147. data/test/data/users-guide/BABEL.data.yaml +24 -0
  148. data/test/data/users-guide/BABEL.schema.yaml +30 -0
  149. data/test/data/users-guide/ExampleAddressBook.java +47 -0
  150. data/test/data/users-guide/Group.java.expected +24 -0
  151. data/test/data/users-guide/Person.java.expected +44 -0
  152. data/test/data/users-guide/address_book.rb +52 -0
  153. data/test/data/users-guide/address_book.schema.yaml +28 -0
  154. data/test/data/users-guide/address_book.yaml +27 -0
  155. data/test/data/users-guide/answers-schema.yaml +12 -0
  156. data/test/data/users-guide/answers-validator.rb +53 -0
  157. data/test/data/users-guide/babel_genclass.result +26 -0
  158. data/test/data/users-guide/config.schema.yaml +7 -0
  159. data/test/data/users-guide/config.yaml +4 -0
  160. data/test/data/users-guide/document01a.yaml +3 -0
  161. data/test/data/users-guide/document01b.yaml +3 -0
  162. data/test/data/users-guide/document02a.yaml +4 -0
  163. data/test/data/users-guide/document02b.yaml +4 -0
  164. data/test/data/users-guide/document03a.yaml +6 -0
  165. data/test/data/users-guide/document03b.yaml +6 -0
  166. data/test/data/users-guide/document04a.yaml +9 -0
  167. data/test/data/users-guide/document04b.yaml +9 -0
  168. data/test/data/users-guide/document05a.yaml +11 -0
  169. data/test/data/users-guide/document05b.yaml +12 -0
  170. data/test/data/users-guide/document06a.yaml +15 -0
  171. data/test/data/users-guide/document06b.yaml +16 -0
  172. data/test/data/users-guide/document07a.yaml +9 -0
  173. data/test/data/users-guide/document07b.yaml +7 -0
  174. data/test/data/users-guide/document12a.json +10 -0
  175. data/test/data/users-guide/document12b.json +6 -0
  176. data/test/data/users-guide/document13a.yaml +17 -0
  177. data/test/data/users-guide/document14a.yaml +3 -0
  178. data/test/data/users-guide/document14b.yaml +3 -0
  179. data/test/data/users-guide/document15a.yaml +6 -0
  180. data/test/data/users-guide/document15b.yaml +5 -0
  181. data/test/data/users-guide/example_address_book.rb +11 -0
  182. data/test/data/users-guide/example_address_book_java.result +32 -0
  183. data/test/data/users-guide/example_address_book_ruby.result +31 -0
  184. data/test/data/users-guide/genclass_java.result +4 -0
  185. data/test/data/users-guide/howto-validation-with-parsing.rb +28 -0
  186. data/test/data/users-guide/howto-validation.rb +25 -0
  187. data/test/data/users-guide/howto3.rb +6 -0
  188. data/test/data/users-guide/howto3.result +5 -0
  189. data/test/data/users-guide/howto3.yaml +8 -0
  190. data/test/data/users-guide/howto5_databinding.result +111 -0
  191. data/test/data/users-guide/invalid01.result +3 -0
  192. data/test/data/users-guide/invalid02.result +5 -0
  193. data/test/data/users-guide/invalid03.result +5 -0
  194. data/test/data/users-guide/invalid04.result +4 -0
  195. data/test/data/users-guide/invalid05.result +11 -0
  196. data/test/data/users-guide/invalid06.result +4 -0
  197. data/test/data/users-guide/invalid07.result +3 -0
  198. data/test/data/users-guide/invalid08.result +3 -0
  199. data/test/data/users-guide/invalid12.json +8 -0
  200. data/test/data/users-guide/invalid14.result +4 -0
  201. data/test/data/users-guide/invalid15.result +4 -0
  202. data/test/data/users-guide/loadbabel.rb +27 -0
  203. data/test/data/users-guide/loadconfig.rb +17 -0
  204. data/test/data/users-guide/loadconfig.result +6 -0
  205. data/test/data/users-guide/models.rb +24 -0
  206. data/test/data/users-guide/option_ha.result +6 -0
  207. data/test/data/users-guide/option_ha_genclass_java.result +7 -0
  208. data/test/data/users-guide/schema01.yaml +3 -0
  209. data/test/data/users-guide/schema02.yaml +12 -0
  210. data/test/data/users-guide/schema03.yaml +9 -0
  211. data/test/data/users-guide/schema04.yaml +20 -0
  212. data/test/data/users-guide/schema05.yaml +29 -0
  213. data/test/data/users-guide/schema06.yaml +11 -0
  214. data/test/data/users-guide/schema12.json +12 -0
  215. data/test/data/users-guide/schema13.yaml +13 -0
  216. data/test/data/users-guide/schema14.yaml +5 -0
  217. data/test/data/users-guide/schema15.yaml +21 -0
  218. data/test/data/users-guide/valid01.result +2 -0
  219. data/test/data/users-guide/valid02.result +2 -0
  220. data/test/data/users-guide/valid03.result +2 -0
  221. data/test/data/users-guide/valid04.result +2 -0
  222. data/test/data/users-guide/valid05.result +2 -0
  223. data/test/data/users-guide/valid06.result +2 -0
  224. data/test/data/users-guide/valid07.result +2 -0
  225. data/test/data/users-guide/valid08.result +2 -0
  226. data/test/data/users-guide/valid12.result +2 -0
  227. data/test/data/users-guide/valid13.result +2 -0
  228. data/test/data/users-guide/valid14.result +2 -0
  229. data/test/data/users-guide/valid15.result +2 -0
  230. data/test/data/users-guide/validate08.rb +37 -0
  231. data/test/test-action.rb +73 -0
  232. data/test/test-action.yaml +738 -0
  233. data/test/test-databinding.rb +84 -0
  234. data/test/test-databinding.yaml +339 -0
  235. data/test/test-main.rb +156 -0
  236. data/test/test-main.yaml +409 -0
  237. data/test/test-metavalidator.rb +80 -0
  238. data/test/test-metavalidator.yaml +1179 -0
  239. data/test/test-parser-yaml.rb +57 -0
  240. data/test/test-parser-yaml.yaml +1753 -0
  241. data/test/test-rule.rb +26 -0
  242. data/test/test-rule.yaml +317 -0
  243. data/test/test-users-guide.rb +82 -0
  244. data/test/test-util.rb +125 -0
  245. data/test/test-validator.rb +95 -0
  246. data/test/test-validator.yaml +986 -0
  247. data/test/test-yaml-parser.rb +47 -0
  248. data/test/test-yaml-parser.yaml +1226 -0
  249. data/test/test.rb +77 -0
  250. metadata +297 -0
@@ -0,0 +1,51 @@
1
+ ###
2
+ ### $Rev$
3
+ ### $Release 1.4.0-beta $
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.method_defined?('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 1.4.0-beta $
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
+ ### Release 1.4.0-beta
4
+ ### $COPYRIGHT$
5
+ ###
6
+
7
+ module Kwalify
8
+
9
+ module Util
10
+
11
+ class OrderedHash < Hash
12
+
13
+ def initialize(*args, &)
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 1.4.0-beta $
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_stream(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
@@ -0,0 +1,159 @@
1
+ ###
2
+ ### $Rev$
3
+ ### $Release 1.4.0-beta $
4
+ ### copyright(c) 2005-2010 kuwata-lab all rights reserved.
5
+ ###
6
+ # frozen_string_literal: false
7
+
8
+ module Kwalify
9
+
10
+ module Util
11
+
12
+ module_function
13
+
14
+ ##
15
+ ## expand tab character to spaces
16
+ ##
17
+ ## ex.
18
+ ## untabified_str = YamlHelper.untabify(tabbed_str)
19
+ ##
20
+ def untabify(str, width=8)
21
+ return str if str.nil?
22
+ list = str.split("\t", -1) # if 2nd arg is negative then split() doesn't remove tailing empty strings
23
+ last = list.pop
24
+ sb = ''
25
+ list.each do |s|
26
+ column = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length
27
+ n = width - (column % width)
28
+ sb << s << (' ' * n)
29
+ end
30
+ sb << last if last
31
+ return sb
32
+ end
33
+
34
+
35
+ ## traverse schema
36
+ ##
37
+ ## ex.
38
+ ## schema = YAML.load_file('myschema.yaml')
39
+ ## Kwalify::Util.traverse_schema(schema) do |rulehash|
40
+ ## ## add module prefix to class name
41
+ ## if rulehash['class']
42
+ ## rulehash['class'] = 'MyModule::' + rulehash['class']
43
+ ## end
44
+ ## end
45
+ def traverse_schema(schema, &) #:yield: rulehash
46
+ hash = schema
47
+ _done = {}
48
+ _traverse_schema(hash, _done, &)
49
+ end
50
+
51
+ def _traverse_schema(hash, _done={}, &)
52
+ return if _done.key?(hash.__id__)
53
+ _done[hash.__id__] = hash
54
+ yield hash
55
+ if hash['mapping']
56
+ hash['mapping'].each {|k, v| _traverse_schema(v, _done, &) }
57
+ elsif hash['sequence']
58
+ _traverse_schema(hash['sequence'][0], _done, &)
59
+ end
60
+ end
61
+ private :_traverse_schema
62
+
63
+
64
+ ## traverse rule
65
+ ##
66
+ ## ex.
67
+ ## schema = YAML.load_file('myschema.yaml')
68
+ ## validator = Kwalify::Validator.new(schema)
69
+ ## Kwalify::Util.traverse_rule(validator) do |rule|
70
+ ## p rule if rule.classname
71
+ ## end
72
+ def traverse_rule(validator, &) #:yield: rule
73
+ rule = validator.is_a?(Rule) ? validator : validator.rule
74
+ _done = {}
75
+ _traverse_rule(rule, _done, &)
76
+ end
77
+
78
+ def _traverse_rule(rule, _done={}, &)
79
+ return if _done.key?(rule.__id__)
80
+ _done[rule.__id__] = rule
81
+ yield rule
82
+ rule.sequence.each do |seq_rule|
83
+ _traverse_rule(seq_rule, _done, &)
84
+ end if rule.sequence
85
+ rule.mapping.each do |name, map_rule|
86
+ _traverse_rule(map_rule, _done, &)
87
+ end if rule.mapping
88
+ end
89
+ private :_traverse_rule
90
+
91
+
92
+ ##
93
+ ## get class object. if not found, NameError raised.
94
+ ##
95
+ def get_class(classname)
96
+ klass = Object
97
+ classname.split('::').each do |name|
98
+ klass = klass.const_get(name)
99
+ end
100
+ return klass
101
+ end
102
+
103
+
104
+ ##
105
+ ## create a hash table from list of hash with primary key.
106
+ ##
107
+ ## ex.
108
+ ## hashlist = [
109
+ ## { "name"=>"Foo", "gender"=>"M", "age"=>20, },
110
+ ## { "name"=>"Bar", "gender"=>"F", "age"=>25, },
111
+ ## { "name"=>"Baz", "gender"=>"M", "age"=>30, },
112
+ ## ]
113
+ ## hashtable = YamlHelper.create_hashtable(hashlist, "name")
114
+ ## p hashtable
115
+ ## # => { "Foo" => { "name"=>"Foo", "gender"=>"M", "age"=>20, },
116
+ ## # "Bar" => { "name"=>"Bar", "gender"=>"F", "age"=>25, },
117
+ ## # "Baz" => { "name"=>"Baz", "gender"=>"M", "age"=>30, }, }
118
+ ##
119
+ def create_hashtable(hashlist, primarykey, flag_duplicate_check=true)
120
+ hashtable = {}
121
+ hashlist.each do |hash|
122
+ key = hash[primarykey]
123
+ unless key
124
+ riase "primary key '#{key}' not found."
125
+ end
126
+ if flag_duplicate_check && hashtable.key?(key)
127
+ raise "primary key '#{key}' duplicated (value '#{hashtable[key]}')"
128
+ end
129
+ hashtable[key] = hash
130
+ end if hashlist
131
+ return hashtable
132
+ end
133
+
134
+
135
+ ##
136
+ ## get nested value directly.
137
+ ##
138
+ ## ex.
139
+ ## val = YamlHelper.get_value(obj, ['aaa', 0, 'xxx'])
140
+ ##
141
+ ## This is equal to the following:
142
+ ## begin
143
+ ## val = obj['aaa'][0]['xxx']
144
+ ## rescue NameError
145
+ ## val = nil
146
+ ## end
147
+ ##
148
+ def get_value(obj, path)
149
+ val = obj
150
+ path.each do |key|
151
+ return nil unless val.is_a?(Hash) || val.is_a?(Array)
152
+ val = val[key]
153
+ end if path
154
+ return val
155
+ end
156
+
157
+ end
158
+
159
+ end