pione 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. data/.gitignore +3 -2
  2. data/History.txt +6 -0
  3. data/Rakefile +1 -1
  4. data/bin/pione-broker +1 -1
  5. data/bin/pione-clean +1 -1
  6. data/bin/pione-client +1 -1
  7. data/bin/pione-log +1 -1
  8. data/bin/pione-relay +1 -1
  9. data/bin/pione-relay-account-db +1 -1
  10. data/bin/pione-relay-client-db +1 -1
  11. data/bin/pione-syntax-checker +1 -1
  12. data/bin/pione-task-worker +1 -1
  13. data/bin/pione-tuple-space-provider +1 -1
  14. data/bin/pione-tuple-space-receiver +1 -1
  15. data/bin/pione-tuple-space-viewer +1 -1
  16. data/bin/pione-val +1 -1
  17. data/example/CTFCorrection/CTFCorrection.pione +78 -0
  18. data/example/CTFCorrection/package.yml +1 -0
  19. data/example/HelloWorld/scenario/output/message.txt +1 -0
  20. data/example/LoopByTouch/LoopByTouch.pione +10 -18
  21. data/example/LoopByTouch/PairLoop.pione +18 -0
  22. data/example/LoopByTouch/SingleLoop.pione +5 -0
  23. data/example/LoopByTouch/TripletLoop.pione +24 -0
  24. data/example/MakePair/scenario/output/comb-1-2.pair +0 -0
  25. data/example/MakePair/scenario/output/comb-1-3.pair +0 -0
  26. data/example/MakePair/scenario/output/comb-1-4.pair +0 -0
  27. data/example/MakePair/scenario/output/comb-1-5.pair +0 -0
  28. data/example/MakePair/scenario/output/comb-2-3.pair +0 -0
  29. data/example/MakePair/scenario/output/comb-2-4.pair +0 -0
  30. data/example/MakePair/scenario/output/comb-2-5.pair +0 -0
  31. data/example/MakePair/scenario/output/comb-3-4.pair +0 -0
  32. data/example/MakePair/scenario/output/comb-3-5.pair +0 -0
  33. data/example/MakePair/scenario/output/comb-4-5.pair +0 -0
  34. data/example/MakePair/scenario/output/perm-1-2.pair +0 -0
  35. data/example/MakePair/scenario/output/perm-1-3.pair +0 -0
  36. data/example/MakePair/scenario/output/perm-1-4.pair +0 -0
  37. data/example/MakePair/scenario/output/perm-1-5.pair +0 -0
  38. data/example/MakePair/scenario/output/perm-2-1.pair +0 -0
  39. data/example/MakePair/scenario/output/perm-2-3.pair +0 -0
  40. data/example/MakePair/scenario/output/perm-2-4.pair +0 -0
  41. data/example/MakePair/scenario/output/perm-2-5.pair +0 -0
  42. data/example/MakePair/scenario/output/perm-3-1.pair +0 -0
  43. data/example/MakePair/scenario/output/perm-3-2.pair +0 -0
  44. data/example/MakePair/scenario/output/perm-3-4.pair +0 -0
  45. data/example/MakePair/scenario/output/perm-3-5.pair +0 -0
  46. data/example/MakePair/scenario/output/perm-4-1.pair +0 -0
  47. data/example/MakePair/scenario/output/perm-4-2.pair +0 -0
  48. data/example/MakePair/scenario/output/perm-4-3.pair +0 -0
  49. data/example/MakePair/scenario/output/perm-4-5.pair +0 -0
  50. data/example/MakePair/scenario/output/perm-5-1.pair +0 -0
  51. data/example/MakePair/scenario/output/perm-5-2.pair +0 -0
  52. data/example/MakePair/scenario/output/perm-5-3.pair +0 -0
  53. data/example/MakePair/scenario/output/perm-5-4.pair +0 -0
  54. data/example/MakePair/scenario/output/succ-1-2.pair +0 -0
  55. data/example/MakePair/scenario/output/succ-2-3.pair +0 -0
  56. data/example/MakePair/scenario/output/succ-3-4.pair +0 -0
  57. data/example/MakePair/scenario/output/succ-4-5.pair +0 -0
  58. data/example/SyntaxError/output_line_error.pione +6 -0
  59. data/example/WorkflowPatterns/38_GeneralSynchronizingMerge/GeneralSynchronizingMerge.pione +94 -0
  60. data/lib/pione.rb +1 -10
  61. data/lib/pione/agent/process-manager.rb +6 -5
  62. data/lib/pione/agent/rule-provider.rb +7 -9
  63. data/lib/pione/agent/task-worker.rb +1 -1
  64. data/lib/pione/command.rb +1 -0
  65. data/lib/pione/command/basic-command.rb +12 -77
  66. data/lib/pione/command/child-process.rb +19 -13
  67. data/lib/pione/command/daemon-process.rb +0 -9
  68. data/lib/pione/command/front-owner-command.rb +0 -6
  69. data/lib/pione/command/option.rb +243 -0
  70. data/lib/pione/command/pione-broker.rb +10 -5
  71. data/lib/pione/command/pione-clean.rb +4 -0
  72. data/lib/pione/command/pione-client.rb +257 -210
  73. data/lib/pione/command/pione-log.rb +38 -19
  74. data/lib/pione/command/pione-relay-account-db.rb +42 -17
  75. data/lib/pione/command/pione-relay-client-db.rb +35 -14
  76. data/lib/pione/command/pione-relay.rb +16 -8
  77. data/lib/pione/command/pione-syntax-checker.rb +33 -13
  78. data/lib/pione/command/pione-task-worker.rb +26 -23
  79. data/lib/pione/command/pione-tuple-space-provider.rb +8 -17
  80. data/lib/pione/command/pione-tuple-space-receiver.rb +13 -3
  81. data/lib/pione/command/pione-tuple-space-viewer.rb +42 -23
  82. data/lib/pione/command/pione-val.rb +15 -7
  83. data/lib/pione/component/document.rb +49 -70
  84. data/lib/pione/component/package.rb +125 -83
  85. data/lib/pione/location/basic-location.rb +1 -0
  86. data/lib/pione/model/assignment.rb +11 -0
  87. data/lib/pione/model/parameters.rb +10 -0
  88. data/lib/pione/model/variable.rb +14 -0
  89. data/lib/pione/parser/common-parser.rb +4 -0
  90. data/lib/pione/parser/document-parser.rb +4 -3
  91. data/lib/pione/parser/rule-definition-parser.rb +2 -1
  92. data/lib/pione/patch/rinda-patch.rb +1 -1
  93. data/lib/pione/rule-handler/action-handler.rb +6 -1
  94. data/lib/pione/rule-handler/basic-handler.rb +0 -6
  95. data/lib/pione/rule-handler/flow-handler.rb +14 -9
  96. data/lib/pione/system/global.rb +3 -0
  97. data/lib/pione/system/package-cache.rb +18 -0
  98. data/lib/pione/transformer/document-transformer.rb +26 -3
  99. data/lib/pione/transformer/rule-definition-transformer.rb +10 -2
  100. data/lib/pione/tuple-space/presence-notifier.rb +4 -3
  101. data/lib/pione/uri-scheme.rb +11 -0
  102. data/lib/pione/uri-scheme/git-scheme.rb +12 -0
  103. data/lib/pione/util.rb +2 -0
  104. data/lib/pione/util/package-parameters-list.rb +32 -0
  105. data/lib/pione/util/process-info.rb +21 -0
  106. data/lib/pione/version.rb +1 -1
  107. data/pione.gemspec +1 -1
  108. data/test/agent/spec_rule-provider.rb +57 -44
  109. data/test/command/command-behavior.rb +15 -0
  110. data/test/command/spec_pione-client.rb +56 -0
  111. data/test/command/spec_pione-val.domain.dump +0 -0
  112. data/test/command/spec_pione-val.rb +22 -0
  113. data/test/component/spec_document.pione +51 -0
  114. data/test/component/spec_document.rb +41 -70
  115. data/test/component/spec_package.rb +18 -3
  116. data/test/parser/spec_document-parser.yml +15 -0
  117. data/test/parser/spec_rule-definition-parser.yml +7 -2
  118. data/test/rule-handler/spec_action-handler.rb +6 -6
  119. data/test/rule-handler/spec_flow-handler.pione +25 -0
  120. data/test/rule-handler/spec_flow-handler.rb +35 -95
  121. data/test/rule-handler/spec_update-criteria.rb +2 -2
  122. data/test/test-util.rb +68 -4
  123. data/test/transformer/spec_block-transformer.rb +1 -1
  124. data/test/transformer/spec_document-transformer.rb +50 -0
  125. data/test/transformer/spec_expr-transformer.rb +1 -1
  126. data/test/transformer/spec_flow-element-transformer.rb +13 -13
  127. data/test/transformer/spec_literal-transformer.rb +1 -1
  128. data/test/transformer/spec_rule-definition-transformer.rb +31 -19
  129. data/test/uri-scheme/spec_git-scheme.rb +20 -0
  130. data/test/util/spec_id.rb +6 -6
  131. data/test/util/spec_package-parameters-list.rb +59 -0
  132. data/test/util/spec_package-parameters-list_1.pione +17 -0
  133. data/test/util/spec_package-parameters-list_2.pione +13 -0
  134. data/test/util/spec_package-parameters-list_3.pione +12 -0
  135. data/test/util/spec_package-parameters-list_4.pione +6 -0
  136. data/test/util/spec_process-info.rb +56 -0
  137. metadata +79 -16
  138. data/lib/pione/option.rb +0 -13
  139. data/lib/pione/option/child-process-option.rb +0 -19
  140. data/lib/pione/option/common-option.rb +0 -31
  141. data/lib/pione/option/option-interface.rb +0 -73
  142. data/lib/pione/option/presence-notifier-option.rb +0 -16
  143. data/lib/pione/option/task-worker-owner-option.rb +0 -24
  144. data/lib/pione/option/tuple-space-provider-option.rb +0 -28
  145. data/lib/pione/option/tuple-space-provider-owner-option.rb +0 -18
  146. data/lib/pione/option/tuple-space-receiver-option.rb +0 -8
