grape-starter 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 567acba57f6b5bbef50e10c04ef3ed959d1d877b
4
- data.tar.gz: 68dea7756db9323789392a89435adc899aab2c72
3
+ metadata.gz: ac704eaf32a74db38f046a62b8a949ccd89ef03c
4
+ data.tar.gz: f19c5ac175f20052670b27c09d9e9449e0f8e6c7
5
5
  SHA512:
6
- metadata.gz: 50e159bda1bd6411ca34f4ee63269fc6ae403e068e51b64926d29f50d5ba0badbc87d744d5fc1867ffd5fe46a894767d84523e3d6287f2a78a6de794dbbe26ba
7
- data.tar.gz: 1065e7cc75744049be7df78c5a2ec275a3786596e37cf6486301bdc3d94b8ff1a4736650bf407f254afc87dabe3d67920b491ed2adcf866e0510b1bf81fbc028
6
+ metadata.gz: bc576028aa7419e171a7da9ec02d36527e067a3afeae583547f795bb4fcd61cb3e2f9f27be1591c9e46c4d8b4f1b3bc71a59f43498098337b6d732ebccb52e42
7
+ data.tar.gz: '0950501ead93312c1ba389c5f33c675500b98fe3a35232b0ae8ab65d8b7efabe7dc5fcba8e233cd8a00d0e9c812262d4cb6b49d5fe5ab5762bf1441c386d3deb'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ### NEXT
2
2
 
3
+ ### 0.5.0
4
+
5
+ - simplyfies request specs, **breaking change**: takes route from spec description
6
+ - adds option to set prefix, defaults to api
7
+ - sets prefix after project name
8
+
3
9
  ### 0.4.2
4
10
 
5
11
  - sets prefix after project name
data/README.md CHANGED
@@ -91,6 +91,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/LeFnor
91
91
  The gem is available as open source under the terms of the [MIT License](LICENSE).
92
92
 
93
93
  ### ToDos
94
-
95
- - [x] make scripts more configurable
96
- - [ ] add logging
data/bin/grape-starter CHANGED
@@ -22,7 +22,11 @@ switch [:f, :force], negatable: false
22
22
  desc 'Creates initial api skeleton'
23
23
  arg_name 'awesome_api'
24
24
  command :new do |c|
25
- c.action do |global_options, _, args|
25
+ c.flag [:p, :prefix],
26
+ default_value: 'api',
27
+ desc: 'sets the prefix of the API (default: api, given: takes this)'
28
+
29
+ c.action do |global_options, options, args|
26
30
  dest = args.empty? ? nil : File.join(Dir.getwd, args.first)
27
31
 
28
32
  case
@@ -34,7 +38,7 @@ command :new do |c|
34
38
  starter_gem = Gem::Specification.find_by_name('grape-starter').gem_dir
35
39
  src = File.join(starter_gem, 'template', '.')
36
40
 
37
- Starter::Builder.new!(args.first, src, dest)
41
+ Starter::Builder.new!(args.first, src, dest, options[:p])
38
42
  $stdout.puts "created: #{args.first}"
39
43
 
40
44
  # after creating tasks
@@ -63,8 +67,7 @@ command :add do |c|
63
67
 
64
68
  begin
65
69
  builder_options = global_options.merge(set: set).merge(options)
66
- Starter::Builder.add!(resource, builder_options)
67
- created_files = Starter::Builder.save
70
+ created_files = Starter::Builder.add!(resource, builder_options)
68
71
 
69
72
  `bundle exec rubocop -a #{created_files.join(' ')}`
70
73
  $stdout.puts "added resource: #{resource}"
@@ -3,30 +3,39 @@ require 'active_support/core_ext/string'
3
3
 
4
4
  module Starter
5
5
  require 'starter/builder/names'
6
+ require 'starter/builder/base_file'
7
+ require 'starter/builder/file_foo'
6
8
  require 'starter/builder/template_files'
7
9
  require 'starter/builder/template_endpoints'
8
10
 
9
11
  class Builder
10
12
  extend Starter::Names
13
+ extend Starter::BaseFile
11
14
  extend Template::Files
12
15
  extend Template::Endpoints
13
16
 
14
17
  class << self
