holoserve 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,19 +1,15 @@
1
1
 
2
2
  class Holoserve::Fixture::Importer
3
3
 
4
+ attr_accessor :hash
4
5
  attr_accessor :fixtures
5
6
 
6
7
  def initialize(hash, fixtures)
7
- @fixtures = fixtures
8
- self.hash = hash
8
+ @hash, @fixtures = hash, fixtures
9
9
  end
10
10
 
11
- def hash=(value)
12
- @imports = value.respond_to?(:delete) && value.delete(:imports) || [ ]
13
- @hash = value
14
- end
15
-
16
- def hash
11
+ def result
12
+ @result = { }
17
13
  import
18
14
  merge
19
15
  @result
@@ -22,23 +18,30 @@ class Holoserve::Fixture::Importer
22
18
  private
23
19
 
24
20
  def import
25
- @imports.each do |import|
26
- path = import[:path]
27
- as = import[:as] || path
28
- only = import[:only]
21
+ imports.each do |import|
22
+ path, as, only, except = *import.values_at(:path, :as, :only, :except)
29
23
 
30
24
  value = Holoserve::Tool::DataPath.new(path, @fixtures).fetch
31
25
 
32
- value.delete_if do |key, v|
33
- ![ only ].flatten.compact.include?(key.to_s)
34
- end if only.respond_to?(:include?) && value.respond_to?(:delete_if)
26
+ if value.respond_to?(:reject)
27
+ value = value.reject{ |key, v| ![ only ].flatten.compact.include?(key.to_s) } if only
28
+ value = value.reject{ |key, v| [ except ].flatten.compact.include?(key.to_s) } if except
29
+ end
35
30
 
36
31
  @result = Holoserve::Tool::DataPath.new(as, @result || { }).store value
37
32
  end
38
33
  end
39
34
 
40
35
  def merge
41
- @result = Holoserve::Tool::Merger.new(@result, @hash).result if @hash
36
+ @result = Holoserve::Tool::Merger.new(@result, hash_without_imports).result
37
+ end
38
+
39
+ def hash_without_imports
40
+ @hash.reject{ |key, v| key == :imports }
41
+ end
42
+
43
+ def imports
44
+ @hash[:imports] || [ ]
42
45
  end
43
46
 
44
47
  end
@@ -8,13 +8,20 @@ class Holoserve::Interface::Control < Sinatra::Base
8
8
  mime_type :json, "application/json"
9
9
 
10
10
  post "/_control/pairs" do
11
- load_file_into(pairs) ?
12
- acknowledgement :
11
+ if pair_id = load_file_into(pairs)
12
+ logger.info "loaded pair #{pair_id}"
13
+ acknowledgement
14
+ else
13
15
  bad_request
16
+ end
17
+ end
18
+
19
+ get "/_control/pairs.:format" do |format|
20
+ respond_formatted params["evaluate"] ? evaluated_pairs : pairs, format
14
21
  end
15
22
 
16
23
  get "/_control/pairs/:id.:format" do |id, format|
17
- pair = pairs[id.to_sym]
24
+ pair = (params["evaluate"] ? evaluated_pairs : pairs)[id.to_sym]
18
25
  if pair
19
26
  respond_formatted pair, format
20
27
  else
@@ -27,9 +34,12 @@ class Holoserve::Interface::Control < Sinatra::Base
27
34
  end
28
35
 
29
36
  post "/_control/fixtures" do
30
- load_file_into(fixtures) ?
31
- acknowledgement :
37
+ if fixture_id = load_file_into(fixtures)
38
+ logger.info "loaded fixture #{fixture_id}"
39
+ acknowledgement
40
+ else
32
41
  bad_request
42
+ end
33
43
  end
34
44
 
35
45
  get "/_control/fixtures/:id.:format" do |id, format|
@@ -47,6 +57,7 @@ class Holoserve::Interface::Control < Sinatra::Base
47
57
 