@@ -18,10 +18,20 @@ TXT
18
18
  end
19
19
 
20
20
  define_option do
21
- use Option::PresenceNotifierOption
21
+ use :debug
22
+ use :color
23
+ use :my_ip_address
24
+ use :no_parent
25
+ use :parent_front
26
+ use :show_communication
27
+ use :show_presence_notifier
22
28
 
23
- option("--presence-port=PORT", "set presence port number") do |data, port|
24
- Global.presence_port = port.to_i
29
+ define(:presence_port) do |item|
30
+ item.long = "--presence-port=PORT"
31
+ item.desc = "set presence port number"
32
+ item.action = lambda do |option, port|
33
+ Global.presence_port = port.to_i
34
+ end
25
35
  end
26
36
  end
27
37
 
@@ -9,46 +9,65 @@ module Pione
9
9
  end
10
10
 
11
11
  define_option do
12
- default :identifiers, []
13
- default :exclusions, []
14
-
15
- option('-i', '--identifier=NAME', 'show tuples that have the identifier') do |data, name|
16
- data[:identifiers] << name
12
+ use :color
13
+ use :debug
14
+ use :show_communication
15
+
16
+ define(:identifiers) do |item|
17
+ item.short = '-i'
18
+ item.long = '--identifier=NAME'
19
+ item.desc = 'show tuples that have the identifier'
20
+ item.default = []
21
+ item.values = lambda {|name| name}
17
22
  end