15
- attr_reader :resource, :set, :force, :entity, :destination
16
-
18
+ attr_reader :prefix, :resource, :set, :force, :entity, :destination
19
+ #
20
+ # public methods
21
+ #
22
+ #
17
23
  # would be called from new command
18
24
  #
19
25
  # name - A String as project name
20
26
  # source - A String which provides the template path
21
27
  # destination - A String which provides the new project path
22
- def new!(name, source, destination)
28
+ def new!(name, source, destination, prefix = 'api')
29
+ @prefix = prefix
23
30
  @resource = name
24
31
  @destination = destination
25
32
 
26
33
  FileUtils.copy_entry source, destination
27
34
 
28
35
  replace_static(File.join('script', 'server'), "API-#{resource}")
29
- replace_static(File.join('api', 'base.rb'), ":#{resource}")
36
+ replace_static(File.join('api', 'base.rb'), ":#{prefix}")
37
+ replace_static(File.join('spec', 'requests', 'root_spec.rb'), prefix)
38
+ replace_static(File.join('spec', 'requests', 'documentation_spec.rb'), prefix)
30
39
 
31
40
  self
32
41
  end
@@ -45,23 +54,10 @@ module Starter
45
54
  @force = options[:force]
46
55
  @entity = options[:entity]
47
56
 
48
- self
49
- end
50
-
51
- #
52
- # … it saves the files
53
- def save
54
- created_files = file_list.each_with_object([]) do |new_file, memo|
55
- memo << send("#{new_file}_name")
56
- save_file(new_file)
57
- end
58
-
59
- add_mount_point
60
-
61
- created_files
57
+ save_resource
62
58
  end
63
59
 
64
- # would be called on from command
60
+ # would be called on from rm command
65
61
  #
66
62
  # resource - A String, which indicates the resource to remove
67
63
  # options - A Hash to provide some optional arguments (default: {})
@@ -93,13 +89,17 @@ module Starter
93
89
 
94
90
  private
95
91
 
96
- # get content for and save new resource files
97
- def save_file(new_file)
98
- new_file_name = "#{new_file}_name"
99
- should_raise?(send(new_file_name))
100
- write_file(send(new_file_name), send(new_file.strip_heredoc))
92
+ # #new! project creation releated helper methods
93
+ #
94
+ # replace something in existend files
95
+ def replace_static(file, replacement)
96
+ server_file = File.join(destination, file)
97
+
98
+ FileFoo.call!(server_file) { |content| content.gsub!('{{{grape-starter}}}', replacement) }
101
99
  end
102
100
 
101
+ # #add! a new resource releated helper methods
102
+ #
103
103
  # provides an array of endpoints for the new resource
104
104
  def endpoint_set
105
105
  crud_set = singular? ? singular_one : crud
@@ -108,76 +108,46 @@ module Starter
108
108
  crud_set.each_with_object([]) { |x, memo| set.map { |y| memo << x if x.to_s.start_with?(y) } }
109
109
  end
110
110
 
111
- # provides a file list for the new resource
112
- def file_list
113
- standards = %w(api_file lib_file api_spec lib_spec)
111
+ #
112
+ # saves all resource related files the files
113
+ def save_resource
114
+ created_files = file_list.each_with_object([]) do |new_file, memo|
115
+ memo << send("#{new_file}_name")
116
+ save_file(new_file)
117
+ end
114
118
 
115
- entity ? standards + ['entity_file'] : standards
116
- end
119
+ add_mount_point
117
120
 
118
- # raises if resource exist and force false
119
- def should_raise?(file)
120
- raise StandardError, '… resource exists' if File.exist?(file) && !force
121
+ created_files
121
122
  end
122
123
 
123
- # replace something in exitend files
124
- #
125
- # will be called on project creation
126
124
  #
127
- # static files such as under script folder,
128
- def replace_static(file, replacement)
129
- server_file = File.join(destination, file)
130
-
131
- file_foo(server_file) { |content| content.gsub!('{{{grape-starter}}}', replacement) }
125
+ # saves new resource files
126
+ def save_file(new_file)
127
+ new_file_name = "#{new_file}_name"
128
+ should_raise?(send(new_file_name))
129
+ FileFoo.write_file(send(new_file_name), send(new_file.strip_heredoc))
132
130
  end
