suit 0.1.0
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/.DS_Store +0 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +40 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +53 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/.DS_Store +0 -0
- data/lib/controllers/matchers.rb +19 -0
- data/lib/controllers/matchers/.DS_Store +0 -0
- data/lib/controllers/matchers/login_matcher.rb +50 -0
- data/lib/controllers/matchers/role_matcher.rb +72 -0
- data/lib/models/matchers.rb +53 -0
- data/lib/models/matchers/nested_attribute_matcher.rb +33 -0
- data/lib/models/matchers/sanitize_matcher.rb +59 -0
- data/lib/models/matchers/scope_active_matchers.rb +43 -0
- data/lib/models/matchers/scope_creator_matchers.rb +65 -0
- data/lib/models/matchers/scope_is_public_matchers.rb +43 -0
- data/lib/models/matchers/scope_ordinal_matchers.rb +47 -0
- data/lib/models/matchers/scope_sorting_matchers.rb +95 -0
- data/lib/models/matchers/scope_time_matchers.rb +59 -0
- data/lib/models/matchers/suit_matcher_base.rb +17 -0
- data/lib/suit.rb +19 -0
- data/lib/suit_factories.rb +45 -0
- data/spec/controllers/matchers/login_matcher_spec.rb +9 -0
- data/spec/spec_helper.rb +12 -0
- data/suit.gemspec +86 -0
- metadata +202 -0
data/.DS_Store
ADDED
|
Binary file
|
data/.document
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/Gemfile
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
source "http://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gem "activesupport", ">= 2.3.5"
|
|
4
|
+
gem "rspec", "~> 2.8.0"
|
|
5
|
+
gem "factory_girl", ">= 1.3.0"
|
|
6
|
+
|
|
7
|
+
# Add dependencies to develop your gem here.
|
|
8
|
+
# Include everything needed to run rake, tests, features, etc.
|
|
9
|
+
group :development do
|
|
10
|
+
gem "rdoc", "~> 3.12"
|
|
11
|
+
gem "bundler", "~> 1.0.0"
|
|
12
|
+
gem "jeweler", "~> 1.8.3"
|
|
13
|
+
gem "rcov", ">= 0"
|
|
14
|
+
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: http://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
activesupport (3.1.3)
|
|
5
|
+
multi_json (~> 1.0)
|
|
6
|
+
diff-lcs (1.1.3)
|
|
7
|
+
factory_girl (2.3.2)
|
|
8
|
+
activesupport
|
|
9
|
+
git (1.2.5)
|
|
10
|
+
jeweler (1.8.3)
|
|
11
|
+
bundler (~> 1.0)
|
|
12
|
+
git (>= 1.2.5)
|
|
13
|
+
rake
|
|
14
|
+
rdoc
|
|
15
|
+
json (1.6.5)
|
|
16
|
+
multi_json (1.0.4)
|
|
17
|
+
rake (0.9.2.2)
|
|
18
|
+
rcov (1.0.0)
|
|
19
|
+
rdoc (3.12)
|
|
20
|
+
json (~> 1.4)
|
|
21
|
+
rspec (2.8.0)
|
|
22
|
+
rspec-core (~> 2.8.0)
|
|
23
|
+
rspec-expectations (~> 2.8.0)
|
|
24
|
+
rspec-mocks (~> 2.8.0)
|
|
25
|
+
rspec-core (2.8.0)
|
|
26
|
+
rspec-expectations (2.8.0)
|
|
27
|
+
diff-lcs (~> 1.1.2)
|
|
28
|
+
rspec-mocks (2.8.0)
|
|
29
|
+
|
|
30
|
+
PLATFORMS
|
|
31
|
+
ruby
|
|
32
|
+
|
|
33
|
+
DEPENDENCIES
|
|
34
|
+
activesupport (>= 2.3.5)
|
|
35
|
+
bundler (~> 1.0.0)
|
|
36
|
+
factory_girl (>= 1.3.0)
|
|
37
|
+
jeweler (~> 1.8.3)
|
|
38
|
+
rcov
|
|
39
|
+
rdoc (~> 3.12)
|
|
40
|
+
rspec (~> 2.8.0)
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2012 Justin Ball
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
= suit
|
|
2
|
+
|
|
3
|
+
A set of rspec scope matchers.
|
|
4
|
+
|
|
5
|
+
== Matchers for common controller methods:
|
|
6
|
+
|
|
7
|
+
describe UsersController, "on GET to show with a valid id" do
|
|
8
|
+
|
|
9
|
+
it { should require_login :index, :get }
|
|
10
|
+
it { should require_role('admin', :index, :get) }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
== Matchers for common active record scopes:
|
|
15
|
+
|
|
16
|
+
scope :by_title, order("title ASC")
|
|
17
|
+
scope :by_name, order("name ASC")
|
|
18
|
+
scope :by_newest, order("created_at DESC")
|
|
19
|
+
scope :by_oldest, order("created_at ASC")
|
|
20
|
+
scope :by_latest, order("updated_at DESC")
|
|
21
|
+
scope :newer_than, lambda { |*args| where("created_at > ?", args.first || DateTime.now) }
|
|
22
|
+
scope :older_than, lambda { |*args| where("created_at < ?", args.first || 1.day.ago.to_s(:db)) }
|
|
23
|
+
scope :is_public, where(["is_public = ?", true])
|
|
24
|
+
scope :created_by, lambda { |creator| where("creator_id = ? AND creator_type = ?", creator.id, creator.class.to_s) } }
|
|
25
|
+
scope :sorted, order("sort ASC")
|
|
26
|
+
scope :sorted_id, order("id ASC")
|
|
27
|
+
|
|
28
|
+
These matchers will test common scopes used in active record models:
|
|
29
|
+
|
|
30
|
+
describe User do
|
|
31
|
+
it { should scope_by_title }
|
|
32
|
+
it { should scope_by_name }
|
|
33
|
+
it { should scope_by_latest }
|
|
34
|
+
it { should scope_by_newest }
|
|
35
|
+
it { should scope_by_oldest }
|
|
36
|
+
|
|
37
|
+
it { should scope_newer_than }
|
|
38
|
+
it { should scope_older_than }
|
|
39
|
+
|
|
40
|
+
it { should scope_is_public }
|
|
41
|
+
|
|
42
|
+
it { should scope_created_by }
|
|
43
|
+
|
|
44
|
+
it { should sanitize :title }
|
|
45
|
+
it { should scope_sorted }
|
|
46
|
+
it { should scope_sorted_id }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
== Copyright
|
|
50
|
+
|
|
51
|
+
Copyright (c) 2012 Tatemae.com. See LICENSE.txt for
|
|
52
|
+
further details.
|
|
53
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'bundler'
|
|
5
|
+
begin
|
|
6
|
+
Bundler.setup(:default, :development)
|
|
7
|
+
rescue Bundler::BundlerError => e
|
|
8
|
+
$stderr.puts e.message
|
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
|
10
|
+
exit e.status_code
|
|
11
|
+
end
|
|
12
|
+
require 'rake'
|
|
13
|
+
|
|
14
|
+
require 'jeweler'
|
|
15
|
+
Jeweler::Tasks.new do |gem|
|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
|
17
|
+
gem.name = "suit"
|
|
18
|
+
gem.homepage = "http://github.com/tatemae/suit"
|
|
19
|
+
gem.license = "MIT"
|
|
20
|
+
gem.summary = "common rspec matchers"
|
|
21
|
+
gem.description = %Q{A collection of commonly used rspec matchers}
|
|
22
|
+
gem.email = "justinball@gmail.com"
|
|
23
|
+
gem.authors = ["Justin Ball"]
|
|
24
|
+
# dependencies defined in Gemfile
|
|
25
|
+
end
|
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
|
27
|
+
|
|
28
|
+
require 'rspec/core'
|
|
29
|
+
require 'rspec/core/rake_task'
|
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
|
36
|
+
spec.rcov = true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
task :default => :spec
|
|
40
|
+
|
|
41
|
+
require 'rdoc/task'
|
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
|
44
|
+
|
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
46
|
+
rdoc.title = "suit #{version}"
|
|
47
|
+
rdoc.rdoc_files.include('README*')
|
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
49
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
data/lib/.DS_Store
ADDED
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__) unless $LOAD_PATH.include?(File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
require 'matchers/login_matcher'
|
|
4
|
+
require 'matchers/role_matcher'
|
|
5
|
+
|
|
6
|
+
module Suit # :nodoc:
|
|
7
|
+
module Controllers # :nodoc:
|
|
8
|
+
# = Matchers for common controller methods:
|
|
9
|
+
#
|
|
10
|
+
# describe UsersController, "on GET to show with a valid id" do
|
|
11
|
+
#
|
|
12
|
+
# it { should require_login :index, :get }
|
|
13
|
+
# it { should require_role('admin', :index, :get) }
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
module Matchers
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
Binary file
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Controllers # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# Ensure a login is required for the given action
|
|
6
|
+
# Parameters:
|
|
7
|
+
# action - Name of the action in the control that should require a login ie "index"
|
|
8
|
+
# verb - Method to use to call the action ie :post, :get
|
|
9
|
+
# login_url - Optional url the user should be redirected to if they aren't logged in. Defaults to '/login'
|
|
10
|
+
#
|
|
11
|
+
# Example:
|
|
12
|
+
# it { should require_login 'index', :get, '/signup' }
|
|
13
|
+
def require_login(action, verb, login_url = '/login')
|
|
14
|
+
RequireLoginMatcher.new(action, verb, login_url, self)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class RequireLoginMatcher
|
|
18
|
+
|
|
19
|
+
def initialize(action, verb, login_url, context)
|
|
20
|
+
@action = action
|
|
21
|
+
@verb = verb
|
|
22
|
+
@login_url = login_url
|
|
23
|
+
@context = context
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def matches?(controller)
|
|
27
|
+
@controller = controller
|
|
28
|
+
requires_login?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def failure_message
|
|
32
|
+
"Expected a #{@action} to #{@action} to require login"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def description
|
|
36
|
+
"require login #{@action}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def requires_login?
|
|
42
|
+
response = @context.send(@verb, @action, :id => 1)
|
|
43
|
+
@context.send(:assert_redirected_to, @login_url)
|
|
44
|
+
true
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Controllers # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# Ensure a role is required for the given action
|
|
6
|
+
# Parameters:
|
|
7
|
+
# role - Role require to access the url.
|
|
8
|
+
# action - Name of the action in the control that should require a role ie "index"
|
|
9
|
+
# verb - Method to use to call the action ie :post, :get
|
|
10
|
+
# flash_message - Flash message indicating that the user was denied access
|
|
11
|
+
# role_url - Optional url the user should be redirected to if they aren't logged in. Defaults to '/role'
|
|
12
|
+
#
|
|
13
|
+
# Example:
|
|
14
|
+
# it { should require_role 'index', :get, /access denied/i, '/signup' }
|
|
15
|
+
def require_role(role, action, verb, flash_message = /permission/i, role_url = '/login')
|
|
16
|
+
RequireRoleMatcher.new(role, action, verb, role_url, flash_message, self)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class RequireRoleMatcher
|
|
20
|
+
|
|
21
|
+
def initialize(role, action, verb, role_url, flash_message, context)
|
|
22
|
+
@role = role
|
|
23
|
+
@action = action
|
|
24
|
+
@verb = verb
|
|
25
|
+
@role_url = role_url
|
|
26
|
+
@context = context
|
|
27
|
+
@flash_message = flash_message
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def matches?(controller)
|
|
31
|
+
@controller = controller
|
|
32
|
+
requires_role?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def failure_message
|
|
36
|
+
"Expected a '#{@action}' to '#{@action}' to require role '#{@role}'"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def description
|
|
40
|
+
"require role #{@action}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def requires_role?
|
|
46
|
+
response = @context.send(@verb, @action, :id => 1)
|
|
47
|
+
@context.send(:assert_redirected_to, @role_url)
|
|
48
|
+
if flash.values.any? {|value| value =~ @flash_message }
|
|
49
|
+
true
|
|
50
|
+
else
|
|
51
|
+
false
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def flash
|
|
56
|
+
return @flash if @flash
|
|
57
|
+
flash_and_now = @controller.request.session["flash"].dup if @controller.request.session["flash"]
|
|
58
|
+
flash = @controller.send(:flash)
|
|
59
|
+
|
|
60
|
+
@flash = if @now
|
|
61
|
+
flash.keys.each {|key| flash_and_now.delete(key) }
|
|
62
|
+
flash_and_now
|
|
63
|
+
else
|
|
64
|
+
flash
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__) unless $LOAD_PATH.include?(File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
require 'matchers/suit_matcher_base'
|
|
4
|
+
require 'matchers/scope_creator_matchers'
|
|
5
|
+
require 'matchers/scope_is_public_matchers'
|
|
6
|
+
require 'matchers/scope_ordinal_matchers'
|
|
7
|
+
require 'matchers/scope_sorting_matchers'
|
|
8
|
+
require 'matchers/scope_time_matchers'
|
|
9
|
+
require 'matchers/scope_active_matchers'
|
|
10
|
+
require 'matchers/nested_attribute_matcher'
|
|
11
|
+
require 'matchers/sanitize_matcher'
|
|
12
|
+
|
|
13
|
+
module Suit # :nodoc:
|
|
14
|
+
module Models # :nodoc:
|
|
15
|
+
# = Matchers for common active record scopes:
|
|
16
|
+
#
|
|
17
|
+
# scope :by_title, order("title ASC")
|
|
18
|
+
# scope :by_name, order("name ASC")
|
|
19
|
+
# scope :by_newest, order("created_at DESC")
|
|
20
|
+
# scope :by_oldest, order("created_at ASC")
|
|
21
|
+
# scope :by_latest, order("updated_at DESC")
|
|
22
|
+
# scope :newer_than, lambda { |*args| where("created_at > ?", args.first || DateTime.now) }
|
|
23
|
+
# scope :older_than, lambda { |*args| where("created_at < ?", args.first || 1.day.ago.to_s(:db)) }
|
|
24
|
+
# scope :is_public, where(["is_public = ?", true])
|
|
25
|
+
# scope :created_by, lambda { |creator| where("creator_id = ? AND creator_type = ?", creator.id, creator.class.to_s) } }
|
|
26
|
+
# scope :sorted, order("sort ASC")
|
|
27
|
+
# scope :sorted_id, order("id ASC")
|
|
28
|
+
#
|
|
29
|
+
# These matchers will test common scopes used in active record models:
|
|
30
|
+
#
|
|
31
|
+
# describe User do
|
|
32
|
+
# it { should scope_by_title }
|
|
33
|
+
# it { should scope_by_name }
|
|
34
|
+
# it { should scope_by_latest }
|
|
35
|
+
# it { should scope_by_newest }
|
|
36
|
+
# it { should scope_by_oldest }
|
|
37
|
+
|
|
38
|
+
# it { should scope_newer_than }
|
|
39
|
+
# it { should scope_older_than }
|
|
40
|
+
|
|
41
|
+
# it { should scope_is_public }
|
|
42
|
+
|
|
43
|
+
# it { should scope_created_by }
|
|
44
|
+
|
|
45
|
+
# it { should sanitize :title }
|
|
46
|
+
# it { should scope_sorted }
|
|
47
|
+
# it { should scope_sorted_id }
|
|
48
|
+
# end
|
|
49
|
+
|
|
50
|
+
module Matchers
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Models # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# Ensures that the model can accept nested attributes for the given model
|
|
6
|
+
def accept_nested_attributes_for(nested_model)
|
|
7
|
+
NestedAttributeMatcher.new(nested_model)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class NestedAttributeMatcher < SuitMatcherBase # :nodoc:
|
|
11
|
+
|
|
12
|
+
def initialize(nested_model)
|
|
13
|
+
@nested_model = nested_model
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def matches?(subject)
|
|
17
|
+
@subject = subject
|
|
18
|
+
@subject.methods.include?("#{@nested_model}_attributes=")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def failure_message
|
|
22
|
+
"#{factory_name} does not accept nested attributes for #{@nested_model}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def description
|
|
26
|
+
"accepts nested attributes for"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Models # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# Ensures that the model sanitizes the given attributes
|
|
6
|
+
def sanitize(attribute)
|
|
7
|
+
SanitizeMatcher.new(attribute)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class SanitizeMatcher < SuitMatcherBase # :nodoc:
|
|
11
|
+
|
|
12
|
+
def initialize(attribute)
|
|
13
|
+
@attribute = attribute
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def matches?(subject)
|
|
17
|
+
@subject = subject
|
|
18
|
+
sanitizes?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def failure_message
|
|
22
|
+
"#{factory_name} does not correctly sanitize the attribute #{@attribute}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def description
|
|
26
|
+
"sanitizes attribute"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def sanitizes?
|
|
32
|
+
bad_scripts = [
|
|
33
|
+
%|';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>|,
|
|
34
|
+
%|'';!--"<XSS>=&{()}|,
|
|
35
|
+
%|<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>|,
|
|
36
|
+
%|<IMG SRC="javascript:alert('XSS');">|,
|
|
37
|
+
%|<IMG SRC=javascript:alert('XSS')>|,
|
|
38
|
+
%|<IMG SRC=JaVaScRiPt:alert('XSS')>|,
|
|
39
|
+
%|<IMG SRC=JaVaScRiPt:alert('XSS')>|,
|
|
40
|
+
%|<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>|,
|
|
41
|
+
%|<IMG """><SCRIPT>alert("XSS")</SCRIPT>">|,
|
|
42
|
+
%|<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>|,
|
|
43
|
+
%|<A HREF="h
|
|
44
|
+
tt p://6	6.000146.0x7.147/">XSS</A>|,
|
|
45
|
+
%|<script>alert('message');</script>| ]
|
|
46
|
+
bad_scripts.each do |bad_value|
|
|
47
|
+
@subject.send("#{@attribute}=", bad_value)
|
|
48
|
+
@subject.save
|
|
49
|
+
clean_value = @subject.send(@attribute)
|
|
50
|
+
return false if clean_value.include?(bad_value)
|
|
51
|
+
end
|
|
52
|
+
true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Models # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# 'active' named scope which indicates whether an item is active or not
|
|
6
|
+
# requires that the class have a factory
|
|
7
|
+
# Tests:
|
|
8
|
+
# scope :newer_than, lambda { |time| {:conditions => ["created_at < ?", time || 1.day.ago] } }
|
|
9
|
+
# Examples:
|
|
10
|
+
# it { should scope_active }
|
|
11
|
+
def scope_active
|
|
12
|
+
ActiveMatcher.new(:active)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class ActiveMatcher < SuitMatcherBase # :nodoc:
|
|
16
|
+
|
|
17
|
+
def initialize(scope, field = :active)
|
|
18
|
+
@scope = scope
|
|
19
|
+
@field = field
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def matches?(subject)
|
|
23
|
+
@subject = subject
|
|
24
|
+
@subject.class.delete_all
|
|
25
|
+
active_item = Factory(factory_name, @field => true)
|
|
26
|
+
not_active_item = Factory(factory_name, @field => false)
|
|
27
|
+
@subject.class.send(@scope).include?(active_item) &&
|
|
28
|
+
!@subject.class.send(@scope).include?(not_active_item)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def failure_message
|
|
32
|
+
"Expected #{factory_name} to scope by #{@scope} on #{@field} and only find active items. But the call failed"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def description
|
|
36
|
+
"active items"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Models # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# Ensures that the model can scope by 'source'
|
|
6
|
+
# requires that the class have a factory and that a user factory exist
|
|
7
|
+
# Tests:
|
|
8
|
+
# scope :created_by, lambda { |item_object| {:conditions => ["items.source_id = ? AND items.source_type = ?", item_object.id, item_object.class.to_s] } }
|
|
9
|
+
# Examples:
|
|
10
|
+
# it { should scope_created_by }
|
|
11
|
+
def scope_source
|
|
12
|
+
CreatedByMatcher.new(:source, :source)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Ensures that the model can scope by created_by
|
|
16
|
+
# requires that the class have a factory and that a user factory exist
|
|
17
|
+
# Tests:
|
|
18
|
+
# scope :created_by, lambda { |user| where(['user_id = ?', user.id]) } }
|
|
19
|
+
# Examples:
|
|
20
|
+
# it { should scope_created_by }
|
|
21
|
+
def scope_created_by
|
|
22
|
+
CreatedByMatcher.new(:created_by, :user)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Ensures that the model can scope by created_by
|
|
26
|
+
# requires that the class have a factory and that a user factory exist
|
|
27
|
+
# Tests:
|
|
28
|
+
# scope :by_creator, lambda { |creator| where(['creator_id = ?', creator.id]) } }
|
|
29
|
+
# Examples:
|
|
30
|
+
# it { should scope_by_creator }
|
|
31
|
+
def scope_by_creator
|
|
32
|
+
CreatedByMatcher.new(:by_creator, :creator)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class CreatedByMatcher < SuitMatcherBase # :nodoc:
|
|
36
|
+
|
|
37
|
+
def initialize(scope, field)
|
|
38
|
+
@scope = scope
|
|
39
|
+
@field = field
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def matches?(subject)
|
|
43
|
+
@subject = subject
|
|
44
|
+
@subject.class.delete_all
|
|
45
|
+
@user = Factory(:user)
|
|
46
|
+
@user1 = Factory(:user)
|
|
47
|
+
@item = Factory(factory_name, @field => @user)
|
|
48
|
+
@item1 = Factory(factory_name, @field => @user1)
|
|
49
|
+
items = @subject.class.send(@scope, @user)
|
|
50
|
+
items.include?(@item) && !items.include?(@item1)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def failure_message
|
|
54
|
+
"Expected #{factory_name} to have scope created_by and to be able to successfully find #{@subject}'s creator"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def description
|
|
58
|
+
"scope created_by"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Models # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# 'is_public' named scope which retrieves items that are marked public
|
|
6
|
+
# requires that the class have a factory
|
|
7
|
+
# Tests:
|
|
8
|
+
# scope :newer_than, lambda { |time| {:conditions => ["created_at < ?", time || 1.day.ago] } }
|
|
9
|
+
# Examples:
|
|
10
|
+
# it { should scope_is_public }
|
|
11
|
+
def scope_is_public
|
|
12
|
+
IsPublicMatcher.new(:is_public)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class IsPublicMatcher < SuitMatcherBase # :nodoc:
|
|
16
|
+
|
|
17
|
+
def initialize(scope, field = :is_public)
|
|
18
|
+
@scope = scope
|
|
19
|
+
@field = field
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def matches?(subject)
|
|
23
|
+
@subject = subject
|
|
24
|
+
@subject.class.delete_all
|
|
25
|
+
public_item = Factory(factory_name, @field => true)
|
|
26
|
+
not_public_item = Factory(factory_name, @field => false)
|
|
27
|
+
@subject.class.send(@scope).include?(public_item) &&
|
|
28
|
+
!@subject.class.send(@scope).include?(not_public_item)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def failure_message
|
|
32
|
+
"Expected #{factory_name} to scope by #{@scope} on #{@field} and only find public items. But the call failed"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def description
|
|
36
|
+
"public items"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Models # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# Ensures that the model can sort by 'sorted'
|
|
6
|
+
# requires that the class have a factory
|
|
7
|
+
# Tests:
|
|
8
|
+
# scope :sorted, order("sort ASC")
|
|
9
|
+
# Examples:
|
|
10
|
+
# it { should scope_sorted }
|
|
11
|
+
def scope_sorted
|
|
12
|
+
OrdinalMatcher.new(:sorted, :sort)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# it { should scope_sorted_id }
|
|
16
|
+
def scope_sorted_id
|
|
17
|
+
OrdinalMatcher.new(:sorted_id, :sort)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class OrdinalMatcher < SuitMatcherBase # :nodoc:
|
|
21
|
+
|
|
22
|
+
def initialize(scope, field)
|
|
23
|
+
@scope = scope
|
|
24
|
+
@field = field
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def matches?(subject)
|
|
28
|
+
@subject = subject
|
|
29
|
+
@subject.class.delete_all
|
|
30
|
+
@first = Factory(factory_name, @field => 1)
|
|
31
|
+
@second = Factory(factory_name, @field => 2)
|
|
32
|
+
@first == @subject.class.send(@scope)[0] && @second == @subject.class.send(@scope)[1]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def failure_message
|
|
36
|
+
"Expected #{factory_name} to have scope #{@scope} and order by #{@field}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def description
|
|
40
|
+
"sort by ordinal"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Models # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# Ensures that the model can sort by_title
|
|
6
|
+
# requires that the class have a factory
|
|
7
|
+
# Tests:
|
|
8
|
+
# scope :by_title, order("title ASC")
|
|
9
|
+
# Examples:
|
|
10
|
+
# it { should scope_by_title }
|
|
11
|
+
def scope_by_title
|
|
12
|
+
SortingMatcher.new(:by_title, :title)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Test for 'by_name' named scope which orders by name
|
|
16
|
+
# requires that the class have a shoulda factory
|
|
17
|
+
# Tests:
|
|
18
|
+
# scope :by_name, order("name ASC")
|
|
19
|
+
# Examples:
|
|
20
|
+
# it { should scope_by_name }
|
|
21
|
+
def scope_by_name
|
|
22
|
+
SortingMatcher.new(:by_name, :name)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# For 'by_latest named scope which orders by updated at:
|
|
26
|
+
# Tests:
|
|
27
|
+
# scope :by_latest, order("updated_at DESC")
|
|
28
|
+
# Examples:
|
|
29
|
+
# it { should scope_by_latest }
|
|
30
|
+
def scope_by_latest
|
|
31
|
+
SortingMatcher.new(:by_latest, :updated_at)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Test for 'by_newest' named scope which orders by 'created_at DESC'
|
|
35
|
+
# requires that the class have a shoulda factory
|
|
36
|
+
# Tests:
|
|
37
|
+
# scope :by_newest, order("created_at DESC")
|
|
38
|
+
# Examples:
|
|
39
|
+
# it { should scope_by_newest }
|
|
40
|
+
def scope_by_newest
|
|
41
|
+
SortingMatcher.new(:by_newest, :created_at)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Test for 'by_oldest' named scope which orders by 'created_at ASC'
|
|
45
|
+
# requires that the class have a shoulda factory
|
|
46
|
+
# Tests:
|
|
47
|
+
# scope :oldest, order("created_at ASC")
|
|
48
|
+
# Examples:
|
|
49
|
+
# it { should scope_oldest }
|
|
50
|
+
def scope_by_oldest
|
|
51
|
+
SortingMatcher.new(:by_oldest, :created_at)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class SortingMatcher < SuitMatcherBase # :nodoc:
|
|
55
|
+
|
|
56
|
+
def initialize(scope, field)
|
|
57
|
+
@scope = scope
|
|
58
|
+
@field = field
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def matches?(subject)
|
|
62
|
+
@subject = subject
|
|
63
|
+
@subject.class.delete_all
|
|
64
|
+
if @scope == :by_newest
|
|
65
|
+
first = Factory(factory_name, :created_at => 1.hour.ago)
|
|
66
|
+
second = Factory(factory_name, :created_at => 1.day.ago)
|
|
67
|
+
first == @subject.class.send(@scope)[0] && second == @subject.class.send(@scope)[1]
|
|
68
|
+
elsif @scope == :by_oldest
|
|
69
|
+
first = Factory(factory_name, :created_at => 1.day.ago)
|
|
70
|
+
second = Factory(factory_name, :created_at => 1.hour.ago)
|
|
71
|
+
first == @subject.class.send(@scope)[0] && second == @subject.class.send(@scope)[1]
|
|
72
|
+
elsif @scope == :by_latest
|
|
73
|
+
first = Factory(factory_name, :updated_at => 1.hour.ago)
|
|
74
|
+
second = Factory(factory_name, :updated_at => 1.day.ago)
|
|
75
|
+
first == @subject.class.send(@scope)[0] && second == @subject.class.send(@scope)[1]
|
|
76
|
+
else
|
|
77
|
+
first = Factory(factory_name, @field => 'a')
|
|
78
|
+
second = Factory(factory_name, @field => 'b')
|
|
79
|
+
first == @subject.class.send(@scope)[0] && second == @subject.class.send(@scope)[1]
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def failure_message
|
|
84
|
+
"Expected #{factory_name} to scope #{@scope} on #{@field}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def description
|
|
88
|
+
"sorting"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Suit # :nodoc:
|
|
2
|
+
module Models # :nodoc:
|
|
3
|
+
module Matchers
|
|
4
|
+
|
|
5
|
+
# 'newer_than' named scope which retrieves items newer than given date
|
|
6
|
+
# requires that the class have a factory
|
|
7
|
+
# Tests:
|
|
8
|
+
# scope :newer_than, lambda { |time| {:conditions => ["created_at < ?", time || 1.day.ago] } }
|
|
9
|
+
# Examples:
|
|
10
|
+
# it { should scope_recent }
|
|
11
|
+
def scope_newer_than
|
|
12
|
+
TimeMatcher.new(:newer_than)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# 'scope_older_than' named scope which retrieves items older than the given date
|
|
16
|
+
# requires that the class have a factory
|
|
17
|
+
# Tests:
|
|
18
|
+
# scope :newer_than, lambda { |time| {:conditions => ["created_at < ?", time || 1.day.ago] } }
|
|
19
|
+
# Examples:
|
|
20
|
+
# it { should scope_recent }
|
|
21
|
+
def scope_older_than
|
|
22
|
+
TimeMatcher.new(:older_than)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class TimeMatcher < SuitMatcherBase # :nodoc:
|
|
26
|
+
|
|
27
|
+
def initialize(scope, field = :created_at)
|
|
28
|
+
@scope = scope
|
|
29
|
+
@field = field
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def matches?(subject)
|
|
33
|
+
@subject = subject
|
|
34
|
+
@subject.class.delete_all
|
|
35
|
+
old_item = Factory(factory_name, @field => 1.month.ago)
|
|
36
|
+
new_item = Factory(factory_name, @field => 1.day.ago)
|
|
37
|
+
items = @subject.class.send(@scope, 1.week.ago)
|
|
38
|
+
if @scope == :newer_than
|
|
39
|
+
items.include?(new_item) && !items.include?(old_item)
|
|
40
|
+
elsif @scope == :older_than
|
|
41
|
+
!items.include?(new_item) && items.include?(old_item)
|
|
42
|
+
else
|
|
43
|
+
raise "matcher not implemented for #{@scope}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def failure_message
|
|
48
|
+
"Expected #{factory_name} to scope by #{@scope} on #{@field} and be successful. But the call failed"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def description
|
|
52
|
+
"items scoped #{@scope}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/suit.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__) unless $LOAD_PATH.include?(File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
module Suit
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
require 'rspec/core'
|
|
7
|
+
require 'rspec/mocks'
|
|
8
|
+
require 'rspec/expectations'
|
|
9
|
+
|
|
10
|
+
require 'factory_girl'
|
|
11
|
+
require 'suit_factories'
|
|
12
|
+
require 'models/matchers'
|
|
13
|
+
require 'controllers/matchers'
|
|
14
|
+
|
|
15
|
+
RSpec.configure do |config|
|
|
16
|
+
config.include(Suit::Models::Matchers)
|
|
17
|
+
config.include(Suit::Controllers::Matchers)
|
|
18
|
+
config.color_enabled = true
|
|
19
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
FactoryGirl.define do
|
|
2
|
+
|
|
3
|
+
sequence :email do |n|
|
|
4
|
+
"somebody#{n}@example.com"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
sequence :login do |n|
|
|
8
|
+
"inquire#{n}"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
sequence :password do |n|
|
|
12
|
+
"password#{n}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
sequence :name do |n|
|
|
16
|
+
"a_name#{n}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
sequence :title do |n|
|
|
20
|
+
"a_title#{n}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
sequence :abbr do |n|
|
|
24
|
+
"abbr#{n}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
sequence :uri do |n|
|
|
28
|
+
"n#{n}.example.com"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
sequence :description do |n|
|
|
32
|
+
"This is the description: #{n}"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
sequence :locale do |n|
|
|
36
|
+
"a#{n}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
sequence :address do |n|
|
|
40
|
+
"#{n} West #{n} South"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
3
|
+
require 'rspec'
|
|
4
|
+
require 'suit'
|
|
5
|
+
|
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
|
7
|
+
# in ./support/ and its subdirectories.
|
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
|
9
|
+
|
|
10
|
+
RSpec.configure do |config|
|
|
11
|
+
|
|
12
|
+
end
|
data/suit.gemspec
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = "suit"
|
|
8
|
+
s.version = "0.1.0"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Justin Ball"]
|
|
12
|
+
s.date = "2012-02-07"
|
|
13
|
+
s.description = "A collection of commonly used rspec matchers"
|
|
14
|
+
s.email = "justinball@gmail.com"
|
|
15
|
+
s.extra_rdoc_files = [
|
|
16
|
+
"LICENSE.txt",
|
|
17
|
+
"README.rdoc"
|
|
18
|
+
]
|
|
19
|
+
s.files = [
|
|
20
|
+
".DS_Store",
|
|
21
|
+
".document",
|
|
22
|
+
".rspec",
|
|
23
|
+
"Gemfile",
|
|
24
|
+
"Gemfile.lock",
|
|
25
|
+
"LICENSE.txt",
|
|
26
|
+
"README.rdoc",
|
|
27
|
+
"Rakefile",
|
|
28
|
+
"VERSION",
|
|
29
|
+
"lib/.DS_Store",
|
|
30
|
+
"lib/controllers/matchers.rb",
|
|
31
|
+
"lib/controllers/matchers/.DS_Store",
|
|
32
|
+
"lib/controllers/matchers/login_matcher.rb",
|
|
33
|
+
"lib/controllers/matchers/role_matcher.rb",
|
|
34
|
+
"lib/models/matchers.rb",
|
|
35
|
+
"lib/models/matchers/nested_attribute_matcher.rb",
|
|
36
|
+
"lib/models/matchers/sanitize_matcher.rb",
|
|
37
|
+
"lib/models/matchers/scope_active_matchers.rb",
|
|
38
|
+
"lib/models/matchers/scope_creator_matchers.rb",
|
|
39
|
+
"lib/models/matchers/scope_is_public_matchers.rb",
|
|
40
|
+
"lib/models/matchers/scope_ordinal_matchers.rb",
|
|
41
|
+
"lib/models/matchers/scope_sorting_matchers.rb",
|
|
42
|
+
"lib/models/matchers/scope_time_matchers.rb",
|
|
43
|
+
"lib/models/matchers/suit_matcher_base.rb",
|
|
44
|
+
"lib/suit.rb",
|
|
45
|
+
"lib/suit_factories.rb",
|
|
46
|
+
"spec/controllers/matchers/login_matcher_spec.rb",
|
|
47
|
+
"spec/spec_helper.rb",
|
|
48
|
+
"suit.gemspec"
|
|
49
|
+
]
|
|
50
|
+
s.homepage = "http://github.com/tatemae/suit"
|
|
51
|
+
s.licenses = ["MIT"]
|
|
52
|
+
s.require_paths = ["lib"]
|
|
53
|
+
s.rubygems_version = "1.8.12"
|
|
54
|
+
s.summary = "common rspec matchers"
|
|
55
|
+
|
|
56
|
+
if s.respond_to? :specification_version then
|
|
57
|
+
s.specification_version = 3
|
|
58
|
+
|
|
59
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
60
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
|
|
61
|
+
s.add_runtime_dependency(%q<rspec>, ["~> 2.8.0"])
|
|
62
|
+
s.add_runtime_dependency(%q<factory_girl>, [">= 1.3.0"])
|
|
63
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
|
64
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
65
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
|
|
66
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
|
67
|
+
else
|
|
68
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
|
69
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
|
70
|
+
s.add_dependency(%q<factory_girl>, [">= 1.3.0"])
|
|
71
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
|
72
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
73
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
|
74
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
|
75
|
+
end
|
|
76
|
+
else
|
|
77
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
|
78
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
|
79
|
+
s.add_dependency(%q<factory_girl>, [">= 1.3.0"])
|
|
80
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
|
81
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
82
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
|
83
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
metadata
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: suit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 27
|
|
5
|
+
prerelease:
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 1
|
|
9
|
+
- 0
|
|
10
|
+
version: 0.1.0
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Justin Ball
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2012-02-07 00:00:00 Z
|
|
19
|
+
dependencies:
|
|
20
|
+
- !ruby/object:Gem::Dependency
|
|
21
|
+
type: :runtime
|
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
23
|
+
none: false
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
hash: 9
|
|
28
|
+
segments:
|
|
29
|
+
- 2
|
|
30
|
+
- 3
|
|
31
|
+
- 5
|
|
32
|
+
version: 2.3.5
|
|
33
|
+
version_requirements: *id001
|
|
34
|
+
name: activesupport
|
|
35
|
+
prerelease: false
|
|
36
|
+
- !ruby/object:Gem::Dependency
|
|
37
|
+
type: :runtime
|
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - ~>
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
hash: 47
|
|
44
|
+
segments:
|
|
45
|
+
- 2
|
|
46
|
+
- 8
|
|
47
|
+
- 0
|
|
48
|
+
version: 2.8.0
|
|
49
|
+
version_requirements: *id002
|
|
50
|
+
name: rspec
|
|
51
|
+
prerelease: false
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
type: :runtime
|
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
55
|
+
none: false
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
hash: 27
|
|
60
|
+
segments:
|
|
61
|
+
- 1
|
|
62
|
+
- 3
|
|
63
|
+
- 0
|
|
64
|
+
version: 1.3.0
|
|
65
|
+
version_requirements: *id003
|
|
66
|
+
name: factory_girl
|
|
67
|
+
prerelease: false
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
type: :development
|
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
71
|
+
none: false
|
|
72
|
+
requirements:
|
|
73
|
+
- - ~>
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
hash: 31
|
|
76
|
+
segments:
|
|
77
|
+
- 3
|
|
78
|
+
- 12
|
|
79
|
+
version: "3.12"
|
|
80
|
+
version_requirements: *id004
|
|
81
|
+
name: rdoc
|
|
82
|
+
prerelease: false
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
type: :development
|
|
85
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
|
86
|
+
none: false
|
|
87
|
+
requirements:
|
|
88
|
+
- - ~>
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
hash: 23
|
|
91
|
+
segments:
|
|
92
|
+
- 1
|
|
93
|
+
- 0
|
|
94
|
+
- 0
|
|
95
|
+
version: 1.0.0
|
|
96
|
+
version_requirements: *id005
|
|
97
|
+
name: bundler
|
|
98
|
+
prerelease: false
|
|
99
|
+
- !ruby/object:Gem::Dependency
|
|
100
|
+
type: :development
|
|
101
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
|
102
|
+
none: false
|
|
103
|
+
requirements:
|
|
104
|
+
- - ~>
|
|
105
|
+
- !ruby/object:Gem::Version
|
|
106
|
+
hash: 49
|
|
107
|
+
segments:
|
|
108
|
+
- 1
|
|
109
|
+
- 8
|
|
110
|
+
- 3
|
|
111
|
+
version: 1.8.3
|
|
112
|
+
version_requirements: *id006
|
|
113
|
+
name: jeweler
|
|
114
|
+
prerelease: false
|
|
115
|
+
- !ruby/object:Gem::Dependency
|
|
116
|
+
type: :development
|
|
117
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
|
118
|
+
none: false
|
|
119
|
+
requirements:
|
|
120
|
+
- - ">="
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
hash: 3
|
|
123
|
+
segments:
|
|
124
|
+
- 0
|
|
125
|
+
version: "0"
|
|
126
|
+
version_requirements: *id007
|
|
127
|
+
name: rcov
|
|
128
|
+
prerelease: false
|
|
129
|
+
description: A collection of commonly used rspec matchers
|
|
130
|
+
email: justinball@gmail.com
|
|
131
|
+
executables: []
|
|
132
|
+
|
|
133
|
+
extensions: []
|
|
134
|
+
|
|
135
|
+
extra_rdoc_files:
|
|
136
|
+
- LICENSE.txt
|
|
137
|
+
- README.rdoc
|
|
138
|
+
files:
|
|
139
|
+
- .DS_Store
|
|
140
|
+
- .document
|
|
141
|
+
- .rspec
|
|
142
|
+
- Gemfile
|
|
143
|
+
- Gemfile.lock
|
|
144
|
+
- LICENSE.txt
|
|
145
|
+
- README.rdoc
|
|
146
|
+
- Rakefile
|
|
147
|
+
- VERSION
|
|
148
|
+
- lib/.DS_Store
|
|
149
|
+
- lib/controllers/matchers.rb
|
|
150
|
+
- lib/controllers/matchers/.DS_Store
|
|
151
|
+
- lib/controllers/matchers/login_matcher.rb
|
|
152
|
+
- lib/controllers/matchers/role_matcher.rb
|
|
153
|
+
- lib/models/matchers.rb
|
|
154
|
+
- lib/models/matchers/nested_attribute_matcher.rb
|
|
155
|
+
- lib/models/matchers/sanitize_matcher.rb
|
|
156
|
+
- lib/models/matchers/scope_active_matchers.rb
|
|
157
|
+
- lib/models/matchers/scope_creator_matchers.rb
|
|
158
|
+
- lib/models/matchers/scope_is_public_matchers.rb
|
|
159
|
+
- lib/models/matchers/scope_ordinal_matchers.rb
|
|
160
|
+
- lib/models/matchers/scope_sorting_matchers.rb
|
|
161
|
+
- lib/models/matchers/scope_time_matchers.rb
|
|
162
|
+
- lib/models/matchers/suit_matcher_base.rb
|
|
163
|
+
- lib/suit.rb
|
|
164
|
+
- lib/suit_factories.rb
|
|
165
|
+
- spec/controllers/matchers/login_matcher_spec.rb
|
|
166
|
+
- spec/spec_helper.rb
|
|
167
|
+
- suit.gemspec
|
|
168
|
+
homepage: http://github.com/tatemae/suit
|
|
169
|
+
licenses:
|
|
170
|
+
- MIT
|
|
171
|
+
post_install_message:
|
|
172
|
+
rdoc_options: []
|
|
173
|
+
|
|
174
|
+
require_paths:
|
|
175
|
+
- lib
|
|
176
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
177
|
+
none: false
|
|
178
|
+
requirements:
|
|
179
|
+
- - ">="
|
|
180
|
+
- !ruby/object:Gem::Version
|
|
181
|
+
hash: 3
|
|
182
|
+
segments:
|
|
183
|
+
- 0
|
|
184
|
+
version: "0"
|
|
185
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
|
+
none: false
|
|
187
|
+
requirements:
|
|
188
|
+
- - ">="
|
|
189
|
+
- !ruby/object:Gem::Version
|
|
190
|
+
hash: 3
|
|
191
|
+
segments:
|
|
192
|
+
- 0
|
|
193
|
+
version: "0"
|
|
194
|
+
requirements: []
|
|
195
|
+
|
|
196
|
+
rubyforge_project:
|
|
197
|
+
rubygems_version: 1.8.12
|
|
198
|
+
signing_key:
|
|
199
|
+
specification_version: 3
|
|
200
|
+
summary: common rspec matchers
|
|
201
|
+
test_files: []
|
|
202
|
+
|