48
58
  put "/_control/situation" do
49
59
  configuration[:situation] = params[:name]
60
+ logger.info "set situation to #{params[:name]}"
50
61
  respond_json_acknowledgement
51
62
  end
52
63
 
@@ -111,10 +122,10 @@ class Holoserve::Interface::Control < Sinatra::Base
111
122
 
112
123
  def load_file_into(hash)
113
124
  data = load_file params["file"][:tempfile]
114
- return false unless data
125
+ return nil unless data
115
126
  id = File.basename params["file"][:filename], ".*"
116
127
  hash[id.to_sym] = Holoserve::Tool::Hash::KeySymbolizer.new(data).hash
117
- true
128
+ id.to_sym
118
129
  end
119
130
 
120
131
  def load_file(filename)
@@ -127,6 +138,19 @@ class Holoserve::Interface::Control < Sinatra::Base
127
138
  end
128
139
  end
129
140
 
141
+ def evaluated_pairs
142
+ result = { }
143
+ pairs.each do |id, pair|
144
+ result[id] = { }
145
+ result[id][:request] = Holoserve::Fixture::Importer.new(pair[:request], fixtures).result
146
+ result[id][:responses] = { }
147
+ pair[:responses].each do |situation, response|
148
+ result[id][:responses][situation] = Holoserve::Fixture::Importer.new(response, fixtures).result
149
+ end
150
+ end
151
+ result
152
+ end
153
+
130
154
  def pairs
131
155
  configuration[:pairs]
132
156
  end
@@ -147,4 +171,8 @@ class Holoserve::Interface::Control < Sinatra::Base
147
171
  Holoserve.instance.configuration
148
172
  end
149
173
 
174
+ def logger
175
+ Holoserve.instance.logger
176
+ end
177
+
150
178
  end
@@ -3,7 +3,7 @@ class Holoserve::Request::Matcher
3
3
 
4
4
  def initialize(request, request_subset, fixtures)
5
5
  @request = request
6
- @request_subset = Holoserve::Fixture::Importer.new(request_subset, fixtures).hash
6
+ @request_subset = Holoserve::Fixture::Importer.new(request_subset, fixtures).result
7
7
  end
8
8
 
9
9
  def match?
@@ -13,13 +13,13 @@ class Holoserve::Response::Combiner
13
13
 
14
14
  def default_response
15
15
  @responses[:default] ?
16
- Holoserve::Fixture::Importer.new(@responses[:default], fixtures).hash :
16
+ Holoserve::Fixture::Importer.new(@responses[:default], fixtures).result :
17
17
  { }
18
18
  end
19
19
 
20
20
  def situation_response
21
21
  situation && @responses[situation.to_sym] ?
22
- Holoserve::Fixture::Importer.new(@responses[situation.to_sym], fixtures).hash :
22
+ Holoserve::Fixture::Importer.new(@responses[situation.to_sym], fixtures).result :
23
23
  { }
24
24
  end
25
25
 
@@ -13,7 +13,7 @@ class Holoserve::Response::Composer
13
13
  private
14
14
 
15
15
  def status
16
- @response[:status]
16
+ @response[:status] || 200
17
17
  end
18
18
 
19
19
  def headers
@@ -65,7 +65,8 @@ class Holoserve::Runner
65
65
 
66
66
  def set_situation
67
67
  Transport::JSON.request :put,
68
- "http://localhost:#{port}/_control/situation/#{@situation}",
68
+ "http://localhost:#{port}/_control/situation",
69
+ :parameters => { :name => @situation },
69
70
  :expected_status_code => 200
70
71
  nil
71
72
  end
@@ -30,9 +30,9 @@ class Holoserve::Tool::DataPath
30
30
 
31
31
  def store(value)
32
32
  path = @path ? @path.split(PATH_SEPARATOR) : [ ]