133
131
 
134
- # will be called an resource creation
135
132
  #
136
- # add it in api base
137
- def add_mount_point
138
- file_foo(api_base_file_name) { |content| add_to_base(content) }
139
- end
140
-
141
- # … adding
142
- def add_to_base(file)
143
- occurence = file.scan(/(\s+mount\s.*?\n)/).last.first
144
- replacement = occurence + mount_point
145
- file.sub!(occurence, replacement)
133
+ # raises if resource exist and force false
134
+ def should_raise?(file)
135
+ raise StandardError, '… resource exists' if File.exist?(file) && !force
146
136
  end
147
137
 
148
- # remove it in api base
149
- def remove_mount_point
150
- file_foo(api_base_file_name) { |content| remove_from_base(content) }
151
- end
138
+ # #add! and #remove! a new resource releated helper methods
139
+ #
140
+ # provides a file list for the new resource
141
+ def file_list
142
+ standards = %w(api_file lib_file api_spec lib_spec)
152
143
 
153
- # removing
154
- def remove_from_base(file)
155
- file.sub!(mount_point, '')
144
+ entity ? standards + ['entity_file'] : standards
156
145
  end
157
146
 
158
147
  # content of the given set of files,
159
148
  def content(set)
160
149
  set.map { |x| send(x) }
161
150
  end
162
-
163
- # general file stuff
164
- #
165
- # … reading and writing content
166
- def file_foo(file)
167
- content = read_file(file)
168
- yield content
169
- write_file(file, content)
170
- end
171
-
172
- # … read
173
- def read_file(file)
174
- File.read(file)
175
- end
176
-
177
- # … write
178
- def write_file(file, content)
179
- File.open(file, 'w') { |f| f.write(content) }
180
- end
181
151
  end
182
152
  end
183
153
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ module Starter
3
+ module BaseFile
4
+ # add it in api base
5
+ def add_mount_point
6
+ FileFoo.call!(api_base_file_name) { |content| add_to_base(content) }
7
+ end
8
+
9
+ # adding mount point to base class
10
+ def add_to_base(file)
11
+ occurence = file.scan(/(\s+mount\s.*?\n)/).last.first
12
+ replacement = occurence + mount_point
13
+ file.sub!(occurence, replacement)
14
+ end
15
+
16
+ # removes in api base
17
+ def remove_mount_point
18
+ FileFoo.call!(api_base_file_name) { |content| remove_from_base(content) }
19
+ end
20
+
21
+ # removes mount point form base class
22
+ def remove_from_base(file)
23
+ file.sub!(mount_point, '')
24
+ end
25
+
26
+ def base_prefix
27
+ base_file
28
+
29
+ base_file.scan(/prefix\s+(:.+)\n/).first.first.delete!(':')
30
+ end
31
+
32
+ def base_version
33
+ base_file
34
+
35
+ base_file.scan(/version\s+(.+),/).first.first.delete!("'")
36
+ end
37
+
38
+ def base_file
39
+ file = File.join(Dir.getwd, 'api', 'base.rb')
40
+ FileFoo.read_file(file)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ module Starter
3
+ class FileFoo
4
+ class << self
5
+ # general file stuff
6
+ #
7
+ # … reading and writing content
8
+ def call!(file)
9
+ content = read_file(file)
10
+ yield content
11
+ write_file(file, content)
12
+ end
13
+
14
+ # … read
15
+ def read_file(file)
16
+ File.read(file)
17
+ end
18
+
19
+ # … write
20
+ def write_file(file, content)
21
+ File.open(file, 'w') { |f| f.write(content) }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -74,34 +74,34 @@ module Starter
74
74
  # request specs shared examples
75
75
  #
76
76
  def post_spec
77
- "it_behaves_like 'POST', base_path: '/api/v1', resource: '#{resource}', params: {}"
77
+ "it_behaves_like 'POST', params: {}"
78
78
  end
79
79
 
80
80
  def get_all_spec
81
- "it_behaves_like 'GET all', base_path: '/api/v1', resource: '#{resource}'"
81
+ "it_behaves_like 'GET all'"
82
82
  end
83
83
 
84
84
  %w(get delete).each do |verb|
