couchbase-model-relationship 0.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.
@@ -0,0 +1,197 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'rubygems'
5
+ require 'bundler/setup'
6
+ require 'rspec/core'
7
+
8
+ require 'couchbase'
9
+ require 'couchbase/model'
10
+
11
+ require 'socket'
12
+ require 'open-uri'
13
+
14
+ class CouchbaseServer
15
+ attr_accessor :host, :port, :num_nodes, :buckets_spec
16
+
17
+ def real?
18
+ true
19
+ end
20
+
21
+ def initialize(params = {})
22
+ @host, @port = ENV['COUCHBASE_SERVER'].split(':')
23
+ @port = @port.to_i
24
+
25
+ if @host.nil? || @host.empty? || @port == 0
26
+ raise ArgumentError, "Check COUCHBASE_SERVER variable. It should be hostname:port"
27
+ end
28
+
29
+ @config = Yajl::Parser.parse(open("http://#{@host}:#{@port}/pools/default"))
30
+ @num_nodes = @config["nodes"].size
31
+ @buckets_spec = params[:buckets_spec] || "default:" # "default:,protected:secret,cache::memcache"
32
+ end
33
+
34
+ def start
35
+ # flush all buckets
36
+ @buckets_spec.split(',') do |bucket|
37
+ name, password, _ = bucket.split(':')
38
+ connection = Couchbase.new(:hostname => @host,
39
+ :port => @port,
40
+ :username => name,
41
+ :bucket => name,
42
+ :password => password)
43
+ connection.flush
44
+ end
45
+ end
46
+ def stop; end
47
+ end
48
+
49
+ class CouchbaseMock
50
+ Monitor = Struct.new(:pid, :client, :socket, :port)
51
+
52
+ attr_accessor :host, :port, :buckets_spec, :num_nodes, :num_vbuckets
53
+
54
+ def real?
55
+ false
56
+ end
57
+
58
+ def initialize(params = {})
59
+ @host = "127.0.0.1"
60
+ @port = 0
61
+ @num_nodes = 10
62
+ @num_vbuckets = 4096
63
+ @buckets_spec = "default:" # "default:,protected:secret,cache::memcache"
64
+ params.each do |key, value|
65
+ send("#{key}=", value)
66
+ end
67
+ yield self if block_given?
68
+ if @num_vbuckets < 1 || (@num_vbuckets & (@num_vbuckets - 1) != 0)
69
+ raise ArgumentError, "Number of vbuckets should be a power of two and greater than zero"
70
+ end
71
+ end
72
+
73
+ def start
74
+ @monitor = Monitor.new
75
+ @monitor.socket = TCPServer.new(nil, 0)
76
+ @monitor.socket.listen(10)
77
+ _, @monitor.port, _, _ = @monitor.socket.addr
78
+ trap("CLD") do
79
+ puts "CouchbaseMock.jar died unexpectedly during startup"
80
+ exit(1)
81
+ end
82
+ @monitor.pid = fork
83
+ if @monitor.pid.nil?
84
+ rc = exec(command_line("--harakiri-monitor=:#{@monitor.port}"))
85
+ else
86
+ trap("CLD", "SIG_DFL")
87
+ @monitor.client, _ = @monitor.socket.accept
88
+ @port = @monitor.client.recv(100).to_i
89
+ end
90
+ end
91
+
92
+ def stop
93
+ @monitor.client.close
94
+ @monitor.socket.close
95
+ Process.kill("TERM", @monitor.pid)
96
+ Process.wait(@monitor.pid)
97
+ end
98
+
99
+ def failover_node(index, bucket = "default")
100
+ @monitor.client.send("failover,#{index},#{bucket}", 0)
101
+ end
102
+
103
+ def respawn_node(index, bucket = "default")
104
+ @monitor.client.send("respawn,#{index},#{bucket}", 0)
105
+ end
106
+
107
+ protected
108
+
109
+ def command_line(extra = nil)
110
+ cmd = "java -jar #{File.dirname(__FILE__)}/CouchbaseMock.jar"
111
+ cmd << " --host #{@host}" if @host
112
+ cmd << " --port #{@port}" if @port
113
+ cmd << " --nodes #{@num_nodes}" if @num_nodes
114
+ cmd << " --vbuckets #{@num_vbuckets}" if @num_vbuckets
115
+ cmd << " --buckets #{@buckets_spec}" if @buckets_spec
116
+ cmd << " #{extra}"
117
+ cmd
118
+ end
119
+ end
120
+
121
+ require 'couchbase/model/relationship'
122
+
123
+ module RspecHelpers
124
+ def stub_instance(klass, stubs = {}, mocks = {})
125
+ stub = stub(klass.name)
126
+ stub.responds_like_instance_of(klass)
127
+
128
+ stub.stubs(stubs) if stubs && ! stubs.empty?
129
+ stub.mocks(mocks) if mocks && ! mocks.empty?
130
+
131
+ stub
132
+ end
133
+
134
+ def stub_klass(klass)
135
+ stub = stub(klass.name)
136
+ stub.responds_like(klass)
137
+
138
+ stub
139
+ end
140
+
141
+ def stub_server(*klasses)
142
+ Thread.current['mock'] = start_mock
143
+ bucket = Couchbase.connect(:hostname => @mock.host, :port => @mock.port)
144
+ [Post, ValidPost, Brewery, Beer, Attachment].each do |model|
145
+ model.bucket = bucket
146
+ end
147
+ bucket
148
+ end
149
+
150
+ def start_mock(params = {})
151
+ mock = nil
152
+ if ENV['COUCHBASE_SERVER']
153
+ mock = CouchbaseServer.new(params)
154
+ if (params[:port] && mock.port != params[:port]) ||
155
+ (params[:host] && mock.host != params[:host]) ||
156
+ mock.buckets_spec != "default:"
157
+ skip("Unable to configure real cluster. Requested config is: #{params.inspect}")
158
+ end
159
+ else
160
+ mock = CouchbaseMock.new(params)
161
+ end
162
+ mock.start
163
+ mock
164
+ end
165
+
166
+ def stop_mock(mock = Thread.current['mock'])
167
+ mock.stop if mock
168
+ end
169
+
170
+ def with_mock(params = {})
171
+ mock = nil
172
+ if block_given?
173
+ mock = start_mock(params)
174
+ yield mock
175
+ end
176
+ ensure
177
+ stop_mock(mock) if mock
178
+ end
179
+
180
+ def uniq_id(*suffixes)
181
+ [caller.first[/.*[` ](.*)'/, 1], suffixes].join("_")
182
+ end
183
+ end
184
+
185
+
186
+ RSpec.configure do |config|
187
+ config.mock_framework = :mocha
188
+ config.include RspecHelpers
189
+
190
+ #config.after(:suite) do
191
+ # stop_mock
192
+ #end
193
+ end
194
+
195
+ Mocha::Configuration.prevent :stubbing_non_existent_method
196
+ Mocha::Configuration.prevent :stubbing_method_on_nil
197
+
metadata ADDED
@@ -0,0 +1,246 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: couchbase-model-relationship
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Moses
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activemodel
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '3'
46
+ - !ruby/object:Gem::Dependency
47
+ name: couchbase
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1'
62
+ - !ruby/object:Gem::Dependency
63
+ name: couchbase-model
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.5.3
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.5.3
78
+ - !ruby/object:Gem::Dependency
79
+ name: json
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 1.7.7
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.7.7
94
+ - !ruby/object:Gem::Dependency
95
+ name: multi_json
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - '='
100
+ - !ruby/object:Gem::Version
101
+ version: 1.7.5
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - '='
108
+ - !ruby/object:Gem::Version
109
+ version: 1.7.5
110
+ - !ruby/object:Gem::Dependency
111
+ name: bundler
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '1.3'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '1.3'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rake
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: rspec
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: mocha
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ description: Closely bound relationships for Couchbase::Model
175
+ email:
176
+ - jon@burningbush.us
177
+ executables: []
178
+ extensions: []
179
+ extra_rdoc_files: []
180
+ files:
181
+ - .gitignore
182
+ - Gemfile
183
+ - LICENSE.txt
184
+ - README.md
185
+ - Rakefile
186
+ - couchbase-model-relationship.gemspec
187
+ - lib/couchbase/model/attributes.rb
188
+ - lib/couchbase/model/complex_attributes.rb
189
+ - lib/couchbase/model/deep_copier.rb
190
+ - lib/couchbase/model/dirty.rb
191
+ - lib/couchbase/model/id_prefix.rb
192
+ - lib/couchbase/model/relationship.rb
193
+ - lib/couchbase/model/relationship/association.rb
194
+ - lib/couchbase/model/relationship/child.rb
195
+ - lib/couchbase/model/relationship/parent.rb
196
+ - lib/couchbase/model/relationship/version.rb
197
+ - spec/association_spec.rb
198
+ - spec/attributes_spec.rb
199
+ - spec/child_spec.rb
200
+ - spec/complex_attributes_spec.rb
201
+ - spec/deep_copier_spec.rb
202
+ - spec/dirty_spec.rb
203
+ - spec/id_prefix_spec.rb
204
+ - spec/parent_spec.rb
205
+ - spec/spec_helper.rb
206
+ homepage: https://github.com/jmoses/couchbase-model-relationship
207
+ licenses:
208
+ - MIT
209
+ post_install_message:
210
+ rdoc_options: []
211
+ require_paths:
212
+ - lib
213
+ required_ruby_version: !ruby/object:Gem::Requirement
214
+ none: false
215
+ requirements:
216
+ - - ! '>='
217
+ - !ruby/object:Gem::Version
218
+ version: '0'
219
+ segments:
220
+ - 0
221
+ hash: -2574960161948404974
222
+ required_rubygems_version: !ruby/object:Gem::Requirement
223
+ none: false
224
+ requirements:
225
+ - - ! '>='
226
+ - !ruby/object:Gem::Version
227
+ version: '0'
228
+ segments:
229
+ - 0
230
+ hash: -2574960161948404974
231
+ requirements: []
232
+ rubyforge_project:
233
+ rubygems_version: 1.8.24
234
+ signing_key:
235
+ specification_version: 3
236
+ summary: Supports relationships that are fetched and saved with a root model
237
+ test_files:
238
+ - spec/association_spec.rb
239
+ - spec/attributes_spec.rb
240
+ - spec/child_spec.rb
241
+ - spec/complex_attributes_spec.rb
242
+ - spec/deep_copier_spec.rb
243
+ - spec/dirty_spec.rb
244
+ - spec/id_prefix_spec.rb
245
+ - spec/parent_spec.rb
246
+ - spec/spec_helper.rb