18
23
 
19
- option('-e', '--exclude=NAME', 'exclude the tuple identifier') do |data, name|
20
- data[:exclusions] << name
24
+ define(:exclusions) do |item|
25
+ item.short = '-e'
26
+ item.long = '--exclude=NAME'
27
+ item.desc = 'exclude the tuple identifier'
28
+ item.default = []
29
+ item.values = lambda {|name| name}
21
30
  end
22
31
 
23
- option('--package=NAME', 'show tuples which domain has the package name') do |data, name|
24
- data[:package] = name
32
+ define(:package) do |item|
33
+ item.long = '--package=NAME'
34
+ item.desc = 'show tuples which domain has the package name'
35
+ item.value = lambda {|name| name}
25
36
  end
26
37
 
27
- option('--rule=NAME', 'show tuples which domain has the rule name') do |data, name|
28
- data[:rule] = name
38
+ define(:rule) do |item|
39
+ item.long = '--rule=NAME'
40
+ item.desc = 'show tuples which domain has the rule name'
41
+ item.value = lambda {|name| name}
29
42
  end
30
43
 
31
- option('--rule-path=NAME', 'show tuples which domain has the rule path') do |data, path|
32
- data[:rule_path] = path
44
+ define(:rule_path) do |item|
45
+ item.long = '--rule-path=NAME'
46
+ item.desc = 'show tuples which domain has the rule path'
47
+ item.value = lambda {|path| path}
33
48
  end