85
85
  define_method(:"#{verb}_one_spec") do
86
- "it_behaves_like '#{verb.upcase} one', base_path: '/api/v1', resource: '#{resource}'"
86
+ "it_behaves_like '#{verb.upcase} one'"
87
87
  end
88
88
  end
89
89
 
90
90
  %w(put patch).each do |verb|
91
91
  define_method(:"#{verb}_one_spec") do
92
- "it_behaves_like '#{verb.upcase} one', base_path: '/api/v1', resource: '#{resource}', params: {}"
92
+ "it_behaves_like '#{verb.upcase} one', params: {}"
93
93
  end
94
94
  end
95
95
 
96
96
  %w(get delete).each do |verb|
97
97
  define_method(:"#{verb}_specific_spec") do
98
- "it_behaves_like '#{verb.upcase} specific', base_path: '/api/v1', resource: '#{resource}', key: 1"
98
+ "it_behaves_like '#{verb.upcase} specific', key: 1"
99
99
  end
100
100
  end
101
101
 
102
102
  %w(put patch).each do |verb|
103
103
  define_method(:"#{verb}_specific_spec") do
104
- "it_behaves_like '#{verb.upcase} specific', base_path: '/api/v1', resource: '#{resource}', key: 1, params: {}"
104
+ "it_behaves_like '#{verb.upcase} specific', key: 1, params: {}"
105
105
  end
106
106
  end
107
107
  end
@@ -51,7 +51,7 @@ module Starter
51
51
  # frozen_string_literal: true
52
52
  require 'spec_helper'
53
53
 
54
- RSpec.describe Api::#{klass_name} do
54
+ RSpec.describe '/#{base_prefix}/#{base_version}/#{resource}' do
55
55
  #{endpoint_specs}
56
56
  end
57
57
  FILE
@@ -1,13 +1,18 @@
1
1
  # frozen_string_literal: true
2
- RSpec.shared_examples 'POST' do |base_path: '/api/v1', resource: '', params: {}|
3
- let(:route) { "#{base_path}/#{resource}" }
2
+
3
+ def route_from_description
4
+ RSpec.current_example.metadata[:example_group][:parent_example_group][:description_args].first
5
+ end
6
+
7
+ RSpec.shared_examples 'POST' do |params: {}|
8
+ let(:route) { route_from_description }
4
9
 
5
10
  subject { post route, params }
6
11
  specify { expect(subject.status).to eql 201 }
7
12
  end
8
13
 
9
- RSpec.shared_examples 'GET all' do |base_path: '/api/v1', resource: ''|
10
- let(:route) { "#{base_path}/#{resource}" }
14
+ RSpec.shared_examples 'GET all' do
15
+ let(:route) { route_from_description }
11
16
 
12
17
  subject { get route }
13
18
  specify { expect(subject.status).to eql 200 }
@@ -15,29 +20,29 @@ end
15
20
 
16
21
  # singular forms
17
22
  #
18
- RSpec.shared_examples 'GET one' do |base_path: '/api/v1', resource: ''|
19
- let(:route) { "#{base_path}/#{resource}" }
23
+ RSpec.shared_examples 'GET one' do
24
+ let(:route) { route_from_description }
20
25
 
21
26
  subject { get route }
22
27
  specify { expect(subject.status).to eql 200 }
23
28
  end
24
29
 
25
- RSpec.shared_examples 'PUT one' do |base_path: '/api/v1', resource: '', params: {}|
26
- let(:route) { "#{base_path}/#{resource}" }
30
+ RSpec.shared_examples 'PUT one' do |params: {}|
31
+ let(:route) { route_from_description }
27
32
 
28
33
  subject { put route, params }
29
34
  specify { expect(subject.status).to eql 200 }
30
35
  end
31
36
 
32
- RSpec.shared_examples 'PATCH one' do |base_path: '/api/v1', resource: '', params: {}|
33
- let(:route) { "#{base_path}/#{resource}" }
37
+ RSpec.shared_examples 'PATCH one' do |params: {}|
38
+ let(:route) { route_from_description }
34
39
 
35
40
  subject { patch route, params }
36
41
  specify { expect(subject.status).to eql 200 }
37
42
  end
38
43
 
