maestro_plugin 0.0.2

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/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use jruby-1.6.8
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ maestro_plugin (0.0.2)
5
+ json (>= 1.4.6)
6
+ logging (= 1.8.0)
7
+ rubyzip (= 0.9.8)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ bouncy-castle-java (1.5.0147)
13
+ diff-lcs (1.2.1)
14
+ jruby-openssl (0.8.7)
15
+ bouncy-castle-java (>= 1.5.0147)
16
+ json (1.7.7-java)
17
+ little-plugger (1.1.3)
18
+ logging (1.8.0)
19
+ little-plugger (>= 1.1.3)
20
+ multi_json (>= 1.3.6)
21
+ multi_json (1.3.6)
22
+ rake (10.0.4)
23
+ rspec (2.13.0)
24
+ rspec-core (~> 2.13.0)
25
+ rspec-expectations (~> 2.13.0)
26
+ rspec-mocks (~> 2.13.0)
27
+ rspec-core (2.13.0)
28
+ rspec-expectations (2.13.0)
29
+ diff-lcs (>= 1.1.3, < 2.0)
30
+ rspec-mocks (2.13.0)
31
+ rubyzip (0.9.8)
32
+
33
+ PLATFORMS
34
+ java
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ bundler (~> 1.3)
39
+ jruby-openssl
40
+ maestro_plugin!
41
+ rake
42
+ rspec (~> 2.13.0)
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Etienne Pelletier
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ maestro_plugin Gem
2
+ ===================
3
+
4
+ Library For Creating Ruby Based Maestro Plugins
5
+ =======
6
+
7
+ # Introduction
8
+
9
+ Maestro 4 provides support for plugins written in Java and Ruby. They are both permitted to have dependent libraries.
10
+ Ruby based plugins provide the worker source file (.rb) and any dependencies (.gem) are loaded using the Rubygems (gem)
11
+ executable. Both plugin types provide a manifest file (manifest.json) that details the contents and attributes of the
12
+ plugin.
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'maestro_plugin'
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install maestro_plugin
27
+
28
+ ## Usage
29
+
30
+ ### Directory Layout
31
+
32
+ Your plugin source directory should contain the following subdirectories:
33
+
34
+ * src - contains the plugin source code.
35
+ * spec - contains the plugin RSpec testing code.
36
+ * images - contains the plugin images displayed in the task list and composition bar.
37
+
38
+ ### The Manifest
39
+
40
+ TBD
41
+
42
+ ### The Worker Class
43
+
44
+ The logic for your plugin is implemented by a worker class. This class should extend the Maestro::MaestroWorker class.
45
+ Set it in the *class* parameter of your manifest. The command parameter for each task defined in the manifest must have
46
+ a matching method in your worker.
47
+
48
+ ### Unit Testing Your Plugin
49
+
50
+ You can use RSpec to perform unit testing. If your plugin invokes any of the utility methods in the MaestroWorker class,
51
+ you should make sure to set the MaestroWorker class to "mock" mode so that it doesn't attempt to post messages on the
52
+ response queue. You can do this by calling the *Maestro::MaestroWorker.mock!* method.
53
+
54
+ ### Packaging Your Plugin
55
+
56
+ You must package your plugin into a zip file. It must contain the following files and directory:
57
+
58
+ * src - the source directory
59
+ * images - the directory containing the image displayed on the Maestro UI in the task list and composition bar.
60
+ * vendor - the directory containing all the gem dependencies.
61
+ * manifest.json - the manifest.
62
+ * README.md - the README file (optional)
63
+ * LICENSE - the license file (optional)
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rake/clean'
4
+
5
+ require File.expand_path('../lib/maestro_plugin/version', __FILE__)
6
+
7
+ CLEAN.include([ 'pkg', '*.gem'])
8
+
9
+ task :default => [:build]
10
+
11
+ desc 'Run specs'
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.pattern = './spec/**/*_spec.rb' # don't need this, it's default.
14
+ t.rspec_opts = '--fail-fast --format p --color'
15
+ # Put spec opts in a file named .rspec in root
16
+ end
17
+
18
+ desc 'Get dependencies with Bundler'
19
+ task :bundle do
20
+ system 'bundle install'
21
+ end
22
+
23
+ task :build => [:clean, :bundle, :spec]
24
+ task :build do
25
+ system 'gem build maestro_plugin.gemspec'
26
+ end
27
+
@@ -0,0 +1,21 @@
1
+ # Copyright 2013© MaestroDev. All rights reserved.
2
+ require 'logging'
3
+
4
+ module Maestro
5
+
6
+ unless Maestro.const_defined?('Logging')
7
+
8
+ module Logging
9
+
10
+ def log
11
+ ::Logging::Logger.new(STDOUT)
12
+ end
13
+
14
+ end
15
+ end
16
+
17
+ class << self
18
+ include Maestro::Logging unless Maestro.include?(Maestro::Logging)
19
+ end
20
+
21
+ end
@@ -0,0 +1,279 @@
1
+ require 'json'
2
+
3
+ module Maestro
4
+
5
+
6
+ # Helper Class for Maestro Plugins written in Ruby. The lifecycle of the plugin
7
+ # starts with a call to the main entry point perform called by the Maestro agent, all the
8
+ # other methods are helpers that can be used to deal with parsing, errors, etc. The lifecycle ends with a call to
9
+ # run_callbacks which can be customized by specifying an on_complete_handler_method, or on_complete_handler_block.
10
+ #
11
+ class MaestroWorker
12
+
13
+ # Workitem constants
14
+ CONTEXT_OUTPUTS_META = '__context_outputs__'
15
+ OUTPUT_META = '__output__'
16
+ PREVIOUS_CONTEXT_OUTPUTS_META = '__previous_context_outputs__'
17
+ STREAMING_META = '__streaming__'
18
+ ERROR_META = '__error__'
19
+ WAITING_META = '__waiting__'
20
+ CANCEL_META = '__cancel__'
21
+ NOT_NEEDED = '__not_needed__'
22
+ LINKS_META = '__links__'
23
+ PERSIST_META = '__persist__'
24
+ MODEL_META = '__model__'
25
+ RECORD_ID_META = '__record_id__'
26
+ RECORD_FIELD_META = '__record_field__'
27
+ RECORD_VALUE_META = '__record_value__'
28
+ RECORD_FIELDS_META = '__record_fields__'
29
+ RECORD_VALUES_META = '__record_values__'
30
+ FILTER_META = '__filter__'
31
+ NAME_META = '__name__'
32
+ CREATE_META = '__create__'
33
+ UPDATE_META = '__update__'
34
+ DELETE_META = '__delete__'
35
+
36
+ class << self
37
+
38
+ attr_reader :exception_handler_method, :exception_handler_block, :on_complete_handler_method, :on_complete_handler_block
39
+
40
+ # Register a callback method or block that gets called when an exception
41
+ # occurs during the processing of an action. +handler+ can be a symbol or
42
+ # string with a method name, or a block. Both will get the exception as
43
+ # the first parameter, and the block handler will receive the participant
44
+ # instance as the second parameter
45
+ def on_exception(handler = nil, &block)
46
+ @exception_handler_method = handler
47
+ @exception_handler_block = block
48
+ end
49
+
50
+ # Register a callback method or block that gets called when the action
51
+ # was successfully completed. Block callbacks get the workitem as
52
+ # parameter.
53
+ def on_complete(handler = nil, &block)
54
+ @on_complete_handler_method = handler
55
+ @on_complete_handler_block = block
56
+ end
57
+
58
+ # Call this to mock calls to outbound systems.
59
+ def mock!
60
+ @mock = true
61
+ end
62
+
63
+ # Call this to unmock calls to outbound systems.
64
+ def unmock!
65
+ @mock = false
66
+ end
67
+
68
+ def mock?
69
+ @mock
70
+ end
71
+
72
+ end
73
+
74
+ attr_accessor :workitem, :action
75
+
76
+ def is_json?(string)
77
+ JSON.parse string
78
+ true
79
+ rescue Exception
80
+ false
81
+ end
82
+
83
+ alias :is_json :is_json?
84
+
85
+ # Perform the specified action with the provided workitem. Invokes the method specified by the action parameter.
86
+ #
87
+ def perform(action, workitem)
88
+ @action, @workitem = action, workitem
89
+ send(action)
90
+ run_callbacks
91
+ rescue => e
92
+ handle_exception(e)
93
+ end
94
+
95
+ def handle_exception(e)
96
+ raise e if self.class.exception_handler_method.nil? && self.class.exception_handler_block.nil?
97
+
98
+ if self.class.exception_handler_method
99
+ send(self.class.exception_handler_method, e)
100
+ else
101
+ self.class.exception_handler_block.call(e, self)
102
+ end
103
+ end
104
+
105
+ def run_callbacks
106
+ return if self.class.on_complete_handler_block.nil? && self.class.on_complete_handler_method.nil?
107
+
108
+ if self.class.on_complete_handler_method
109
+ send(self.class.on_complete_handler_method)
110
+ else
111
+ self.class.on_complete_handler_block.call(workitem)
112
+ end
113
+ end
114
+
115
+ # Set a value in the context output
116
+ def save_output_value(name, value)
117
+ set_field(CONTEXT_OUTPUTS_META, {}) if get_field(CONTEXT_OUTPUTS_META).nil?
118
+ get_field(CONTEXT_OUTPUTS_META)[name] = value
119
+ end
120
+
121
+ # Read a value from the context output
122
+ def read_output_value(name)
123
+ if get_field(PREVIOUS_CONTEXT_OUTPUTS_META).nil?
124
+ set_field(CONTEXT_OUTPUTS_META, {}) if get_field(CONTEXT_OUTPUTS_META).nil?
125
+ get_field(CONTEXT_OUTPUTS_META)[name]
126
+ else
127
+ get_field(PREVIOUS_CONTEXT_OUTPUTS_META)[name]
128
+ end
129
+ end
130
+
131
+ # Sends the specified ouput string to the server for persistence
132
+ def write_output(output)
133
+ return if output.gsub(/\n/, '').empty?
134
+
135
+ workitem[OUTPUT_META] = output
136
+ workitem[STREAMING_META] = true
137
+ send_workitem_message
138
+ rescue Exception => e
139
+ Maestro.log.warn "Unable To Write Output To Server #{e.class} #{e}: #{e.backtrace.join("\n")}"
140
+ ensure
141
+ workitem.delete(STREAMING_META)
142
+ end
143
+
144
+ def error
145
+ fields[ERROR_META]
146
+ end
147
+
148
+ def error?
149
+ !(error.nil? or error.empty?)
150
+ end
151
+
152
+ def set_error(error)
153
+ set_field(ERROR_META, error)
154
+ end
155
+
156
+ #control
157
+
158
+ # Sets the current task as waiting
159
+ def set_waiting(should_wait)
160
+ workitem[WAITING_META] = should_wait
161
+ send_workitem_message
162
+ rescue Exception => e
163
+ Maestro.log.warn "Failed To Send Waiting Message To Server #{e.class} #{e}: #{e.backtrace.join("\n")}"
164
+ ensure
165
+ workitem.delete(WAITING_META) unless should_wait
166
+ end
167
+
168
+ # Send the "cancel" message to the server
169
+ def cancel
170
+ workitem[CANCEL_META] = true
171
+ send_workitem_message
172
+ rescue Exception => e
173
+ Maestro.log.warn "Failed To Send Cancel Message To Server #{e.class} #{e}: #{e.backtrace.join("\n")}"
174
+ ensure
175
+ workitem.delete(CANCEL_META)
176
+ end
177
+
178
+
179
+ # Send the "not needed" message to the server.
180
+ def not_needed
181
+ workitem[NOT_NEEDED] = true
182
+ send_workitem_message
183
+ rescue Exception => e
184
+ Maestro.log.warn "Failed To Send Not Needed Message To Server #{e.class} #{e}: #{e.backtrace.join("\n")}"
185
+ ensure
186
+ workitem.delete(NOT_NEEDED)
187
+ end
188
+
189
+ # end control
190
+
191
+ # persistence
192
+ def update_fields_in_record(model, name_or_id, record_field, record_value)
193
+ workitem[PERSIST_META] = true
194
+ workitem[UPDATE_META] = true
195
+ workitem[MODEL_META] = model
196
+ workitem[RECORD_ID_META] = name_or_id.to_s
197
+ workitem[RECORD_FIELD_META] = record_field
198
+ workitem[RECORD_VALUE_META] = record_value
199
+
200
+ send_workitem_message
201
+
202
+ workitem.delete(PERSIST_META)
203
+ workitem.delete(UPDATE_META)
204
+ end
205
+
206
+
207
+ def create_record_with_fields(model, record_fields, record_values = nil)
208
+ workitem[PERSIST_META] = true
209
+ workitem[CREATE_META] = true
210
+ workitem[MODEL_META] = model
211
+ unless record_fields.is_a? Hash
212
+ Maestro.log.warn 'deprecation: create_record_with_fields should be called with a Hash'
213
+ record_fields = record_fields.join(',') if record_fields.respond_to? 'join'
214
+ record_values = record_values.join(',') if record_values.respond_to? 'join'
215
+ end
216
+
217
+ workitem[RECORD_FIELDS_META] = record_fields
218
+ workitem[RECORD_VALUES_META] = record_values
219
+ send_workitem_message
220
+
221
+ workitem.delete(PERSIST_META)
222
+ workitem.delete(CREATE_META)
223
+ end
224
+
225
+
226
+ def delete_record(model, filter)
227
+ workitem[PERSIST_META] = true
228
+ workitem[DELETE_META] = true
229
+ workitem[MODEL_META] = model
230
+
231
+ if filter.is_a? Hash
232
+ workitem[FILTER_META] = filter
233
+ else
234
+ Maestro.log.warn 'deprecation: delete_record should be called with a Hash'
235
+ workitem[NAME_META] = filter.to_s
236
+ end
237
+
238
+ send_workitem_message
239
+
240
+ workitem.delete(PERSIST_META)
241
+ workitem.delete(DELETE_META)
242
+ end
243
+
244
+ # end persistence
245
+
246
+ def get_field(field)
247
+ fields[field]
248
+ end
249
+
250
+ def fields
251
+ workitem['fields']
252
+ end
253
+
254
+ alias_method :get_fields, :fields
255
+
256
+
257
+ def set_field(field, value)
258
+ fields[field] = value
259
+ end
260
+
261
+ # Adds a link to be displayed in the Maestro UI.
262
+ def add_link(name, url)
263
+ set_field(LINKS_META, []) if fields[LINKS_META].nil?
264
+ fields[LINKS_META] << {'name' => name, 'url' => url}
265
+ end
266
+
267
+ private
268
+
269
+ def send_workitem_message
270
+ ruote_participants.send_workitem_message(workitem) unless MaestroWorker.mock?
271
+ end
272
+
273
+ def ruote_participants
274
+ Maestro::RuoteParticipants.instance
275
+ end
276
+
277
+
278
+ end
279
+ end
@@ -0,0 +1,5 @@
1
+ module Maestro
2
+ module Plugin
3
+ VERSION = '0.0.2'
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ # Copyright 2013© MaestroDev. All rights reserved.
2
+ require 'maestro_plugin/version'
3
+ require 'maestro_plugin/logging'
4
+ require 'maestro_plugin/maestro_worker'
5
+
6
+
7
+
8
+
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'maestro_plugin/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'maestro_plugin'
8
+ spec.version = Maestro::Plugin::VERSION
9
+ spec.authors = ['Etienne Pelletier']
10
+ spec.email = ['epelletier@maestrodev.com']
11
+ spec.description = %q{A ruby library to help with the creation of Maestro plugins}
12
+ spec.summary = %q{Maestro ruby plugin}
13
+ spec.homepage = 'https://github.com/maestrodev/maestro-ruby-plugin'
14
+ spec.license = 'Apache 2.0'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'logging', '1.8.0'
22
+ spec.add_dependency 'rubyzip', '0.9.8'
23
+ spec.add_dependency 'json', '>= 1.4.6'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.3'
26
+ spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'jruby-openssl'
28
+ spec.add_development_dependency 'rspec', '~> 2.13.0'
29
+
30
+ end
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+
3
+ describe Maestro::MaestroWorker do
4
+
5
+ describe 'Mock' do
6
+
7
+ before :each do
8
+ Maestro::MaestroWorker.mock!
9
+ end
10
+
11
+ after :each do
12
+ Maestro::MaestroWorker.unmock!
13
+ end
14
+
15
+ it 'should mock send_workitem_message calls' do
16
+ @workitem = {'fields' => {}}
17
+
18
+ @worker = Maestro::MaestroWorker.new
19
+ @worker.stub(:workitem => @workitem)
20
+ @worker.should_not_receive(:ruote_participant)
21
+
22
+ @worker.write_output('Some test string')
23
+
24
+ end
25
+
26
+ end
27
+
28
+ describe 'Messaging' do
29
+ before :each do
30
+ @workitem = {'fields' => {}}
31
+ @ruote_participants = double("ruote_participants")
32
+ @ruote_participants.should_receive(:send_workitem_message).with(@workitem)
33
+
34
+ @worker = Maestro::MaestroWorker.new
35
+ @worker.stub(:ruote_participants => @ruote_participants)
36
+ @worker.stub(:workitem => @workitem)
37
+ @worker.should_receive(:send_workitem_message).at_least(:once).and_call_original
38
+
39
+ end
40
+
41
+ it 'should send a write_output message' do
42
+ @worker.write_output('Some Silly String')
43
+ @worker.workitem['__output__'].should eql('Some Silly String')
44
+ @worker.workitem['__streaming__'].should be_nil
45
+ end
46
+
47
+ it 'should send a not needed message' do
48
+ @worker.not_needed
49
+ @worker.workitem['__not_needed__'].should be_nil
50
+ end
51
+
52
+ it 'should send a cancel message' do
53
+ @worker.cancel
54
+ @worker.workitem['__cancel__'].should be_nil
55
+ end
56
+
57
+ it 'should send a set_waiting message' do
58
+ @ruote_participants.should_receive(:send_workitem_message).with(@workitem)
59
+ @worker.set_waiting(true)
60
+ @worker.workitem['__waiting__'].should be_true
61
+
62
+ @worker.set_waiting(false)
63
+ @worker.workitem['__waiting__'].should be_nil
64
+ end
65
+
66
+ it 'should send a create record message' do
67
+ @worker.create_record_with_fields('cars', ['manu', 'date', 'name'], ['ferrari', '1964', '250 GTO'])
68
+
69
+ @worker.workitem['__model__'].should eql('cars')
70
+ @worker.workitem['__record_fields__'].should eql('manu,date,name')
71
+ @worker.workitem['__record_values__'].should eql('ferrari,1964,250 GTO')
72
+ end
73
+
74
+ it 'should send a create record message with a hash' do
75
+ fields = {'manu' => 'ferrari', 'date' => '1964', 'name' => 'GTO'}
76
+ @worker.create_record_with_fields('cars', fields)
77
+ @worker.workitem['__model__'].should eql('cars')
78
+ @worker.workitem['__record_fields__'].should eql(fields)
79
+ end
80
+
81
+ it 'should send an update record-field message' do
82
+ @worker.update_fields_in_record('animal', 'donkey', 'name', 'e-or')
83
+
84
+ @worker.workitem['__model__'].should eql('animal')
85
+ @worker.workitem['__record_id__'].should eql('donkey')
86
+ @worker.workitem['__record_field__'].should eql('name')
87
+ @worker.workitem['__record_value__'].should eql('e-or')
88
+ end
89
+
90
+ it 'should send a delete record message' do
91
+ @worker.delete_record('animal', 1)
92
+ @worker.workitem['__model__'].should eql('animal')
93
+ @worker.workitem['__name__'].should eql('1')
94
+ @worker.workitem['__filter__'].should be_nil
95
+ end
96
+
97
+ it 'should send a delete record message with a filter' do
98
+ filter = {'type' => 1}
99
+ @worker.delete_record('animal', filter)
100
+ @worker.workitem['__model__'].should eql('animal')
101
+ @worker.workitem['__filter__'].should eql(filter)
102
+ @worker.workitem['__name__'].should be_nil
103
+ end
104
+ end
105
+
106
+ describe 'Field handling' do
107
+ before :each do
108
+ @worker = Maestro::MaestroWorker.new
109
+ @worker.workitem = {'fields' => {}}
110
+ end
111
+
112
+ it 'should set and get errors' do
113
+ @worker.workitem['__error__'].should be_nil
114
+ @worker.error?.should be_false
115
+ @worker.set_error 'myerror'
116
+ @worker.error?.should be_true
117
+ @worker.workitem['fields']['__error__'].should eq('myerror')
118
+ end
119
+
120
+ it 'should set fields' do
121
+ @worker.workitem = {'fields' => {'a' => 'a'}}
122
+ @worker.fields['a'].should eq('a')
123
+ @worker.fields['b'] = 'b'
124
+ @worker.fields['b'].should eq('b')
125
+ end
126
+ end
127
+
128
+ describe 'Helpers' do
129
+ before :each do
130
+ @worker = Maestro::MaestroWorker.new
131
+ @worker.workitem = {'fields' => {}}
132
+ end
133
+
134
+ it 'should validate JSON data contained in strings' do
135
+ @worker.is_json?('{"key": "a string"}').should be_true
136
+ @worker.is_json?('a string').should be_false
137
+ end
138
+
139
+
140
+
141
+ end
142
+ end
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'logger'
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib') unless $LOAD_PATH.include?(File.dirname(__FILE__) + '/../lib')
6
+
7
+ require 'maestro_plugin'
8
+
9
+ RSpec.configure do |config|
10
+
11
+ end
12
+
13
+
14
+
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: maestro_plugin
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - Etienne Pelletier
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2013-04-04 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: logging
17
+ version_requirements: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - "="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.8.0
23
+ requirement: *id001
24
+ prerelease: false
25
+ type: :runtime
26
+ - !ruby/object:Gem::Dependency
27
+ name: rubyzip
28
+ version_requirements: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - "="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.8
34
+ requirement: *id002
35
+ prerelease: false
36
+ type: :runtime
37
+ - !ruby/object:Gem::Dependency
38
+ name: json
39
+ version_requirements: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 1.4.6
45
+ requirement: *id003
46
+ prerelease: false
47
+ type: :runtime
48
+ - !ruby/object:Gem::Dependency
49
+ name: bundler
50
+ version_requirements: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: "1.3"
56
+ requirement: *id004
57
+ prerelease: false
58
+ type: :development
59
+ - !ruby/object:Gem::Dependency
60
+ name: rake
61
+ version_requirements: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ requirement: *id005
68
+ prerelease: false
69
+ type: :development
70
+ - !ruby/object:Gem::Dependency
71
+ name: jruby-openssl
72
+ version_requirements: &id006 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ requirement: *id006
79
+ prerelease: false
80
+ type: :development
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ version_requirements: &id007 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ version: 2.13.0
89
+ requirement: *id007
90
+ prerelease: false
91
+ type: :development
92
+ description: A ruby library to help with the creation of Maestro plugins
93
+ email:
94
+ - epelletier@maestrodev.com
95
+ executables: []
96
+
97
+ extensions: []
98
+
99
+ extra_rdoc_files: []
100
+
101
+ files:
102
+ - .gitignore
103
+ - .rvmrc
104
+ - Gemfile
105
+ - Gemfile.lock
106
+ - LICENSE.txt
107
+ - README.md
108
+ - Rakefile
109
+ - lib/maestro_plugin.rb
110
+ - lib/maestro_plugin/logging.rb
111
+ - lib/maestro_plugin/maestro_worker.rb
112
+ - lib/maestro_plugin/version.rb
113
+ - maestro_plugin.gemspec
114
+ - spec/maestro_worker_spec.rb
115
+ - spec/spec_helper.rb
116
+ homepage: https://github.com/maestrodev/maestro-ruby-plugin
117
+ licenses:
118
+ - Apache 2.0
119
+ post_install_message:
120
+ rdoc_options: []
121
+
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ hash: 2
130
+ segments:
131
+ - 0
132
+ version: "0"
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ hash: 2
139
+ segments:
140
+ - 0
141
+ version: "0"
142
+ requirements: []
143
+
144
+ rubyforge_project:
145
+ rubygems_version: 1.8.24
146
+ signing_key:
147
+ specification_version: 3
148
+ summary: Maestro ruby plugin
149
+ test_files:
150
+ - spec/maestro_worker_spec.rb
151
+ - spec/spec_helper.rb