34
49
 
35
- option('--data-name=NAME', 'show tuples that has the the name') do |data, name|
36
- data[:data_name] = name
50
+ define(:data_name) do |item|
51
+ item.long = '--data-name=NAME'
52
+ item.desc = 'show tuples that has the the name'
53
+ item.value = lambda {|name| name}
37
54
  end
38
55
 
39
- option(
40
- '--type=TYPE',
41
- 'show the bag which has the type("bag", "read_waiter", or "take_waiter")'
42
- ) do |data, bag_type|
43
- data[:bag_type] = bag_type.to_sym
56
+ define(:bag_type) do |item|
57
+ item.long = '--type=TYPE'
58
+ item.desc = 'show the bag which has the type("bag", "read_waiter", or "take_waiter")'
59
+ item.value = lambda {|bag_type| bag_type.to_sym}
44
60
  end
45
61
 
46
- option('--client=ADDRESS', 'druby address of target client process') do |data, address|
47
- data[:address] = address
62
+ define(:address) do |item|
63
+ item.long = '--client=ADDRESS'
64
+ item.desc = 'druby address of target client process'
65
+ item.value = lambda {|address| address}
48
66
  end
49
67
  end
50
68
 
51
- def initialize
69
+ def initialize(*argv)
70
+ super
52
71
  @tuple_space_servers = []
53
72
  end
54
73
 
@@ -1,24 +1,26 @@
1
1
  module Pione
2
2
  module Command
3
- # PioneSyntaxChecker is a command for checking syntax tree and model of the
4
- # PIONE document.
5
- class PioneEval < BasicCommand
3
+ # PioneVal command enables you to get evaluation result of PIONE expressions from out of PIONE system.
4
+ class PioneVal < BasicCommand
6
5
  define_info do
7
6
  set_name "pione-val"
8
7
  set_banner "Get the evaluation result value of the PIONE expression."
9
8
  end
10
9
 
11
10
  define_option do
12
- default :domain_info, Location["./domain.dump"]
11
+ use :debug
13
12
 
14
- option('--domain-info=LOCATION', 'location of Domain info file') do |data, location|
15
- data[:domain_info] = Location[location]
13
+ define(:domain_info) do |item|
14
+ item.long = '--domain-info=LOCATION'
15
+ item.desc = 'location of Domain info file'
16
+ item.default = Location["./domain.dump"]
17
+ item.value = lambda {|location| Location[location]}
16
18
  end
17
19
  end
18
20
 
19
21
  start do
20
22
  # get expression string
21
- str = ARGV[0] || abort("no expressions")
23
+ str = @argv.first || abort("no expressions")
22
24
 
23
25
  # setup domain info
24
26
  domain_info = nil
@@ -30,6 +32,12 @@ module Pione
30
32
  # evaluate it and print the result
31
33
  $stdout.puts Pione.val(str, domain_info)
32
34
  exit
35
+ rescue Model::UnboundVariableError => e
36
+ if option[:domain_info].exist?
37
+ raise
38
+ else
39
+ abort("domain info file '%s' not found" % option[:domain_info].uri.to_s)
40
+ end
33
41
  rescue => e
34
42
  abort("error: %s" % e)
35
43
  end
@@ -1,91 +1,70 @@
1
1
  module Pione
2
2
  module Component
3
- class Document < PioneObject
4
- # Add ruby shebang line.
5
- def ruby(str, charset=nil)
6
- res = "#!/usr/bin/env ruby\n"
7
- res << "# -*- coding: #{charset} -*-\n" if charset
8
- return res + str
3
+ class DuplicatedRuleError < StandardError
4
+ def initialize(rule_path)
5
+ @rule_path = rule_path
9
6
  end
10
7
 
11
- # Load a rule document and return it.
12
- def self.load(filepath, package_name="main")
13
- filepath = Location[filepath] unless filepath.kind_of?(Location::BasicLocation)
14
- parse(filepath.read, package_name)
8
+ def message
9
+ "There are duplicated rule %s in docuemtn" % @rule_path
15
10
  end
