holoserve 0.4.0 → 0.4.1
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/README.rdoc +5 -0
- data/bin/holoserve +3 -0
- data/bin/test.log +4 -0
- data/lib/holoserve/fixture/importer.rb +1 -1
- data/lib/holoserve/interface/control/state.rb +1 -1
- data/lib/holoserve/response/combiner.rb +1 -1
- data/lib/holoserve/response/selector.rb +8 -2
- data/lib/holoserve/tool/data_path.rb +4 -2
- data/lib/holoserve/tool/merger.rb +17 -7
- data/lib/holoserve.rb +6 -6
- data/spec/lib/holoserve/fixture/importer_spec.rb +19 -0
- data/spec/lib/holoserve/tool/data_path_spec.rb +12 -0
- data/spec/lib/holoserve/tool/merger_spec.rb +26 -0
- metadata +18 -17
data/README.rdoc
CHANGED
@@ -130,6 +130,8 @@ The request/response pair file should have the following format.
|
|
130
130
|
imports:
|
131
131
|
- path: "test_fixture.users.0"
|
132
132
|
as: "json.user"
|
133
|
+
transitions:
|
134
|
+
session_one: "existing"
|
133
135
|
"user_one == :missing":
|
134
136
|
json:
|
135
137
|
message: "user not found"
|
@@ -170,3 +172,6 @@ are posted and the second one reacts on the transmission of <tt>username=one</tt
|
|
170
172
|
If the state includes <tt>user_one == :existing</tt>, the first response would return the complete user object encoded
|
171
173
|
as json, while the second one would reply the message "invalid password". In the state includes
|
172
174
|
<tt>user_one == :missing</tt>, both requests would be replied with the message "user not found".
|
175
|
+
|
176
|
+
The <tt>transitions</tt> part of the response allows you set the successor state. If a response is selected, the
|
177
|
+
corresponding transitions will be evaluated.
|
data/bin/holoserve
CHANGED
@@ -14,6 +14,9 @@ OptionParser.new do |parser|
|
|
14
14
|
parser.on("-P", "--port PORT", Integer, "The port holoserve should listen to.") do |value|
|
15
15
|
options[:port] = value
|
16
16
|
end
|
17
|
+
parser.on("-l", "--log-file FILE", "The file where the messages go to.") do |value|
|
18
|
+
options[:log_filename] = value
|
19
|
+
end
|
17
20
|
parser.on("-f", "--fixture-files PATTERN", "Load the specified fixture files on startup.") do |value|
|
18
21
|
options[:fixture_file_pattern] = value
|
19
22
|
end
|
data/bin/test.log
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
[690:INFO] 2012-04-02 21:19:51 :: Starting server on 0.0.0.0:4250 in production mode. Watch out for stones.
|
2
|
+
[708:INFO] 2012-04-02 21:20:17 :: Starting server on 0.0.0.0:4250 in production mode. Watch out for stones.
|
3
|
+
[712:INFO] 2012-04-02 21:20:24 :: Starting server on 0.0.0.0:4250 in production mode. Watch out for stones.
|
4
|
+
[724:INFO] 2012-04-02 21:20:33 :: Starting server on 0.0.0.0:4250 in production mode. Watch out for stones.
|
@@ -33,7 +33,7 @@ class Holoserve::Fixture::Importer
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def merge
|
36
|
-
@result = Holoserve::Tool::Merger.new(@result, hash_without_imports).result
|
36
|
+
@result = Holoserve::Tool::Merger.new(@result, hash_without_imports, :fusion).result
|
37
37
|
end
|
38
38
|
|
39
39
|
def hash_without_imports
|
@@ -8,7 +8,7 @@ module Holoserve::Interface::Control::State
|
|
8
8
|
use Goliath::Rack::Params
|
9
9
|
|
10
10
|
def response(environment)
|
11
|
-
state.merge! params
|
11
|
+
state.merge! Holoserve::Tool::Hash::KeySymbolizer.new(params).hash
|
12
12
|
logger.info "set state to '#{state.inspect}'"
|
13
13
|
respond_json_acknowledgement
|
14
14
|
end
|
@@ -3,7 +3,8 @@ class Holoserve::Response::Selector
|
|
3
3
|
|
4
4
|
class Sandbox
|
5
5
|
|
6
|
-
def initialize(state)
|
6
|
+
def initialize(state, logger)
|
7
|
+
@logger = logger
|
7
8
|
state.each do |resource, value|
|
8
9
|
define_singleton_method resource.to_sym do
|
9
10
|
value ? value.to_sym : nil
|
@@ -11,11 +12,16 @@ class Holoserve::Response::Selector
|
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
15
|
+
def method_missing(method_name, *arguments, &block)
|
16
|
+
@logger.warn "tried to use undefined state key '#{method_name}'"
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
14
20
|
end
|
15
21
|
|
16
22
|
def initialize(responses, state, logger)
|
17
23
|
@responses, @logger = responses, logger
|
18
|
-
@sandbox = Sandbox.new state
|
24
|
+
@sandbox = Sandbox.new state, logger
|
19
25
|
end
|
20
26
|
|
21
27
|
def default_response
|
@@ -36,17 +36,19 @@ class Holoserve::Tool::DataPath
|
|
36
36
|
path = @path ? @path.split(PATH_SEPARATOR) : [ ]
|
37
37
|
return Holoserve::Tool::Merger.new(@data, value).result if path.empty?
|
38
38
|
|
39
|
-
result = selected = clone
|
39
|
+
result = selected = clone(@data)
|
40
40
|
key = parse_key path.shift
|
41
41
|
|
42
42
|
while path.length > 0
|
43
43
|
break unless selected.respond_to?(:[])
|
44
44
|
|
45
|
-
selected[key] ||= { }
|
45
|
+
selected[key] ||= path.first.to_s == "@" ? [ ] : { }
|
46
46
|
selected = selected[key]
|
47
47
|
key = parse_key path.shift
|
48
48
|
end
|
49
49
|
|
50
|
+
key = selected.length if key.to_s == "@"
|
51
|
+
|
50
52
|
selected[key] = value
|
51
53
|
result
|
52
54
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
|
2
2
|
class Holoserve::Tool::Merger
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
attr_accessor :mode
|
5
|
+
|
6
|
+
def initialize(hash_or_array_one, hash_or_array_two, mode = :union)
|
7
|
+
@hash_or_array_one, @hash_or_array_two, @mode = hash_or_array_one, hash_or_array_two, mode
|
6
8
|
end
|
7
9
|
|
8
10
|
def result
|
@@ -20,24 +22,32 @@ class Holoserve::Tool::Merger
|
|
20
22
|
def merged_hash
|
21
23
|
result = { }
|
22
24
|
(@hash_or_array_one.keys + @hash_or_array_two.keys).uniq.each do |key|
|
23
|
-
value_one, value_two = @hash_or_array_one[key]
|
25
|
+
value_one, value_two = @hash_or_array_one[key], @hash_or_array_two[key]
|
24
26
|
result[key] = if values_mergeable?(value_one, value_two)
|
25
|
-
self.class.new(value_one, value_two).result
|
27
|
+
self.class.new(value_one, value_two, @mode).result
|
26
28
|
else
|
27
|
-
value_two
|
29
|
+
@hash_or_array_two.has_key?(key) ? value_two : value_one
|
28
30
|
end
|
29
31
|
end
|
30
32
|
result
|
31
33
|
end
|
32
34
|
|
33
35
|
def merged_array
|
36
|
+
send :"#{@mode}_array"
|
37
|
+
end
|
38
|
+
|
39
|
+
def fusion_array
|
40
|
+
@hash_or_array_one + @hash_or_array_two
|
41
|
+
end
|
42
|
+
|
43
|
+
def union_array
|
34
44
|
result = Array.new [ @hash_or_array_one.length, @hash_or_array_two.length ].max
|
35
45
|
result.each_index do |index|
|
36
46
|
value_one, value_two = @hash_or_array_one[index], @hash_or_array_two[index]
|
37
47
|
result[index] = if values_mergeable?(value_one, value_two)
|
38
|
-
self.class.new(value_one, value_two).result
|
48
|
+
self.class.new(value_one, value_two, @mode).result
|
39
49
|
else
|
40
|
-
value_two
|
50
|
+
index < @hash_or_array_two.length ? value_two : value_one
|
41
51
|
end
|
42
52
|
end
|
43
53
|
result
|
data/lib/holoserve.rb
CHANGED
@@ -14,7 +14,7 @@ class Holoserve
|
|
14
14
|
def initialize(options = { })
|
15
15
|
@port = options[:port] || 4250
|
16
16
|
@pid_filename = options[:pid_filename] || File.expand_path(File.join(File.dirname(__FILE__), "..", "holoserve.pid"))
|
17
|
-
@log_filename = options[:log_filename]
|
17
|
+
@log_filename = options[:log_filename]
|
18
18
|
@fixture_file_pattern = options[:fixture_file_pattern]
|
19
19
|
@pair_file_pattern = options[:pair_file_pattern]
|
20
20
|
@state = options[:state] || { }
|
@@ -52,7 +52,7 @@ class Holoserve
|
|
52
52
|
private
|
53
53
|
|
54
54
|
def initialize_logger
|
55
|
-
@logger = Logger.new @log_filename
|
55
|
+
@logger = Logger.new(@log_filename ? @log_filename : $stdout)
|
56
56
|
end
|
57
57
|
|
58
58
|
def load_pairs
|
@@ -64,13 +64,13 @@ class Holoserve
|
|
64
64
|
|
65
65
|
runner = Goliath::Runner.new [
|
66
66
|
"-P", @pid_filename,
|
67
|
-
"-l", @log_filename,
|
67
|
+
@log_filename ? [ "-l", @log_filename ] : "-s",
|
68
68
|
"-e", "production",
|
69
69
|
"-p", @port.to_s,
|
70
|
-
daemonize ? "-d" :
|
71
|
-
], nil
|
70
|
+
daemonize ? "-d" : nil
|
71
|
+
].flatten.compact, nil
|
72
72
|
runner.options[:pairs] = @pairs
|
73
|
-
runner.options[:state] = @state
|
73
|
+
runner.options[:state] = Tool::Hash::KeySymbolizer.new(@state).hash
|
74
74
|
runner.api = Interface.new
|
75
75
|
runner.app = Goliath::Rack::Builder.build Interface, runner.api
|
76
76
|
runner.run
|
@@ -40,6 +40,25 @@ describe Holoserve::Fixture::Importer do
|
|
40
40
|
subject.result.should == { :test => 1 }
|
41
41
|
end
|
42
42
|
|
43
|
+
it "should return a hash with imported fixtures at a new target array" do
|
44
|
+
subject.hash = {
|
45
|
+
:imports => [
|
46
|
+
{ :path => "one.first", :as => "test.@" }
|
47
|
+
]
|
48
|
+
}
|
49
|
+
subject.result.should == { :test => [ 1 ] }
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return a hash with imported fixtures at an existing target array" do
|
53
|
+
subject.hash = {
|
54
|
+
:imports => [
|
55
|
+
{ :path => "one.second", :as => "test.@" }
|
56
|
+
],
|
57
|
+
:test => [ 1 ]
|
58
|
+
}
|
59
|
+
subject.result.should == { :test => [ 2, 1 ] }
|
60
|
+
end
|
61
|
+
|
43
62
|
it "should return a hash with imported and white-list filtered fixtures" do
|
44
63
|
subject.hash = {
|
45
64
|
:imports => [
|
@@ -82,6 +82,18 @@ describe Holoserve::Tool::DataPath do
|
|
82
82
|
subject.store("value").should == { :test => "value", :another => { :test => "value" } }
|
83
83
|
end
|
84
84
|
|
85
|
+
it "should store the given value at the specified path and place it in a new array" do
|
86
|
+
subject.path = "test.@"
|
87
|
+
subject.data = { }.freeze
|
88
|
+
subject.store("value").should == { :test => [ "value" ] }
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should store the given value at the specified path and place it in an existing array" do
|
92
|
+
subject.path = "test.@"
|
93
|
+
subject.data = { :test => [ 1 ] }.freeze
|
94
|
+
subject.store(2).should == { :test => [ 1, 2 ] }
|
95
|
+
end
|
96
|
+
|
85
97
|
end
|
86
98
|
|
87
99
|
end
|
@@ -17,6 +17,17 @@ describe Holoserve::Tool::Merger do
|
|
17
17
|
|
18
18
|
end
|
19
19
|
|
20
|
+
context "of two hashes with boolean values" do
|
21
|
+
|
22
|
+
let(:argument_one) { { :one => false, :two => true } }
|
23
|
+
let(:argument_two) { { :one => true, :two => false } }
|
24
|
+
|
25
|
+
it "should merge hashes with boolean values" do
|
26
|
+
subject.result.should == { :one => true, :two => false }
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
20
31
|
context "of two nested hashes" do
|
21
32
|
|
22
33
|
let(:argument_one) { { :test => { :regular =>"value", :nested => "value" } } }
|
@@ -56,6 +67,21 @@ describe Holoserve::Tool::Merger do
|
|
56
67
|
|
57
68
|
end
|
58
69
|
|
70
|
+
context "of two arrays in fusion mode" do
|
71
|
+
|
72
|
+
before :each do
|
73
|
+
subject.mode = :fusion
|
74
|
+
end
|
75
|
+
|
76
|
+
let(:argument_one) { [ 1 ] }
|
77
|
+
let(:argument_two) { [ 2, 3 ] }
|
78
|
+
|
79
|
+
it "should combine all arrays" do
|
80
|
+
subject.result.should == [ 1, 2, 3 ]
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
59
85
|
end
|
60
86
|
|
61
87
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: holoserve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: goliath
|
16
|
-
requirement: &
|
16
|
+
requirement: &70271201827600 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70271201827600
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70271205878240 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70271205878240
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rdoc
|
38
|
-
requirement: &
|
38
|
+
requirement: &70271201838000 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70271201838000
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: cucumber
|
49
|
-
requirement: &
|
49
|
+
requirement: &70271201834120 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70271201834120
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &70271201831820 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70271201831820
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: transport
|
71
|
-
requirement: &
|
71
|
+
requirement: &70271205892940 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70271205892940
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: oauth
|
82
|
-
requirement: &
|
82
|
+
requirement: &70271205890640 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70271205890640
|
91
91
|
description: This tool can be used to fake webservice APIs for testing proposals.
|
92
92
|
email: philipp.bruell@skrill.com
|
93
93
|
executables:
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- LICENSE
|
101
101
|
- Rakefile
|
102
102
|
- bin/holoserve
|
103
|
+
- bin/test.log
|
103
104
|
- lib/holoserve/fixture/importer.rb
|
104
105
|
- lib/holoserve/fixture.rb
|
105
106
|
- lib/holoserve/interface/control/bucket.rb
|
@@ -147,7 +148,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
148
|
version: '0'
|
148
149
|
segments:
|
149
150
|
- 0
|
150
|
-
hash: -
|
151
|
+
hash: -4367529671340100891
|
151
152
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
153
|
none: false
|
153
154
|
requirements:
|