coral_core 0.2.30 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -8
  3. data/Gemfile.lock +15 -86
  4. data/Rakefile +1 -3
  5. data/VERSION +1 -1
  6. data/coral_core.gemspec +12 -102
  7. metadata +18 -239
  8. data/lib/coral/command/shell.rb +0 -140
  9. data/lib/coral/machine/fog.rb +0 -215
  10. data/lib/coral/network/default.rb +0 -26
  11. data/lib/coral/node/rackspace.rb +0 -23
  12. data/lib/coral_core/config/collection.rb +0 -57
  13. data/lib/coral_core/config/options.rb +0 -70
  14. data/lib/coral_core/config/project.rb +0 -225
  15. data/lib/coral_core/config.rb +0 -329
  16. data/lib/coral_core/core.rb +0 -58
  17. data/lib/coral_core/event/puppet_event.rb +0 -98
  18. data/lib/coral_core/event/regexp_event.rb +0 -55
  19. data/lib/coral_core/event.rb +0 -170
  20. data/lib/coral_core/mixin/config_collection.rb +0 -52
  21. data/lib/coral_core/mixin/config_ops.rb +0 -51
  22. data/lib/coral_core/mixin/config_options.rb +0 -38
  23. data/lib/coral_core/mixin/lookup.rb +0 -211
  24. data/lib/coral_core/mixin/macro/object_interface.rb +0 -292
  25. data/lib/coral_core/mixin/macro/plugin_interface.rb +0 -277
  26. data/lib/coral_core/mixin/settings.rb +0 -46
  27. data/lib/coral_core/mixin/sub_config.rb +0 -208
  28. data/lib/coral_core/mod/hash.rb +0 -29
  29. data/lib/coral_core/mod/hiera_backend.rb +0 -63
  30. data/lib/coral_core/plugin/command.rb +0 -95
  31. data/lib/coral_core/plugin/machine.rb +0 -152
  32. data/lib/coral_core/plugin/network.rb +0 -24
  33. data/lib/coral_core/plugin/node.rb +0 -184
  34. data/lib/coral_core/plugin.rb +0 -261
  35. data/lib/coral_core/plugin_base.rb +0 -147
  36. data/lib/coral_core/repository.rb +0 -553
  37. data/lib/coral_core/resource.rb +0 -243
  38. data/lib/coral_core/template/environment.rb +0 -72
  39. data/lib/coral_core/template/json.rb +0 -13
  40. data/lib/coral_core/template/wrapper.rb +0 -13
  41. data/lib/coral_core/template/yaml.rb +0 -13
  42. data/lib/coral_core/template.rb +0 -92
  43. data/lib/coral_core/util/cli.rb +0 -293
  44. data/lib/coral_core/util/data.rb +0 -389
  45. data/lib/coral_core/util/disk.rb +0 -105
  46. data/lib/coral_core/util/git.rb +0 -40
  47. data/lib/coral_core/util/interface.rb +0 -190
  48. data/lib/coral_core/util/process.rb +0 -43
  49. data/lib/coral_core/util/shell.rb +0 -183
  50. data/lib/coral_core.rb +0 -375
  51. data/locales/en.yml +0 -8
  52. data/spec/coral_core/interface_spec.rb +0 -489
  53. data/spec/coral_mock_input.rb +0 -29
  54. data/spec/coral_test_kernel.rb +0 -22
  55. data/spec/spec_helper.rb +0 -15
