obvious 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,199 +0,0 @@
1
- require 'yaml'
2
-
3
- require_relative 'helpers/application'
4
- require_relative 'descriptor'
5
-
6
- module Obvious
7
- module Generators
8
- class ApplicationGenerator
9
- class << self
10
- def generate
11
- @app = Obvious::Generators::Application.instance
12
-
13
- puts 'Generating the files...'
14
-
15
- Obvious::Generators::ApplicationGenerator.create_directories ['/', '/actions', '/contracts', '/entities',
16
- '/spec', '/spec/actions', '/spec/contracts', '/spec/entities',
17
- '/spec/doubles']
18
-
19
- unless File.exist? "#{@app.target_path}/Rakefile"
20
- puts 'Creating Rakefile...'
21
- `cp #{@app.lib_path}/obvious/files/Rakefile #{@app.target_path}/Rakefile`
22
- end
23
-
24
- unless File.exist? "#{@app.target_path}/external"
25
- puts 'Creating external directory'
26
- `cp -r #{@app.lib_path}/obvious/files/external #{@app.target_path}/external`
27
- end
28
-
29
- descriptors = Dir['descriptors/*.yml']
30
-
31
- puts 'Creating actions from descriptors... ' unless descriptors.length.zero?
32
- descriptors.each do |file|
33
- yaml = YAML.load_file(file)
34
- descriptor = Obvious::Generators::Descriptor.new yaml
35
- descriptor.to_file
36
- end
37
-
38
- @app.remove_duplicates
39
-
40
- puts 'Writing Entities scaffolds... '
41
- Obvious::Generators::ApplicationGenerator.write_entities
42
-
43
- puts 'Writing jacks scaffolds... '
44
- Obvious::Generators::ApplicationGenerator.write_jacks
45
-
46
- puts "Files are located in the `#{@app.dir}` directory."
47
- end # ::generate
48
-
49
- def create_directories directories
50
- directories.each do |dir|
51
- Dir.mkdir @app.dir + dir
52
- end
53
- end
54
-
55
- def write_entities
56
- @app.entities.each do |k, v|
57
- name = k
58
- method_specs = ''
59
- method_defs = ''
60
-
61
- method_defs << '
62
- def self.shape
63
- {}
64
- end
65
- '
66
-
67
- v.each do |method|
68
- method_defs << "
69
- def #{method} input
70
- nil
71
- end
72
- "
73
-
74
- method_specs << "
75
- describe '.#{method}' do
76
- it 'should #{method} with valid input'
77
-
78
- it 'should raise an error with invalid input'
79
-
80
- end
81
- "
82
- end
83
-
84
- output = %Q{class #{name}
85
- #{method_defs}
86
- end
87
- }
88
- snake_name = name.gsub(/(.)([A-Z])/,'\1_\2').downcase
89
-
90
- filename = "#{@app.dir}/entities/#{snake_name}.rb"
91
- File.open(filename, 'w') { |f| f.write(output) }
92
-
93
- output = %Q{require_relative '../../entities/#{snake_name}'
94
-
95
- describe #{name} do
96
- #{method_specs}
97
- end
98
- }
99
-
100
- filename = "#{@app.dir}/spec/entities/#{snake_name}_spec.rb"
101
- File.open(filename, 'w') {|f| f.write(output) }
102
- end
103
- end #write_entities
104
-
105
- def write_jacks
106
- @app.jacks.each do |k, v|
107
- name = k.chomp('Jack').downcase
108
- method_specs = ''
109
- contract_defs = ''
110
-
111
- jack_double_default_methods = ''
112
- jack_double_badoutput_methods = ''
113
-
114
- v.each do |method|
115
-
116
- contract_defs << "
117
- contract_for :#{method}, {
118
- :input => {},
119
- :output => {},
120
- }
121
- "
122
-
123
- method_specs << "
124
- describe '.#{method}_contract' do
125
- it 'should #{method} data with valid input'
126
-
127
- it 'should raise an error with invalid input'
128
-
129
- it 'should raise an error with invalid output'
130
-
131
- end
132
- "
133
-
134
- jack_double_default_methods << "
135
- def #{method} input
136
- {}
137
- end
138
- "
139
-
140
- jack_double_badoutput_methods << "
141
- def #{method} input
142
- nil
143
- end
144
- "
145
- end
146
-
147
- output = %Q{require 'obvious'
148
-
149
- class #{k}Contract < Obvious::Contract
150
- #{contract_defs}
151
- end
152
- }
153
-
154
- snake_name = k.gsub(/(.)([A-Z])/,'\1_\2').downcase
155
-
156
- filename = "#{@app.dir}/contracts/#{snake_name}_contract.rb"
157
- File.open(filename, 'w') {|f| f.write(output) }
158
-
159
- output = %Q{require_relative '../../contracts/#{snake_name}_contract'
160
-
161
- describe #{k}Contract do
162
- #{method_specs}
163
- end
164
- }
165
-
166
- filename = "#{@app.dir}/spec/contracts/#{snake_name}_spec.rb"
167
- File.open(filename, 'w') {|f| f.write(output) }
168
-
169
- output = %Q{require_relative '../../contracts/#{snake_name}_contract'
170
-
171
- class #{k}Double
172
- def self.create behavior
173
- case behavior
174
- when :bad_output
175
- #{k}_BadOutput.new
176
- when :default
177
- #{k}_Default.new
178
- end
179
- end
180
- end
181
-
182
- class #{k}_Default < #{k}Contract
183
- #{jack_double_default_methods}
184
- end
185
-
186
- class #{k}_BadOutput < #{k}Contract
187
- #{jack_double_badoutput_methods}
188
- end
189
- }
190
-
191
- filename = "#{@app.dir}/spec/doubles/#{snake_name}_double.rb"
192
- File.open(filename, 'w') {|f| f.write(output) }
193
-
194
- end
195
- end # generate_jacks_code
196
- end
197
- end
198
- end
199
- end
@@ -1,131 +0,0 @@
1
- require 'yaml'
2
-
3
- require_relative 'helpers/application'
4
-
5
- module Obvious
6
- module Generators
7
- class InvalidDescriptorError < StandardError; end
8
-
9
- class Descriptor
10
- def initialize descriptor
11
- @descriptor = descriptor
12
- end
13
-
14
- def to_file
15
- validate_descriptor
16
-
17
- @jacks, @entities = {}, {}
18
- @code = ''
19
-
20
- @descriptor['Code'].each do |entry|
21
- write_comments_for entry
22
- process_requirements_for entry if entry['requires']
23
- end
24
-
25
- write_action
26
- end
27
-
28
- private
29
- def write_comments_for entry
30
- @code << " \# #{entry['c']}\n"
31
- @code << " \# use: #{entry['requires']}\n" if entry['requires']
32
- @code << " \n"
33
- end
34
-
35
- def process_requirements_for entry
36
- app = Obvious::Generators::Application.instance
37
- requires = entry['requires'].split ','
38
-
39
- requires.each do |req|
40
- req.strip!
41
- infos = req.split '.'
42
-
43
- if infos[0].index 'Jack'
44
- app.jacks[infos[0]] = [] unless app.jacks[infos[0]]
45
- @jacks[infos[0]] = [] unless @jacks[infos[0]]
46
-
47
- app.jacks[infos[0]] << infos[1]
48
- @jacks[infos[0]] << infos[1]
49
- else
50
- app.entities[infos[0]] = [] unless app.entities[infos[0]]
51
- @entities[infos[0]] = [] unless @entities[infos[0]]
52
-
53
- app.entities[infos[0]] << infos[1]
54
- @entities[infos[0]] << infos[1]
55
- end
56
- end
57
- end # #process_requirements_for
58
-
59
- def write_action
60
- jacks_data = process_jacks
61
- requirements = require_entities
62
-
63
- output = %Q{#{requirements}
64
- class #{@descriptor['Action']}
65
-
66
- def initialize #{jacks_data[:inputs]}
67
- #{jacks_data[:assignments]} end
68
-
69
- def execute input
70
- #{@code} end
71
- end
72
- }
73
-
74
- snake_name = @descriptor['Action'].gsub(/(.)([A-Z])/,'\1_\2').downcase
75
-
76
- filename = "#{Obvious::Generators::Application.instance.dir}/actions/#{snake_name}.rb"
77
- File.open(filename, 'w') {|f| f.write(output) }
78
-
79
- output = %Q{require_relative '../../actions/#{snake_name}'
80
-
81
- describe #{@descriptor['Action']} do
82
-
83
- it '#{@descriptor['Description']}'
84
-
85
- it 'should raise an error with invalid input'
86
-
87
- end
88
- }
89
-
90
- filename = "#{Obvious::Generators::Application.instance.dir}/spec/actions/#{snake_name}_spec.rb"
91
- File.open(filename, 'w') {|f| f.write(output) }
92
- end
93
-
94
- def process_jacks
95
- jack_inputs = ''
96
- jack_assignments = ''
97
-
98
- @jacks.each do |k, v|
99
- name = k.chomp('Jack').downcase
100
- jack_inputs << "#{name}_jack, "
101
- jack_assignments << " @#{name}_jack = #{name}_jack\n"
102
- end
103
-
104
- jack_inputs.chomp! ', '
105
-
106
- {
107
- inputs: jack_inputs,
108
- assignments: jack_assignments
109
- }
110
- end
111
-
112
- def require_entities
113
- entity_requires = ''
114
-
115
- @entities.each do |k, v|
116
- snake_name = k.gsub(/(.)([A-Z])/,'\1_\2').downcase
117
- entity_requires << "require_relative '../entities/#{snake_name}'\n"
118
- end
119
-
120
- entity_requires
121
- end
122
-
123
- def validate_descriptor
124
- raise InvalidDescriptorError unless @descriptor
125
- raise InvalidDescriptorError if @descriptor['Code'].nil?
126
- raise InvalidDescriptorError if @descriptor['Action'].nil?
127
- raise InvalidDescriptorError if @descriptor['Description'].nil?
128
- end
129
- end # ::Descriptor
130
- end
131
- end
@@ -1,47 +0,0 @@
1
- require 'singleton'
2
-
3
- module Obvious
4
- module Generators
5
- class Application
6
- include Singleton
7
-
8
- attr_reader :jacks, :entities, :dir
9
-
10
- def initialize
11
- @dir = 'app'
12
-
13
- counter = 1
14
- while File.directory? @dir
15
- @dir = "app_#{counter}"
16
- counter += 1
17
- end
18
- end
19
-
20
- def jacks
21
- @jacks ||= {}
22
- end
23
-
24
- def entities
25
- @entities ||= {}
26
- end
27
-
28
- def target_path
29
- File.realpath Dir.pwd
30
- end
31
-
32
- def lib_path
33
- Gem::Specification.find_by_name("obvious").gem_dir + '/lib'
34
- end
35
-
36
- def remove_duplicates
37
- entities.each do |k, v|
38
- v.uniq!
39
- end
40
-
41
- jacks.each do |k,v|
42
- v.uniq!
43
- end
44
- end
45
- end # ::Application
46
- end
47
- end
@@ -1,4 +0,0 @@
1
- task :rspec do
2
- sh 'rspec ./app -c'
3
- end
4
-
@@ -1,99 +0,0 @@
1
- require 'json'
2
-
3
- class FsPlug
4
-
5
- def initialize filename
6
- @filename = filename
7
- end
8
-
9
- def load_data
10
- contents = File.read @filename
11
- JSON.parse contents, :symbolize_names => true
12
- end
13
-
14
- def save_data input
15
- json_data = JSON.pretty_generate input
16
- File.open(@filename, 'w') {|f| f.write(json_data) }
17
- end
18
-
19
- def save input
20
- data = []
21
- query = load_data
22
-
23
- new_element = true if input[:id] == -1 # by convention set new element flag if id == -1
24
-
25
- max_id = -1
26
- # transform the data if needed
27
- query.each do |h|
28
- if input[:id] == h[:id]
29
- h = input
30
- end
31
- max_id = h[:id] if h[:id] > max_id
32
- data << h
33
- end
34
-
35
- # add data to the list if it's a new element
36
- if new_element
37
- input[:id] = max_id + 1
38
- data << input
39
- end
40
-
41
- save_data data
42
-
43
- # return the transformed data
44
- input
45
- end
46
-
47
- def list
48
- load_data
49
- end
50
-
51
- def get input
52
- data = []
53
- query = load_data
54
-
55
- # transform the data if needed
56
- query.each do |h|
57
- return h if h[:id] == input[:id]
58
- end
59
-
60
- raise Exception.new 'no object found'
61
- end
62
-
63
- def remove input
64
- data = []
65
- # parse the json list
66
- query = load_data
67
-
68
- # transform the data if needed
69
- query.each do |h|
70
- unless h[:id] == input[:id]
71
- data << h
72
- end
73
- end
74
-
75
- save_data data
76
-
77
- # return true on success
78
- true
79
- end
80
-
81
- def find input
82
- data = []
83
- query = load_data
84
-
85
- key = input.keys[0]
86
-
87
- query.each do |h|
88
- if input[key] == h[key]
89
- return h
90
- end
91
- end
92
-
93
- raise Exception.new 'no object found'
94
- end
95
- end
96
-
97
-
98
-
99
-
@@ -1,62 +0,0 @@
1
- require 'moped'
2
-
3
- # To get the mongo system to work you need to have a counters collection. The
4
- # code here will increment the seq field which we use to set the id. If you are
5
- # having problems, you probably need to create the collection and add entries
6
- # for each other collection you want to have an id sequence.
7
-
8
- class MongoPlug
9
- def initialize collection
10
- @collection = collection
11
- @session = MONGO_SESSION
12
- end
13
-
14
- def list
15
- result = @session[@collection].find.entries
16
- result.map! do |entry|
17
- clean_up entry
18
- end
19
-
20
- result
21
- end
22
-
23
- def get input
24
- result = symbolize_keys @session[@collection].find(:id => input[:id]).first
25
- clean_up result
26
- end
27
-
28
- def save input
29
- if input[:id] == -1
30
- id = @session[:counters].find(:_id => @collection).modify({ "$inc" => { seq: 1 } }, new:true)["seq"]
31
- input[:id] = id
32
- end
33
- result = @session[@collection].find(:id => input[:id]).modify(input, upsert: true, new: true)
34
- clean_up result
35
- end
36
-
37
- def remove input
38
- @session[@collection].find(:id => input[:id]).remove
39
- true
40
- end
41
-
42
- def clean_up input
43
- result = symbolize_keys input
44
- result.delete :_id
45
- result
46
- end
47
-
48
- def symbolize_keys hash
49
- hash.inject({}){|result, (key, value)|
50
- new_key = case key
51
- when String then key.to_sym
52
- else key
53
- end
54
- new_value = case value
55
- when Hash then symbolize_keys(value)
56
- else value
57
- end
58
- result[new_key] = new_value
59
- result
60
- }
61
- end
62
- end
@@ -1,38 +0,0 @@
1
- require 'sequel'
2
-
3
- # assume that DB is defined as a global constant elsewhere
4
-
5
- class MysqlPlug
6
-
7
- def initialize table
8
- @table = table
9
- end
10
-
11
- def save input
12
- table = DB[@table]
13
- input[:id] = nil if input[:id] == -1
14
-
15
- # this does an upsert
16
- result = table.on_duplicate_key_update.insert input
17
-
18
- input[:id] = result
19
- input
20
- end
21
-
22
- def list
23
- table = DB[@table]
24
- table.all
25
- end
26
-
27
- def get input
28
- table = DB[@table]
29
- table.first :id => input[:id]
30
- end
31
-
32
- def remove input
33
- table = DB[@table]
34
- result = table.where(:id => input[:id]).delete
35
- return true if result == 1
36
- false
37
- end
38
- end
@@ -1,94 +0,0 @@
1
- require 'json'
2
- require 'aws/s3'
3
-
4
- class S3Plug
5
- include AWS::S3
6
-
7
- def initialize input
8
- @filename = input[:filename]
9
- @bucket = input[:bucket]
10
-
11
- # you can test locally with the fake-s3 gem: https://github.com/jubos/fake-s3
12
- # or just swap out for the filesystem plug locally
13
- s3_key = ENV['S3_KEY'] || '123'
14
- s3_secret = ENV['S3_SECRET'] || 'abc'
15
- s3_server = ENV['S3_SERVER'] || '0.0.0.0'
16
- s3_port = ENV['S3_PORT'] || '10001'
17
-
18
- AWS::S3::Base.establish_connection!(:access_key_id => s3_key,
19
- :secret_access_key => s3_secret,
20
- :server => s3_server,
21
- :port => s3_port)
22
- end
23
-
24
- def load_data
25
- contents = S3Object.value @filename, @bucket
26
- JSON.parse contents, :symbolize_names => true
27
- end
28
-
29
- def save_data data
30
- json_data = JSON.pretty_generate data
31
- S3Object.store @filename, json_data, @bucket
32
- end
33
-
34
- def save input
35
- data = []
36
- result = load_data
37
- new_element = true if input[:id] == -1 # by convention set new element flag if id == -1
38
-
39
- max_id = -1
40
- # transform the data if needed
41
- result.each do |h|
42
- if input[:id] == h[:id]
43
- h = input
44
- end
45
- max_id = h[:id] if h[:id] > max_id
46
- data << h
47
- end
48
-
49
- # add data to the list if it's a new element
50
- if new_element
51
- input[:id] = max_id + 1
52
- data << input
53
- end
54
-
55
- save_data data
56
-
57
- # return the transformed data
58
- input
59
- end
60
-
61
- def list
62
- load_data
63
- end
64
-
65
- def get input
66
- data = []
67
- result = load_data
68
-
69
- # transform the data if needed
70
- result.each do |h|
71
- return h if h[:id] == input[:id]
72
- end
73
-
74
- {}
75
- end
76
-
77
- def remove input
78
- data = []
79
- result = load_data
80
-
81
- # transform the data if needed
82
- result.each do |h|
83
- unless h[:id] == input[:id]
84
- data << h
85
- end
86
- end
87
-
88
- save_data data
89
-
90
- # return true on success
91
- true
92
- end
93
- end
94
-
Binary file