resource_spec 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 41c01c8d22dd537442114ef20b0b4191620589ce
4
+ data.tar.gz: 08783f47f460b39eae770a759909a794b9de0cdd
5
+ SHA512:
6
+ metadata.gz: 3e5a976cb1342b0d0571ae1e773c2fd10eadd710506e871b43cfd79080a4dfe788e6a2b62f5c68c8fde603cbe4d3651277f09033cda1cefce6f6b1957ada80a4
7
+ data.tar.gz: 6bc8512c1a5be47b889b3dc1206ceb1fb3f572b4c7fcf3fcb9136d89ef859d548cf9939512ac7d8ad920ab96443a20b7b0ccca7f3ce90b80a04c72aedeec4495
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /spec/dummy/log
11
+ /spec/dummy/tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ Documentation:
2
+ Enabled: false
3
+
4
+ Style/StringLiterals:
5
+ EnforcedStyle: double_quotes
6
+
7
+ Style/ClassAndModuleChildren:
8
+ EnforcedStyle: compact
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in resource_spec.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # ResourceSpec
2
+
3
+ Test your RESTful Rails controllers with ease.
4
+
5
+ ### Motivation
6
+
7
+ In every rails app we have a set of controllers which incapsulates simple CRUD logic, especially in admin area. Most of such controllers stays uncovered: it often seems excessive to test typical things. In other hand, in such typical places there always exists some unusual logic, which had to be tested. Furthermore, 100% test coverage rocks.
8
+
9
+ ## Simple Use Case
10
+
11
+ Given we have [typical REST controller](spec/dummy/app/controllers/users_controller.rb).
12
+
13
+ It can be tested with a few lines of code:
14
+
15
+ ```ruby
16
+ include_context "ResourceSpec", User do
17
+ it_behaves_like "GET :new"
18
+ it_behaves_like "POST :create"
19
+ it_behaves_like "GET :edit"
20
+ it_behaves_like "PUT :update"
21
+ it_behaves_like "DELETE :destroy"
22
+ it_behaves_like "GET :index"
23
+ end
24
+ ```
25
+
26
+ `FactoryGirl` factory for `User` must be defined. Calls to `FactoryGirl` or other factory engine can be overriden with settings.
27
+
28
+ ## Customization
29
+
30
+ Take a look at [default settings](lib/resource_spec/context.rb). All of these settings can be changed inside `include_context` block.
31
+
32
+ Some examples:
33
+
34
+ ### Redirect to `#index` instead of `#show` on create
35
+
36
+ Define override context somewhere in `support` folder:
37
+
38
+ ```ruby
39
+ RSpec.shared_context "ResourceSpec overrides" do
40
+ let(:success_resource_url) { controller.url_for(action: :index) }
41
+ end
42
+ ```
43
+
44
+ Then include:
45
+
46
+ ```ruby
47
+ include_context "ResourceSpec", User do
48
+ include_context "ResourceSpec overrides"
49
+
50
+ ...
51
+ end
52
+ ```
53
+
54
+ ### Nesting
55
+
56
+ This will make nested resources like `/category/:category_id/groups` work:
57
+
58
+ ```ruby
59
+ let(:category) { create(:category) }
60
+
61
+ include_context "ResourceSpec", Group do
62
+ let(:url_args) { { category_id: category.id } }
63
+
64
+ ...
65
+ end
66
+ ```
67
+
68
+ ### Skipping passwords
69
+
70
+ `POST :create` and `PUT :update` examples are checking the record on compliance between params passed by request and record values saved to database. Some fields like images, generated tokens, encrypted passwords must be skipped.
71
+
72
+ ```ruby
73
+ include_context "ResourceSpec", User do
74
+ let(:not_expected_params) do
75
+ %i(password password_confirmation last_sign_in_at)
76
+ end
77
+
78
+ ...
79
+ end
80
+
81
+ ```
82
+
83
+ ### Timestamps
84
+
85
+ If you have any DateTime fields in your model - freeze the time:
86
+
87
+ ```ruby
88
+ around { |example| travel_to(Time.now, &example) }
89
+ ```
90
+
91
+ If you have Date columns - use `#to_date` in factory.
92
+
93
+ ## Installation
94
+
95
+ Add this line to your application's Gemfile:
96
+
97
+ ```ruby
98
+ gem "resource_spec"
99
+ ```
100
+
101
+ And this to `spec_helper.rb`:
102
+
103
+ ```ruby
104
+ require "resource_spec/all"
105
+ ```
106
+
107
+ And then execute:
108
+
109
+ $ bundle
110
+
111
+ Or install it yourself as:
112
+
113
+ $ gem install resource_spec
114
+
115
+ ## Development
116
+
117
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
118
+
119
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
120
+
121
+ ## Contributing
122
+
123
+ Bug reports and pull requests are welcome on GitHub at https://github.com/gzigzigzeo/resource_spec.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "resource_spec"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ require "resource_spec/context"
2
+ require "resource_spec/index"
3
+ require "resource_spec/new"
4
+ require "resource_spec/edit"
5
+ require "resource_spec/create"
6
+ require "resource_spec/update"
7
+ require "resource_spec/destroy"
@@ -0,0 +1,43 @@
1
+ RSpec.shared_context "ResourceSpec" do |model|
2
+ let(:model) { model }
3
+
4
+ let(:param_name) { model.model_name.param_key }
5
+ let(:primary_key_param_name) { :id }
6
+ let(:factory_name) { model }
7
+
8
+ let(:attributes) { FactoryGirl.attributes_for(factory_name).except(:id) }
9
+ let(:not_expected_params) { [] }
10
+ let(:params) { attributes }
11
+ let(:invalid_params) { Hash[params.keys.zip([""] * params.keys.size)] }
12
+ let(:params_to_expect) { params.except(*not_expected_params) }
13
+
14
+ let(:resource) { assigns[param_name] }
15
+ let(:instance) { FactoryGirl.create(factory_name) }
16
+
17
+ let(:collection) { assigns[param_name.to_s.pluralize.to_sym] }
18
+
19
+ let(:url_args) { {} }
20
+
21
+ let(:index_url_args) { {} }
22
+
23
+ let(:new_url_args) { url_args.merge(param_name => params) }
24
+
25
+ let(:success_resource_url) do
26
+ controller.url_for(action: :show, primary_key_param_name => resource.id)
27
+ end
28
+
29
+ let(:create_url_args) { new_url_args }
30
+ let(:invalid_create_url_args) { url_args.merge(param_name => invalid_params) }
31
+ let(:success_create_url) { success_resource_url }
32
+
33
+ let(:edit_url_args) { url_args.merge(primary_key_param_name => instance.id) }
34
+
35
+ let(:update_url_args) { edit_url_args.merge(new_url_args) }
36
+ let(:invalid_update_url_args) do
37
+ edit_url_args.merge(param_name => invalid_params)
38
+ end
39
+ let(:success_update_url) { success_resource_url }
40
+
41
+ let(:destroy_url_args) { edit_url_args }
42
+ let(:success_destroy_url) { controller.url_for(action: :index) }
43
+ end
@@ -0,0 +1,20 @@
1
+ RSpec.shared_examples "POST :create" do
2
+ describe "POST :create" do
3
+ it "301" do
4
+ post :create, create_url_args
5
+
6
+ expect(resource.errors).to be_blank, "Given params: #{create_url_args} failed with errors: #{resource.errors.full_messages}, "
7
+ expect(resource).to be_persisted
8
+ expect(resource.reload).to have_attributes(params_to_expect)
9
+
10
+ expect(response).to redirect_to(success_create_url)
11
+ end
12
+
13
+ it "422" do
14
+ post :create, invalid_create_url_args
15
+
16
+ expect(response).to be_success
17
+ expect(resource.errors).to be_present
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ RSpec.shared_examples "DELETE :destroy" do |**kwargs|
2
+ describe "DELETE :destroy" do
3
+ it "301" do
4
+ delete :destroy, destroy_url_args
5
+
6
+ expect(response).to redirect_to(success_destroy_url)
7
+
8
+ if kwargs[:paranoid]
9
+ expect(resource.deleted_at).to be_present
10
+ else
11
+ expect { resource.reload }.to raise_error(ActiveRecord::RecordNotFound)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ RSpec.shared_examples "GET :edit" do
2
+ describe "GET :edit" do
3
+ it "200" do
4
+ get :edit, edit_url_args
5
+
6
+ expect(response).to be_success
7
+ expect(resource).to eq(instance)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ RSpec.shared_examples "GET :index" do
2
+ let!(:expected_collection) { FactoryGirl.create_list(model, rand(3) + 1) }
3
+
4
+ describe "GET :index" do
5
+ it "200" do
6
+ get :index, index_url_args
7
+
8
+ expect(response).to be_success
9
+ expect(collection).to be_present, "let(:collection) is blank and must point to actual collection"
10
+ expect(collection.size).to eq(expected_collection.size)
11
+ expect(collection).to include(*expected_collection)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ RSpec.shared_examples "GET :new" do
2
+ describe "GET :new" do
3
+ it "200" do
4
+ get :new, new_url_args
5
+
6
+ expect(response).to be_success
7
+
8
+ expect(resource).to be_present, "let(:resource) must point to controller variable containing instance, assigns[#{param_name}] by default"
9
+ expect(resource).to be_new_record
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ RSpec.shared_examples "PUT :update" do
2
+ describe "PUT :update" do
3
+ it "301" do
4
+ put :update, update_url_args
5
+
6
+ expect(resource.errors).to be_blank, "Given params: #{create_url_args} failed with errors: #{resource.errors.full_messages}, "
7
+ expect(resource.reload).to have_attributes(params_to_expect)
8
+
9
+ expect(response).to redirect_to(success_update_url)
10
+ end
11
+
12
+ it "422" do
13
+ put :update, invalid_update_url_args
14
+
15
+ expect(response).to be_success
16
+ expect(resource.errors).to be_present
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module ResourceSpec
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,4 @@
1
+ require "resource_spec/version"
2
+
3
+ module ResourceSpec
4
+ end
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "resource_spec/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "resource_spec"
8
+ spec.version = ResourceSpec::VERSION
9
+ spec.authors = ["Victor Sokolov"]
10
+ spec.email = ["gzigzigzeo@evilmartians.com"]
11
+
12
+ spec.summary = %(RSpec shared examples for testing Rails REST controllers)
13
+ spec.description = %(RSpec shared examples for testing Rails REST controllers)
14
+ spec.homepage = "https://github.com/gzigzigzeo/resource_spec"
15
+
16
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
17
+ # delete this section to allow pushing this gem to any host.
18
+ if spec.respond_to?(:metadata)
19
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
20
+ else
21
+ fail(
22
+ "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ )
24
+ end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.10"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "rails"
34
+ spec.add_development_dependency "sqlite3"
35
+ spec.add_development_dependency "factory_girl"
36
+ spec.add_development_dependency "ffaker"
37
+ spec.add_development_dependency "responders", "~> 2.0"
38
+ spec.add_development_dependency "database_cleaner"
39
+ spec.add_dependency "rspec"
40
+ spec.add_dependency "rspec-rails"
41
+ end
metadata ADDED
@@ -0,0 +1,204 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resource_spec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Victor Sokolov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-11-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sqlite3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: factory_girl
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ffaker
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: responders
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: database_cleaner
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rspec-rails
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: RSpec shared examples for testing Rails REST controllers
154
+ email:
155
+ - gzigzigzeo@evilmartians.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".gitignore"
161
+ - ".rspec"
162
+ - ".rubocop.yml"
163
+ - ".travis.yml"
164
+ - Gemfile
165
+ - README.md
166
+ - Rakefile
167
+ - bin/console
168
+ - bin/setup
169
+ - lib/resource_spec.rb
170
+ - lib/resource_spec/all.rb
171
+ - lib/resource_spec/context.rb
172
+ - lib/resource_spec/create.rb
173
+ - lib/resource_spec/destroy.rb
174
+ - lib/resource_spec/edit.rb
175
+ - lib/resource_spec/index.rb
176
+ - lib/resource_spec/new.rb
177
+ - lib/resource_spec/update.rb
178
+ - lib/resource_spec/version.rb
179
+ - resource_spec.gemspec
180
+ homepage: https://github.com/gzigzigzeo/resource_spec
181
+ licenses: []
182
+ metadata:
183
+ allowed_push_host: https://rubygems.org
184
+ post_install_message:
185
+ rdoc_options: []
186
+ require_paths:
187
+ - lib
188
+ required_ruby_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ requirements: []
199
+ rubyforge_project:
200
+ rubygems_version: 2.4.8
201
+ signing_key:
202
+ specification_version: 4
203
+ summary: RSpec shared examples for testing Rails REST controllers
204
+ test_files: []