data/lib/coral_core.rb DELETED
@@ -1,375 +0,0 @@
1
-
2
- #*******************************************************************************
3
- # Coral Core Library
4
- #
5
- # This provides core data elements and utilities used in the Coral gems.
6
- #
7
- # Author:: Adrian Webb (mailto:adrian.webb@coraltech.net)
8
- # License:: GPLv3
9
-
10
- #-------------------------------------------------------------------------------
11
- # Global namespace
12
-
13
- module Kernel
14
-
15
- def dbg(data, label = '')
16
- # Invocations of this function should NOT be committed to the project
17
- require 'pp'
18
-
19
- puts '>>----------------------'
20
- unless label.empty?
21
- puts label
22
- puts '---'
23
- end
24
- pp data
25
- puts '<<'
26
- end
27
-
28
- #---
29
-
30
- def coral_locate(command)
31
- command = command.to_s
32
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
33
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
34
- exts.each do |ext|
35
- exe = File.join(path, "#{command}#{ext}")
36
- return exe if File.executable?(exe)
37
- end
38
- end
39
- return nil
40
- end
41
-
42
- #---
43
-
44
- def coral_require(base_dir, name)
45
- name = name.to_s
46
-
47
- require File.join(base_dir, "#{name}.rb")
48
- directory = File.join(base_dir, name)
49
-
50
- if File.directory?(directory)
51
- Dir.glob(File.join(directory, '**', '*.rb')).each do |sub_file|
52
- require sub_file
53
- end
54
- end
55
- end
56
- end
57
-
58
- #-------------------------------------------------------------------------------
59
- # Top level properties
60
-
61
- lib_dir = File.dirname(__FILE__)
62
- core_dir = File.join(lib_dir, 'coral_core')
63
- mixin_dir = File.join(core_dir, 'mixin')
64
- macro_dir = File.join(mixin_dir, 'macro')
65
- event_dir = File.join(core_dir, 'event')
66
- template_dir = File.join(core_dir, 'template')
67
- util_dir = File.join(core_dir, 'util')
68
- mod_dir = File.join(core_dir, 'mod')
69
-
70
- #-------------------------------------------------------------------------------
71
- # Coral requirements
72
-
73
- git_location = coral_locate('git')
74
-
75
- $:.unshift(lib_dir) unless $:.include?(lib_dir) || $:.include?(File.expand_path(lib_dir))
76
-
77
- #---
78
-
79
- require 'rubygems'
80
-
81
- require 'i18n'
82
- require 'log4r'
83
- require 'deep_merge'
84
- require 'yaml'
85
- require 'multi_json'
86
- require 'digest/sha1'
87
-
88
- require 'puppet'
89
- require 'fog'
90
-
91
- #---
92
-
93
- # TODO: Make this dynamically settable
94
-
95
- I18n.load_path << File.expand_path(File.join('..', 'locales', 'en.yml'), lib_dir)
96
-
97
- #---
98
-
99
- if git_location
100
- require 'grit'
101
- coral_require(util_dir, :git)
102
- end
103
-
104
- #---
105
-
106
- # Object modifications (100% pure monkey patches)
107
- Dir.glob(File.join(mod_dir, '*.rb')).each do |file|
108
- require file
109
- end
110
-
111
- #---
112
-
113
- # Mixins for classes
114
- Dir.glob(File.join(mixin_dir, '*.rb')).each do |file|
115
- require file
116
- end
117
- Dir.glob(File.join(macro_dir, '*.rb')).each do |file|
118
- require file
119
- end
120
-
121
- #---
122
-
123
- coral_require(util_dir, :data)
124
- coral_require(core_dir, :config)
125
- coral_require(util_dir, :interface)
126
- coral_require(core_dir, :core)
127
-
128
- # Include core utilities
129
- [ :cli, :disk, :process, :shell ].each do |name|
130
- coral_require(util_dir, name)
131
- end
132
-
133
- # Include core systems
134
- [ :event, :template, :repository, :resource, :plugin_base, :plugin ].each do |name|
135
- coral_require(core_dir, name)
136
- end
137
-
138
- #*******************************************************************************
139
- # Coral Core Library
140
- #
141
- # This provides core data elements and utilities used in the Coral gems.
142
- #
143
- # Author:: Adrian Webb (mailto:adrian.webb@coraltech.net)
144
- # License:: GPLv3
145
- module Coral
146
-
147
- VERSION = File.read(File.join(File.dirname(__FILE__), '..', 'VERSION'))
148
-
149
- #---
150
-
151
- @@config_file = 'coral.json'
152
-
153
- #-----------------------------------------------------------------------------
154
-
155
- def self.ui
156
- return Core.ui
157
- end
158
-
159
- #---
160
-
161
- def self.logger
162
- return Core.logger
163
- end
164
-
165
- #-----------------------------------------------------------------------------
166
-
167
- def self.config_file=file_name
168
- @@config_file = file_name
169
- end
170
-
171
- #---
172
-
173
- def self.config_file
174
- return @@config_file
175
- end
176
-
177
- #-----------------------------------------------------------------------------
178
- # Initialization
179
-
180
- @@initialized = false
181
-
182
- def self.initialize
183
- unless @@initialized
184
- Config.set_property('time', Time.now.to_i)
185
-
186
- begin
187
- # Include Coral plugins
188
- Puppet::Node::Environment.new.modules.each do |mod|
189
- lib_path = File.join(mod.path, 'lib', 'coral')
190
- Plugin.register(lib_path)
191
- end
192
- rescue
193
- end
194
-
195
- Plugin.initialize
196
-
197
- @@initialized = true
198
- end
199
- end
200
-
201
- #---
202
-
203
- def self.initialized?
204
- return @@initialized
205
- end
206
-
207
- #-----------------------------------------------------------------------------
208
- # Plugins
209
-
210
- def self.plugin(type, provider, options = {})
211
- default_provider = Plugin.type_default(type)
212
-
213
- if options.is_a?(Hash) || options.is_a?(Coral::Config)
214
- config = Config.ensure(options)
215
- provider = config.get(:provider, provider)
216
- name = config.get(:name, ( provider ? provider : default_provider ))
217
- options = config.export
218
- end
219
- provider = default_provider unless provider # Sanity checking (see plugins)
220
- existing_instance = Plugin.get_instance(type, name) if name
221
-
222
- return existing_instance if existing_instance
223
- return Plugin.create_instance(type, provider, options)
224
- end
225
-
226
- #---
227
-
228
- def self.plugins(type, data, build_hash = false, keep_array = false)
229
- group = ( build_hash ? {} : [] )
230
- klass = class_const([ :coral, :plugin, type ])
231
- data = klass.build_info(type, data) if klass.respond_to?(:build_info)
232
-
233
- data.each do |options|
234
- if plugin = plugin(type, options[:provider], options)
235
- if build_hash
236
- group[plugin.name] = plugin
237
- else
238
- group << plugin
239
- end
240
- end
241
- end
242
- return group.shift if ! build_hash && group.length == 1 && ! keep_array
243
- return group
244
- end
245
-
246
- #---
247
-
248
- def self.get_plugin(type, name)
249
- return Plugin.get_instance(type, name)
250
- end
251
-
252
- #---
253
-
254
- def self.remove_plugin(plugin)
255
- return Plugin.remove_instance(plugin)
256
- end
257
-
258
- #-----------------------------------------------------------------------------
259
- # Core plugin type facade
260
-
261
- def self.network(name, options = {}, provider = nil)
262
- plugin = plugin(:network, provider, options)
263
- plugin.name = name
264
- return plugin
265
- end
266
-
267
- #---
268
-
269
- def self.networks(data, build_hash = false, keep_array = false)
270
- return plugins(:network, data, build_hash, keep_array)
271
- end
272
-
273
- #---
274
-
275
- def self.node(name, options = {}, provider = nil)
276
- plugin = plugin(:node, provider, options)
277
- plugin.name = name
278
- return plugin
279
- end
280
-
281
- #---
282
-
283
- def self.nodes(data, build_hash = false, keep_array = false)
284
- return plugins(:node, data, build_hash, keep_array)
285
- end
286
-
287
- #---
288
-
289
- def self.machine(options = {}, provider = nil)
290
- plugin = plugin(:machine, provider, options)
291
- return plugin
292
- end
293
-
294
- #---
295
-
296
- def self.machines(data, build_hash = false, keep_array = false)
297
- return plugins(:machine, data, build_hash, keep_array)
298
- end
299
-
300
- #---
301
-
302
- def self.command(options, provider = nil)
303
- return plugin(:command, provider, options)
304
- end
305
-
306
- #---
307
-
308
- def self.commands(data, build_hash = false, keep_array = false)
309
- return plugins(:command, data, build_hash, keep_array)
310
- end
311
-
312
- #-----------------------------------------------------------------------------
313
- # External execution
314
-
315
- def self.run
316
- begin
317
- initialize
318
- yield
319
-
320
- rescue Exception => error
321
- ui.warn(error.inspect)
322
- ui.warn(Util::Data.to_yaml(error.backtrace))
323
- raise
324
- end
325
- end
326
-
327
- #-----------------------------------------------------------------------------
328
- # Utilities
329
-
330
- def self.class_name(name, separator = '::', want_array = FALSE)
331
- components = []
332
-
333
- case name
334
- when String, Symbol
335
- components = name.to_s.split(separator)
336
- when Array
337
- components = name
338
- end
339
-
340
- components.collect! do |value|
341
- value.to_s.strip.capitalize
342
- end
343
-
344
- if want_array
345
- return components
346
- end
347
- return components.join(separator)
348
- end
349
-
350
- #---
351
-
352
- def self.class_const(name, separator = '::')
353
- components = class_name(name, separator, TRUE)
354
- constant = Object
355
-
356
- components.each do |component|
357
- constant = constant.const_defined?(component) ?
358
- constant.const_get(component) :
359
- constant.const_missing(component)
360
- end
361
-
362
- return constant
363
- end
364
-
365
- #---
366
-
367
- def self.sha1(data)
368
- return Digest::SHA1.hexdigest(Util::Data.to_json(data, false))
369
- end
370
- end
371
-
372
- #-------------------------------------------------------------------------------
373
- # Coral initialization
374
-
375
- Coral.initialize
data/locales/en.yml DELETED
@@ -1,8 +0,0 @@
1
- en:
2
- coral:
3
- core:
4
- util:
5
- cli:
6
- options:
7
- help: |-
8
- Display help information for this command
@@ -1,489 +0,0 @@
1
-
2
- require 'spec_helper'
3
-
4
- module Coral
5
-
6
- describe Util::Interface do
7
-
8
- #---------------------------------------------------------------------------
9
- # UI functionality
10
-
11
- describe "#say" do
12
-
13
- #-------------------------------------------------------------------------
14
- # Delegation
15
-
16
- it "can delegate to another class that contains this method" do
17
- output = double('output')
18
- output.should_receive(:puts).with('message')
19
-
20
- ui = Util::Interface.new({
21
- :output => output,
22
- :printer => :puts,
23
- })
24
- Util::Interface.new({ :ui_delegate => ui }).say(:info, 'message')
25
- end
26
-
27
- #-------------------------------------------------------------------------
28
- # Output formats
29
-
30
- it "prints a message with default options" do
31
- output1 = double('output1')
32
- output1.should_receive(:puts).with('message')
33
-
34
- Util::Interface.new({ :output => output1 }).say(:info, 'message')
35
-
36
- output2 = double('output2')
37
- output2.should_receive(:puts).with('[component] message')
38
-
39
- Util::Interface.new({
40
- :resource => 'component',
41
- :output => output2,
42
- }).say(:info, 'message')
43
- end
44
-
45
- #---
46
-
47
- it "prints a message with and without newlines included" do
48
- output1 = double('output1')
49
- output1.should_receive(:puts).with('message')
50
-
51
- test = Util::Interface.new({ :output => output1 })
52
- test.say(:info, 'message', { :new_line => true })
53
-
54
- output2 = double('output2')
55
- output2.should_receive(:print).with('message')
56
-
57
- test = Util::Interface.new({ :output => output2 })
58
- test.say(:info, 'message', { :new_line => false })
59
- end
60
-
61
- #---
62
-
63
- it "routes message to output and error channels based on type given" do
64
- [:info, :warn, :success].each do |type|
65
- output = double('output')
66
- output.should_receive(:puts).with('message')
67
-
68
- Util::Interface.new({
69
- :output => output,
70
- :printer => :puts,
71
- :color => false,
72
- }).say(type, 'message')
73
- end
74
-
75
- error = double('error')
76
- error.should_receive(:puts).with('message')
77
-
78
- Util::Interface.new({
79
- :error => error,
80
- :printer => :puts,
81
- :color => false,
82
- }).say(:error, 'message')
83
- end
84
-
85
- #---
86
-
87
- it "routes message to output and error channels based on channel given" do
88
- [:info, :warn, :success].each do |type|
89
- output = double('output')
90
- output.should_receive(:puts).with('message')
91
-
92
- Util::Interface.new({
93
- :output => output,
94
- :printer => :puts,
95
- }).say(:info, 'message', { :channel => type })
96
- end
97
-
98
- error = double('error')
99
- error.should_receive(:puts).with('message')
100
-
101
- Util::Interface.new({
102
- :error => error,
103
- :printer => :puts,
104
- :color => false,
105
- }).say(:info, 'message', { :channel => :error })
106
- end
107
- end
108
-
109
- #---
110
-
111
- describe "#ask" do
112
-
113
- #-------------------------------------------------------------------------
114
- # Delegation
115
-
116
- it "can delegate to another class that contains this method"
117
-
118
- #-------------------------------------------------------------------------
119
- # Input
120
-
121
- it "displays a prompt and returns user feedback"
122
- end
123
-
124
- #---
125
-
126
- describe "#info" do
127
-
128
- #-------------------------------------------------------------------------
129
- # Delegation
130
-
131
- it "can delegate to another class that contains this method" do
132
- output = double('output')
133
- output.should_receive(:puts).with('message')
134
-
135
- ui = Util::Interface.new({
136
- :output => output,
137
- :printer => :puts,
138
- })
139
- Util::Interface.new({ :ui_delegate => ui }).info('message')
140
- end
141
-
142
- #-------------------------------------------------------------------------
143
- # Printing
144
-
145
- it "prints an uncolored information message" do
146
- output = double('output')
147
- output.should_receive(:puts).with('message')
148
-
149
- Util::Interface.new({
150
- :output => output,
151
- :printer => :puts,
152
- }).info('message')
153
- end
154
- end
155
-
156
- #---
157
-
158
- describe "#warn" do
159
-
160
- #-------------------------------------------------------------------------
161
- # Delegation
162
-
163
- it "can delegate to another class that contains this method" do
164
- output = double('output')
165
- output.should_receive(:puts).with('message')
166
-
167
- ui = Util::Interface.new({
168
- :output => output,
169
- :printer => :puts,
170
- :color => false,
171
- })
172
- Util::Interface.new({ :ui_delegate => ui }).warn('message')
173
- end
174
-
175
- #-------------------------------------------------------------------------
176
- # Printing
177
-
178
- it "prints an uncolored warning message" do
179
- output = double('output')
180
- output.should_receive(:puts).with('message')
181
-
182
- Util::Interface.new({
183
- :output => output,
184
- :printer => :puts,
185
- :color => false,
186
- }).warn('message')
187
- end
188
-
189
- #---
190
-
191
- it "prints a colored warning message" do
192
- output = double('output')
193
- output.should_receive(:print).with(/^\e\[33mmessage\e\[0m$/)
194
-
195
- Util::Interface.new({
196
- :output => output,
197
- :color => true,
198
- }).warn('message', { :new_line => false })
199
- end
200
- end
201
-
202
- #---
203
-
204
- describe "#error" do
205
-
206
- #-------------------------------------------------------------------------
207
- # Delegation
208
-
209
- it "can delegate to another class that contains this method" do
210
- error = double('error')
211
- error.should_receive(:puts).with('message')
212
-
213
- ui = Util::Interface.new({
214
- :error => error,
215
- :printer => :puts,
216
- :color => false,
217
- })
218
- Util::Interface.new({ :ui_delegate => ui }).error('message')
219
- end
220
-
221
- #-------------------------------------------------------------------------
222
- # Printing
223
-
224
- it "prints an uncolored error message" do
225
- error = double('error')
226
- error.should_receive(:puts).with('message')
227
-
228
- Util::Interface.new({
229
- :error => error,
230
- :printer => :puts,
231
- :color => false,
232
- }).error('message')
233
- end
234
-
235
- #---
236
-
237
- it "prints a colored error message" do
238
- error = double('error')
239
- error.should_receive(:print).with(/^\e\[31mmessage\e\[0m$/)
240
-
241
- Util::Interface.new({
242
- :error => error,
243
- :color => true,
244
- }).error('message', { :new_line => false })
245
- end
246
- end
247
-
248
- #---
249
-
250
- describe "#success" do
251
-
252
- #-------------------------------------------------------------------------
253
- # Delegation
254
-
255
- it "can delegate to another class that contains this method" do
256
- output = double('output')
257
- output.should_receive(:puts).with('message')
258
-
259
- ui = Util::Interface.new({
260
- :output => output,
261
- :printer => :puts,
262
- :color => false,
263
- })
264
- Util::Interface.new({ :ui_delegate => ui }).success('message')
265
- end
266
-
267
- #-------------------------------------------------------------------------
268
- # Printing
269
-
270
- it "prints an uncolored success message" do
271
- output = double('output')
272
- output.should_receive(:puts).with('message')
273
-
274
- Util::Interface.new({
275
- :output => output,
276
- :printer => :puts,
277
- :color => false,
278
- }).success('message')
279
- end
280
-
281
- #---
282
-
283
- it "prints a colored success message" do
284
- output = double('output')
285
- output.should_receive(:print).with(/^\e\[32mmessage\e\[0m$/)
286
-
287
- Util::Interface.new({
288
- :output => output,
289
- :color => true,
290
- }).success('message', { :new_line => false })
291
- end
292
- end
293
-
294
- #---------------------------------------------------------------------------
295
- # Utilities
296
-
297
- describe "#format_message" do
298
-
299
- #-------------------------------------------------------------------------
300
- # Delegation
301
-
302
- it "can delegate to another class that contains this method" do
303
- message = Util::Interface.new({
304
- :ui_delegate => Util::Interface.new('delegate')
305
- }).format_message(:info, 'message', { :prefix => true })
306
-
307
- message.should == '[delegate] message'
308
- end
309
-
310
- #-------------------------------------------------------------------------
311
- # Prefix specifications
312
-
313
- it "returns without a prefix because no resource" do
314
- message = Util::Interface.new.format_message(:info, 'message', { :prefix => true })
315
- message.should == 'message'
316
- end
317
-
318
- #---
319
-
320
- it "returns without a prefix because prefix is false" do
321
- message = Util::Interface.new('component').format_message(:info, 'message', { :prefix => false })
322
- message.should == 'message'
323
- end
324
-
325
- #---
326
-
327
- it "returns without a prefix because no prefix option given" do
328
- message = Util::Interface.new('component').format_message(:info, 'message')
329
- message.should == 'message'
330
- end
331
-
332
- #---
333
-
334
- it "returns with a prefix if resource and prefix option given" do
335
- message = Util::Interface.new('component').format_message(:info, 'message', { :prefix => true })
336
- message.should == '[component] message'
337
- end
338
-
339
- #-------------------------------------------------------------------------
340
- # Color specifications
341
-
342
- it "formats a error message in red if color enabled" do
343
- message = Util::Interface.new({
344
- :resource => 'component',
345
- :color => true,
346
- }).format_message(:error, 'message')
347
- message.should match(/^\e\[31mmessage\e\[0m$/)
348
- end
349
-
350
- #---
351
-
352
- it "formats a warning message in yellow if color enabled" do
353
- message = Util::Interface.new({
354
- :resource => 'component',
355
- :color => true,
356
- }).format_message(:warn, 'message')
357
- message.should match(/^\e\[33mmessage\e\[0m$/)
358
- end
359
-
360
- #---
361
-
362
- it "formats a success message in green if color enabled" do
363
- message = Util::Interface.new({
364
- :resource => 'component',
365
- :color => true,
366
- }).format_message(:success, 'message')
367
- message.should match(/^\e\[32mmessage\e\[0m$/)
368
- end
369
- end
370
-
371
- #---------------------------------------------------------------------------
372
-
373
- describe "#safe_puts" do
374
-
375
- #-------------------------------------------------------------------------
376
- # Delegation
377
-
378
- it "can delegate to another class that contains this method" do
379
- output = double('output')
380
- output.should_receive(:puts).with('message')
381
-
382
- ui = Util::Interface.new({
383
- :output => output,
384
- :printer => :puts,
385
- })
386
- Util::Interface.new({ :ui_delegate => ui }).safe_puts('message')
387
- end
388
-
389
- #-------------------------------------------------------------------------
390
- # Instance configuration
391
-
392
- it "prints an empty string unless message given" do
393
- output = double('output')
394
- output.should_receive(:puts).with('')
395
-
396
- Util::Interface.new({
397
- :output => output,
398
- :printer => :puts,
399
- }).safe_puts()
400
- end
401
-
402
- #---
403
-
404
- it "prints to different output channels if they are given" do
405
- output1 = double('output1')
406
- output1.should_receive(:puts).with('message')
407
-
408
- test = Util::Interface.new({
409
- :output => output1,
410
- :printer => :puts,
411
- })
412
- test.safe_puts('message')
413
-
414
- output2 = double('output2')
415
- output2.should_receive(:puts).with('message')
416
-
417
- test.output = output2
418
- test.safe_puts('message')
419
- end
420
-
421
- #---
422
-
423
- it "prints with puts if puts printer option given" do
424
- output = double('output')
425
- output.should_receive(:puts).with('message')
426
-
427
- Util::Interface.new({
428
- :output => output,
429
- :printer => :puts,
430
- }).safe_puts('message')
431
- end
432
-
433
- #---
434
-
435
- it "prints with print if print printer option given" do
436
- output = double('output')
437
- output.should_receive(:print).with('message')
438
-
439
- Util::Interface.new({
440
- :output => output,
441
- :printer => :print,
442
- }).safe_puts('message')
443
- end
444
-
445
- #-------------------------------------------------------------------------
446
- # Method configuration
447
-
448
- it "can override the instance output channel" do
449
- output1 = double('output1')
450
- output1.should_not_receive(:puts).with('message')
451
-
452
- output2 = double('output2')
453
- output2.should_receive(:puts).with('message')
454
-
455
- Util::Interface.new({
456
- :output => output1,
457
- :printer => :puts,
458
- }).safe_puts('message', { :channel => output2 })
459
- end
460
-
461
- #---
462
-
463
- it "can override the instance printer handler" do
464
- output = double('output')
465
- output.should_not_receive(:puts).with('message')
466
- output.should_receive(:print).with('message')
467
-
468
- Util::Interface.new({
469
- :output => output,
470
- :printer => :puts,
471
- }).safe_puts('message', { :printer => :print })
472
- end
473
- end
474
-
475
- #---------------------------------------------------------------------------
476
-
477
- describe "#check_delegate" do
478
-
479
- it "returns false if no delegate exists" do
480
- Util::Interface.new.check_delegate('safe_puts').should be_false
481
- end
482
- it "returns true if a delegate exists and it implements given method" do
483
- test = Util::Interface.new({ :ui_delegate => Util::Interface.new })
484
- test.check_delegate('safe_puts').should be_true
485
- test.check_delegate('nonexistent').should be_false
486
- end
487
- end
488
- end
489
- end