11
+ end
16
12
 
17
- # Parse a rule document string.
18
- def self.parse(src, package_name="main")
19
- src = src.read if src.kind_of?(Location::BasicLocation)
20
- # parse the document and build the model
21
- parser = Parser::DocumentParser.new
22
- transformer = Transformer::DocumentTransformer.new(package_name)
23
- toplevels = transformer.apply(parser.parse(src))
24
-
25
- # rules and assignments
26
- rules = toplevels.select{|elt| elt.kind_of?(Component::Rule)}
27
- assignments = toplevels.select{|elt| elt.kind_of?(Assignment)}
28
- assignments.each {|assignment| assignment.set_toplevel(true)}
29
- user_params = Naming::ParamLine.values(toplevels)
30
- Naming::ParamBlock.values(toplevels).each do |elts|
31
- user_params += elts
32
- end
33
- assignments += user_params.map do |param|
34
- param.tap do |x|
35
- x.set_toplevel(true)
36
- x.set_user_param(true)
37
- end
38
- end
13
+ class Document < StructX
14
+ class << self
15
+ # Load a PIONE rule document.
16
+ #
17
+ # @param location [Location,String]
18
+ # location of the PIONE document
19
+ # @return [Component::Document]
20
+ # the document
21
+ def load(src, package_name="Main")
22
+ src = src.read if src.kind_of?(Location::BasicLocation)
39
23
 
40
- # make document parameters
41
- params = assignments.inject(VariableTable.empty) do |vtable, a|
42
- vtable.tap{|t| t.set(a.variable, a.expr)}
43
- end.to_params
24
+ # parse the document and build the model
25
+ parser = Parser::DocumentParser.new
26
+ transformer = Transformer::DocumentTransformer.new(package_name)
27
+ toplevels = transformer.apply(parser.parse(src))
44
28
 
45
- # set document parameters into rules
46
- rules.each {|rule| rule.condition.params.merge!(params)}
29
+ # rules and assignments
30
+ rules = toplevels.select{|elt| elt.kind_of?(Component::Rule)}
31
+ assignments = Naming[:AssignmentLine, :ParamLine, :ParamBlock].values(toplevels).flatten
47
32
 
48
- # make rule table
49
- table = rules.inject({}) do |tbl, rule|
50
- tbl.tap{|x| x[rule.path] = rule}
51
- end
52
- return new(table, params)
53
- end
33
+ # make document parameters
34
+ params = assignments.inject(VariableTable.empty) do |vtable, a|
35
+ vtable.tap{|t| t.set(a.variable, a.expr)}
36
+ end.to_params
54
37
 
55
- attr_reader :rules
56
- attr_reader :params
38
+ # set document parameters into rules
39
+ rules.each {|rule| rule.condition.params.merge!(params)}
57
40
 
58
- # Creates a document.
59
- def initialize(rules, params)
60
- @rules = rules
61
- @params = params
62
- instance_eval(&b) if block_given?
41
+ return new(package_name, rules, params)
42
+ end
63
43
  end
64
44
 
65
- # Returns the named rule.
66
- # @param [String] name
67
- # rule path
68
- # @return [Pione::Model::Rule]
69
- def [](name)
70
- @rules[name].condition.params.merge!(@params)
71
- @rules[name]
72
- end
45
+ member :package_name
46
+ member :rules
47
+ member :params
73
48
 
74
- # Returns main rule of main package.
75
- # @return [Rule]
76
- # main rule of main package
77
- def main
78
- @rules["&main:Main"].condition.params.merge!(@params)
79
- @rules["&main:Main"]
49
+ # Find the named rule.
50
+ #
51
+ # @param name [String]
52
+ # rule name
53
+ # @return [Component::Rule]
54
+ def find(name)
55
+ rules.find {|rule| rule.name == name}
80
56
  end
81
57
 
82
- # Returns root rule.
58
+ # Create a root rule which calls the rule with the parameters.
59
+ #
60
+ # @param rule [Component::Rule]
61
+ # rule that is called by the root rule
83
62
  # @param [Parameters] params
84
- # root root parameter
85
- # @return [RootRule]
63
+ # user parameters
64
+ # @return [Component::RootRule]
86
65
  # root rule