33
- return value if path.empty?
33
+ return Holoserve::Tool::Merger.new(@data, value).result if path.empty?
34
34
 
35
- selected = @data
35
+ result = selected = clone @data
36
36
  key = parse_key path.shift
37
37
 
38
38
  while path.length > 0
@@ -44,7 +44,7 @@ class Holoserve::Tool::DataPath
44
44
  end
45
45
 
46
46
  selected[key] = value
47
- @data
47
+ result
48
48
  end
49
49
 
50
50
  private
@@ -53,4 +53,8 @@ class Holoserve::Tool::DataPath
53
53
  key =~ /^\d+$/ ? key.to_i : key.to_sym
54
54
  end
55
55
 
56
+ def clone(object)
57
+ Marshal.load Marshal.dump(object)
58
+ end
59
+
56
60
  end
@@ -2,7 +2,13 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "he
2
2
 
3
3
  describe Holoserve::Fixture::Importer do
4
4
 
5
- let(:fixtures) { { :test => { :nested => "value", :second => "value" }, :another => "value" } }
5
+ let(:fixtures) do
6
+ {
7
+ :one => { :first => 1, :second => 2 }.freeze,
8
+ :two => 3,
9
+ :three => { :third => 4 }.freeze
10
+ }.freeze
11
+ end
6
12
 
7
13
  subject { described_class.new nil, fixtures }
8
14
 
@@ -12,66 +18,102 @@ describe Holoserve::Fixture::Importer do
12
18
  subject.hash = {
13
19
  :test => "value"
14
20
  }
15
- subject.hash.should == { :test => "value" }
21
+ subject.result.should == { :test => "value" }
16
22
  end
17
23
 
18
24
  it "should return a hash with imported fixtures" do
19
25
  subject.hash = {
20
26
  :imports => [
21
- { :path => "test.nested" }
27
+ { :path => "one" }
22
28
  ]
23
29
  }
24
- subject.hash.should == { :test => { :nested => "value" } }
30
+ subject.result.should == { :first => 1, :second => 2 }
25
31
  end
26
32
 
27
33
  it "should return a hash with imported fixtures at a target path" do
28
34
  subject.hash = {
29
35
  :imports => [
30
- { :path => "test.nested", :as => "test" }
36
+ { :path => "one.first", :as => "test" }
31
37
  ]
32
38
  }
33
- subject.hash.should == { :test => "value" }
39
+ subject.result.should == { :test => 1 }
34
40
  end
35
41
 
36
- it "should return a hash with imported and filtered fixtures" do
42
+ it "should return a hash with imported and white-list filtered fixtures" do
37
43
  subject.hash = {
38
44
  :imports => [
39
- { :path => "test", :as => "test", :only => [ "second" ] }
45
+ { :path => "one", :as => "test", :only => "second" }
40
46
  ]
41
47
  }
42
- subject.hash.should == { :test => { :second => "value" } }
48
+ subject.result.should == { :test => { :second => 2 } }
49
+ end
50
+
51
+ it "should return a hash with imported and black-list filtered fixtures" do
52
+ subject.hash = {
53
+ :imports => [
54
+ { :path => "one", :as => "test", :except => [ "second" ] }
55
+ ]
56
+ }
57
+ subject.result.should == { :test => { :first => 1 } }
43
58
  end
44
59
 
45
60
  it "should return a hash where all the imports are imported" do
46
61
  subject.hash = {
47
62
  :imports => [
48
- { :path => "test.nested", :as => "test" },
49
- { :path => "another", :as => "another.test" }
63
+ { :path => "one.first", :as => "test" },
64
+ { :path => "two", :as => "another.test" }
65
+ ]
66
+ }
67
+ subject.result.should == { :test => 1, :another => { :test => 3 } }
68
+ end
69
+
70
+ it "should return a hash where all the imports are merged together" do
71
+ subject.hash = {
72
+ :imports => [
73
+ { :path => "one" },
74
+ { :path => "three" }
50
75
  ]
51
76
  }