39
- RSpec.shared_examples 'DELETE one' do |base_path: '/api/v1', resource: ''|
40
- let(:route) { "#{base_path}/#{resource}" }
44
+ RSpec.shared_examples 'DELETE one' do
45
+ let(:route) { route_from_description }
41
46
 
42
47
  subject { delete route }
43
48
  specify { expect(subject.status).to eql 204 }
@@ -45,32 +50,32 @@ end
45
50
 
46
51
  # plural forms
47
52
  #
48
- RSpec.shared_examples 'GET specific' do |base_path: '/api/v1', resource: '', key: nil|
49
- let(:route) { "#{base_path}/#{resource}" }
53
+ RSpec.shared_examples 'GET specific' do |key: nil|
54
+ let(:route) { route_from_description }
50
55
  let(:specific_route) { "#{route}/#{key}" }
51
56
 
52
57
  subject { get specific_route }
53
58
  specify { expect(subject.status).to eql 200 }
54
59
  end
55
60
 
56
- RSpec.shared_examples 'PUT specific' do |base_path: '/api/v1', resource: '', key: nil, params: {}|
57
- let(:route) { "#{base_path}/#{resource}" }
61
+ RSpec.shared_examples 'PUT specific' do |key: nil, params: {}|
62
+ let(:route) { route_from_description }
58
63
  let(:specific_route) { "#{route}/#{key}" }
59
64
 
60
65
  subject { put specific_route, params }
61
66
  specify { expect(subject.status).to eql 200 }
62
67
  end
63
68
 
64
- RSpec.shared_examples 'PATCH specific' do |base_path: '/api/v1', resource: '', key: nil, params: {}|
65
- let(:route) { "#{base_path}/#{resource}" }
69
+ RSpec.shared_examples 'PATCH specific' do |key: nil, params: {}|
70
+ let(:route) { route_from_description }
66
71
  let(:specific_route) { "#{route}/#{key}" }
67
72
 
68
73
  subject { patch specific_route, params }
69
74
  specify { expect(subject.status).to eql 200 }
70
75
  end
71
76
 
72
- RSpec.shared_examples 'DELETE specific' do |base_path: '/api/v1', resource: '', key: nil|
73
- let(:route) { "#{base_path}/#{resource}" }
77
+ RSpec.shared_examples 'DELETE specific' do |key: nil|
78
+ let(:route) { route_from_description }
74
79
  let(:specific_route) { "#{route}/#{key}" }
75
80
 
76
81
  subject { delete specific_route }
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Starter
3
- VERSION = '0.4.2'
3
+ VERSION = '0.5.0'
4
4
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
  require 'spec_helper'
3
3
 
4
- RSpec.describe Api::Base do
4
+ RSpec.describe '/{{{grape-starter}}}/v1/oapi' do
5
5
  subject(:swagger) do
6
- get '/api/v1/oapi'
6
+ get RSpec.current_example.metadata[:example_group][:full_description]
7
7
  last_response
8
8
  end
9
9
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require 'spec_helper'
3
3
 
4
- RSpec.describe Api::Base do
4
+ RSpec.describe '/{{{grape-starter}}}/v1/root' do
5
5
  let(:exposed_keys) do
6
6
  [
7
7
  :verb,
@@ -10,7 +10,7 @@ RSpec.describe Api::Base do
10
10
  ]
11
11
  end
12
12
 
13
- subject { get '/api/v1/root' }
13
+ subject { get RSpec.current_example.metadata[:example_group][:full_description] }
14
14
  specify { expect(subject.status).to eql 200 }
15
15
 
16
16
  let(:response) { JSON.parse(subject.body, symbolize_names: true) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-starter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - LeFnord
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-28 00:00:00.000000000 Z
11
+ date: 2016-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gli
@@ -160,6 +160,8 @@ files:
160
160
  - grape-starter.gemspec
161
161
  - lib/starter.rb
162
162
  - lib/starter/builder.rb
163
+ - lib/starter/builder/base_file.rb
164
+ - lib/starter/builder/file_foo.rb
163
165
  - lib/starter/builder/names.rb
164
166
  - lib/starter/builder/template_endpoints.rb
165
167
  - lib/starter/builder/template_files.rb