87
- def root_rule(params)
88
- Component::RootRule.new(main, @params.merge(params))
66
+ def create_root_rule(rule, user_params)
67
+ Component::RootRule.new(rule, params.merge(user_params))
89
68
  end
90
69
  end
91
70
  end
@@ -14,72 +14,30 @@ module Pione
14
14
  end
15
15
  end
16
16
 
17
- # Package is a container of rules, script, scenario, and etc.
18
- class Package
19
- include SimpleIdentity
20
-
21
- attr_reader :info
22
- attr_reader :bin
23
- attr_reader :scenarios
24
- attr_reader :documents
25
- attr_reader :rules
26
- attr_reader :params
27
-
28
- forward_as_key :@info, "PackageName", :name
29
-
30
- # @param info [Hash]
31
- # package information table
32
- # @param bin [Location]
33
- # package bin directory
34
- # @param scenarios [Array<PackageScenario>]
35
- # scenarios
36
- # @param documents [Array<Document>]
37
- # PIONE documents
38
- def initialize(info, bin, scenarios, documents)
39
- @info = info
40
- @bin = bin
41
- @scenarios = scenarios
42
- @documents = documents
43
- build_rules
44
- build_params
45
- end
46
-
47
- # Return the package entry rule.
48
- #
49
- # @return [Rule]
50
- # entry rule
51
- def main
52
- @rules["&%s:Main" % name].tap{|x| x.condition.params.merge!(@params)}
53
- end
54
-
55
- # Return the named rule.
56
- #
57
- # @param [String] name
58
- # rule path
59
- # @return [Rule]
60
- # the rule
61
- def [](name)
62
- @rules[name].params.merge!(@params)
63
- @rules[name]
64
- end
65
-
66
- # Return root rule.
67
- #
68
- # @param prams [Parameters]
69
- # root parameters
70
- # @return [RootRule]
71
- # root rule
72
- def root_rule(params)
73
- Component::RootRule.new(main, @params.merge(params))
17
+ # Package is a container of rules, scripts, scenarios, and etc.
18
+ class Package < StructX
19
+ member :info, default: {}
20
+ member :bin
21
+ member :scenarios, default: []
22
+ member :documents, default: []
23
+
24
+ forward_as_key Proc.new{info}, "PackageName", :name
25
+ forward :@unified_document, :find, :find_rule
26
+ forward! :@unified_document, :rules, :create_root_rule, :params
27
+
28
+ def initialize(*args)
29
+ super(*args)
30
+ build_unified_document
31
+ validate
74
32
  end
75
33
 
76
34
  # Upload the package files to the location.
77
35
  #
78
36
  # @return [void]
79
37
  def upload(dest)
80
- if @bin.exist?
38
+ if bin and bin.exist?
81
39
  # upload bin files
82
- @bin.entries.each do |entry|
40
+ bin.entries.each do |entry|
83
41
  entry.copy(dest + name + "bin" + entry.basename)
84
42
  end
85
43
  end
@@ -93,34 +51,31 @@ module Pione
93
51
  # the scenario
94
52
  def find_scenario(name)
95
53
  if name == :anything
96
- @scenarios.first
54
+ scenarios.first
97
55
  else
98
- @scenarios.find {|scenario| scenario.name == name}
56
+ scenarios.find {|scenario| scenario.name == name}
99
57
  end
100
58
  end
101
59
 
102
60
  private
103
61
 
104
- # Build rules from all documents in the package.
105
- def build_rules
106
- @rules = {}
107
- @documents.each do |doc|
108
- doc.rules.each do |name, rule|
109
- unless @rules[name]
110
- @rules[name] = rule
111
- else
112
- raise InvalidPackage.new(self, "duplicated rules: %s" % name)
113
- end
114
- end
62
+ # Build an unified document from all documents in the package.
63
+ def build_unified_document
64
+ rules = documents.map{|doc| doc.rules}.flatten
65
+ params = documents.inject(Model::Parameters.empty) do |_params, document|
66
+ _params.merge(document.params)
115
67
  end
68
+ @unified_document = Component::Document.new(name, rules, params)
116
69
  end
117
70
 
118
- # Build parameters from all documents in the package.
119
- def build_params
120
- @params = Model::Parameters.empty
121
- @documents.each do |doc|
122
- doc.params.each do |param|
123
- @params.merge!(param)
71
+ # Validate package consistency.
72
+ def validate
73
+ @unified_document.rules.map{|rule| rule.path}.sort.inject do |prev, elt|
74
+ if prev == elt
75
+ msg = "There are duplicated rules '%s' in the package '%s'"
76
+ raise InvalidPackage.new(self, msg % [name, package])
77
+ else
78
+ elt
124
79
  end
125
80
  end
126
81
  end
@@ -128,10 +83,26 @@ module Pione
128
83
 
129
84
  # PackageReader is a reader for packages.
130
85
  class PackageReader
86
+ class << self
87
+ # Read a pacakge from the location.
88
+ #
89
+ # @param location [Location::BasicLocation]
90
+ # location of package
91
+ # @return [Package]
92
+ # the package
93
+ def read(location)
94
+ new(location).read
95
+ end
96
+ end
97
+
98
+ attr_reader :location
99
+ attr_reader :type
100
+
131
101
  # @param location [Location]
132
102
  # package location
133
103
  def initialize(location)
134
104
  @location = location
105
+ @type = check_package_type
135
106
  end
136
107
 
137
108
  # Read the package.
@@ -139,15 +110,51 @@ module Pione
139
110
  # @return [Package]
140
111
  # the package
141
112
  def read
142
- infos = read_package_info
143
- bin = @location + "bin"
144
- scenarios = find_scenarios
145
- documents = find_documents(infos["PackageName"])
146
- Package.new(infos, bin, scenarios, documents)
113
+ case @type
114
+ when :directory
115
+ return read_package_directory
116
+ when :pione_document_file
117
+ return read_pione_document_file
118
+ end
147
119
  end
148
120
 
149
121
  private
150
122
 
123
+ # Check package type.
124
+ #
125
+ # @return [Symbol]
126
+ # package type
127
+ def check_package_type
128
+ return :directory if @location.directory?
129
+ if File.extname(@location.basename) == ".pione"
130
+ return :pione_document_file
131
+ end
132
+ raise ArgumentError.new(@location)
133
+ end
134
+
135
+ # Read package directory.
136
+ #
137
+ # @return [Package]
138
+ # the package
139
+ def read_package_directory
140
+ info = read_package_info
141
+ Package.new(
142
+ info: info,
143
+ bin: @location + "bin",
144
+ scenarios: find_scenarios,
145
+ documents: find_documents(info["PackageName"])
146
+ )
147
+ end
148
+
149
+ # Read PIONE document.
150
+ #
151
+ # @return [Package]
152
+ # the package
153
+ def read_pione_document_file
154
+ document = Component::Document.load(@location, "Main")
155
+ Package.new(info: {"PackageName" => "Main"}, documents: [document])
156
+ end
157
+
151
158
  # Read the informations from the package location.
152
159
  #
153
160
  # @return [Hash]
@@ -187,6 +194,22 @@ module Pione
187
194
  end
188
195
  end
189
196
 
197
+ # RehearsalResult represents error result of rehearsal test.
198
+ class RehearsalResult < StructX
199
+ member :key
200
+ member :name
201
+
202
+ # Create an error message.
203
+ def to_s
204
+ case key
205
+ when :different
206
+ "%s is different from expected result." % name
207
+ when :not_exist
208
+ "%s doesn't exist." % name
209
+ end
210
+ end
211
+ end
212
+
190
213
  # PackageScenario is a class for expected scenario of rule's behavior.
191
214
  class PackageScenario
192
215
  include SimpleIdentity
@@ -222,6 +245,25 @@ module Pione
222
245
  def output
223
246
  @location + "output"
224
247
  end
248
+
249
+ # Validate reheasal results.
250
+ def validate(result_location)
251
+ return [] unless output.exist?
252
+
253
+ errors = []
254
+ output.entries.each do |entry|
255
+ name = entry.basename
256
+ result = result_location + name
257
+ if result.exist?
258
+ if entry.read != result.read
259
+ errors << RehearsalResult.new(:different, name)
260
+ end
261
+ else
262
+ errors << RehearsalResult.new(:not_exist, name)
263
+ end
264
+ end
265
+ return errors
266
+ end
225
267
  end
226
268
 
227
269
  # PackageScenarioReader is a reader for loading scenarios.