52
- subject.hash.should == { :test => "value", :another => { :test => "value" } }
77
+ subject.result.should == { :first => 1, :second => 2, :third => 4 }
53
78
  end
54
79
 
55
80
  it "should return a hash where the data is merged with the imports" do
56
81
  subject.hash = {
57
82
  :imports => [
58
- { :path => "test.nested", :as => "test" }
83
+ { :path => "one.first", :as => "test" }
59
84
  ],
60
85
  :another => "value"
61
86
  }
62
- subject.hash.should == { :test => "value", :another => "value" }
87
+ subject.result.should == { :test => 1, :another => "value" }
63
88
  end
64
89
 
65
90
  it "should return a hash where the data is deep merged with the imports" do
66
91
  subject.hash = {
67
92
  :imports => [
68
- { :path => "test.nested", :as => "test.nested" }
93
+ { :path => "one.first", :as => "test.nested" }
69
94
  ],
70
95
  :test => {
71
96
  :another => "value"
72
97
  }
73
98
  }
74
- subject.hash.should == { :test => { :nested => "value", :another => "value" } }
99
+ subject.result.should == { :test => { :nested => 1, :another => "value" } }
100
+ end
101
+
102
+ it "should not destroy the original hash and stay repeatable" do
103
+ hash = {
104
+ :imports => [
105
+ { :path => "three" },
106
+ { :path => "one.first", :as => "test.nested" }
107
+ ],
108
+ :test => {
109
+ :another => "value"
110
+ }
111
+ }
112
+ subject.hash = hash
113
+ subject.result.should == { :third => 4, :test => { :nested => 1, :another => "value" } }
114
+
115
+ importer = described_class.new hash, fixtures
116
+ importer.result.should == { :third => 4, :test => { :nested => 1, :another => "value" } }
75
117
  end
76
118
 
77
119
  end
@@ -8,37 +8,37 @@ describe Holoserve::Tool::DataPath do
8
8
 
9
9
  it "should return the given data if no path is specified" do
10
10
  subject.path = nil
11
- subject.data = { :test => "value" }
11
+ subject.data = { :test => "value" }.freeze
12
12
  subject.fetch.should == { :test => "value" }
13
13
  end
14
14
 
15
15
  it "should return the value specified by the given path" do
16
16
  subject.path = "test"
17
- subject.data = { :test => "value" }
17
+ subject.data = { :test => "value" }.freeze
18
18
  subject.fetch.should == "value"
19
19
  end
20
20
 
21
21
  it "should return the nested value specified by the given path" do
22
22
  subject.path = "test.nested"
23
- subject.data = { :test => { :nested => "value" } }
23
+ subject.data = { :test => { :nested => "value" }.freeze }.freeze
24
24
  subject.fetch.should == "value"
25
25
  end
26
26
 
27
27
  it "should return nil if the path points to nowhere" do
28
28
  subject.path = "test.nested"
29
- subject.data = { :test => true }
29
+ subject.data = { :test => true }.freeze
30
30
  subject.fetch.should be_nil
31
31
  end
32
32
 
33
33
  it "should return nil if the last path element doesn't exists'" do
34
34
  subject.path = "test.nested"
35
- subject.data = { :test => { :another => "value" } }
35
+ subject.data = { :test => { :another => "value" }.freeze }.freeze
36
36
  subject.fetch.should be_nil
37
37
  end
38
38
 
39
39
  it "should return in an array nested value specified by the given path" do
40
40
  subject.path = "test.1.nested"
41
- subject.data = { :test => [ { }, { :nested => "value" } ] }
41
+ subject.data = { :test => [ { }.freeze, { :nested => "value" }.freeze ].freeze }.freeze
42
42
  subject.fetch.should == "value"
43
43
  end
44
44
 
@@ -46,27 +46,33 @@ describe Holoserve::Tool::DataPath do
46
46
 
47
47
  describe "store" do
48
48
 
49
- it "should return the given value if no path is specified" do
49
+ it "should merge the given value with the root element if no path is given" do
50
50
  subject.path = nil
51
- subject.data = { :test => "value" }
51
+ subject.data = { :test => "value" }.freeze
52
+ subject.store(:another => "value").should == { :test => "value", :another => "value" }
53
+ end
54
+
55
+ it "should return the value if no path is given and value is not mergeable" do
56
+ subject.path = nil
57
+ subject.data = { :test => "value" }.freeze
52
58
  subject.store("value").should == "value"
53
59
  end
54
60
 
55
61
  it "should store the given value at the specified path" do
56
62
  subject.path = "another"
57
- subject.data = { :test => "value" }
63
+ subject.data = { :test => "value" }.freeze
58
64
  subject.store("value").should == { :test => "value", :another => "value" }
59
65
  end
60
66
 
61
67
  it "should store the given value in a nested hash" do
62
68
  subject.path = "test.another"
63
- subject.data = { :test => { :nested => "value" } }
69
+ subject.data = { :test => { :nested => "value" }.freeze }.freeze
64
70
  subject.store("value").should == { :test => { :nested => "value", :another => "value" } }
65
71
  end
66
72
 
67
73
  it "should store the given value at the specified path and create it if missing" do
68
74
  subject.path = "another.test"
69
- subject.data = { :test => "value" }
75
+ subject.data = { :test => "value" }.freeze
70
76
  subject.store("value").should == { :test => "value", :another => { :test => "value" } }
71
77
  end
72
78
 
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.3.0
4
+ version: 0.3.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-02-09 00:00:00.000000000 Z
12
+ date: 2012-02-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
- requirement: &70132546243580 !ruby/object:Gem::Requirement
16
+ requirement: &70159532631360 !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: *70132546243580
24
+ version_requirements: *70159532631360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: sinatra
27
- requirement: &70132546257040 !ruby/object:Gem::Requirement
27
+ requirement: &70159532629620 !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: :runtime
34
34
  prerelease: false
35
- version_requirements: *70132546257040
35
+ version_requirements: *70159532629620
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: unicorn
38
- requirement: &70132546255800 !ruby/object:Gem::Requirement
38
+ requirement: &70159532627220 !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: :runtime
45
45
  prerelease: false
46
- version_requirements: *70132546255800
46
+ version_requirements: *70159532627220
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: transport
49
- requirement: &70132546254300 !ruby/object:Gem::Requirement
49
+ requirement: &70159532638140 !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: :runtime
56
56
  prerelease: false
57
- version_requirements: *70132546254300
57
+ version_requirements: *70159532638140
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: cucumber
60
- requirement: &70132546252800 !ruby/object:Gem::Requirement
60
+ requirement: &70159532632680 !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: *70132546252800
68
+ version_requirements: *70159532632680
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &70132546265600 !ruby/object:Gem::Requirement
71
+ requirement: &70159532646160 !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: *70132546265600
79
+ version_requirements: *70159532646160
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: transport
82
- requirement: &70132546264780 !ruby/object:Gem::Requirement
82
+ requirement: &70159532643660 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70132546264780
90
+ version_requirements: *70159532643660
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: oauth
93
- requirement: &70132546263580 !ruby/object:Gem::Requirement
93
+ requirement: &70159532640540 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70132546263580
101
+ version_requirements: *70159532640540
102
102
  description: This tool can be used to fake webservice APIs for testing proposals.
103
103
  email: philipp.bruell@skrill.com
104
104
  executables:
@@ -150,7 +150,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
150
  version: '0'
151
151
  segments:
152
152
  - 0
153
- hash: 4596962680025174660
153
+ hash: -2968421100355071724
154
154
  required_rubygems_version: !ruby/object:Gem::Requirement
155
155
  none: false
156
156
  requirements: