carlosbrando-remarkable 0.0.99 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -5
- data/Manifest.txt +53 -35
- data/PostInstall.txt +1 -6
- data/README.rdoc +109 -15
- data/Rakefile +29 -29
- data/lib/remarkable/active_record/README.markdown +378 -0
- data/lib/remarkable/active_record/active_record.rb +12 -11
- data/lib/remarkable/active_record/helpers.rb +215 -5
- data/lib/remarkable/active_record/macros/associations/association_matcher.rb +242 -0
- data/lib/remarkable/active_record/macros/callbacks/callback_matcher.rb +46 -0
- data/lib/remarkable/active_record/macros/database/column_matcher.rb +122 -0
- data/lib/remarkable/active_record/macros/database/index_matcher.rb +103 -0
- data/lib/remarkable/active_record/macros/validations/allow_mass_assignment_of_matcher.rb +52 -0
- data/lib/remarkable/active_record/macros/validations/ensure_value_in_list_matcher.rb +83 -0
- data/lib/remarkable/active_record/macros/validations/ensure_value_in_range_matcher.rb +172 -0
- data/lib/remarkable/active_record/macros/validations/have_class_methods_matcher.rb +54 -0
- data/lib/remarkable/active_record/macros/validations/have_instance_methods_matcher.rb +54 -0
- data/lib/remarkable/active_record/macros/validations/have_named_scope_matcher.rb +94 -0
- data/lib/remarkable/active_record/macros/validations/have_readonly_attributes_matcher.rb +48 -0
- data/lib/remarkable/active_record/macros/validations/protect_attributes_matcher.rb +51 -0
- data/lib/remarkable/active_record/macros/validations/validate_acceptance_of_matcher.rb +79 -0
- data/lib/remarkable/active_record/macros/validations/validate_associated_matcher.rb +177 -0
- data/lib/remarkable/active_record/macros/validations/validate_confirmation_of_matcher.rb +74 -0
- data/lib/remarkable/active_record/macros/validations/validate_exclusion_of_matcher.rb +38 -0
- data/lib/remarkable/active_record/macros/validations/validate_format_of_matcher.rb +33 -0
- data/lib/remarkable/active_record/macros/validations/validate_inclusion_of_matcher.rb +45 -0
- data/lib/remarkable/active_record/macros/validations/validate_length_of_matcher.rb +248 -0
- data/lib/remarkable/active_record/macros/validations/validate_numericality_of_matcher.rb +206 -0
- data/lib/remarkable/active_record/macros/validations/validate_presence_of_matcher.rb +72 -0
- data/lib/remarkable/active_record/macros/validations/validate_uniqueness_of_matcher.rb +222 -0
- data/lib/remarkable/active_record/macros.rb +52 -0
- data/lib/remarkable/assertions.rb +29 -0
- data/lib/remarkable/controller/README.markdown +147 -0
- data/lib/remarkable/controller/controller.rb +11 -6
- data/lib/remarkable/controller/helpers.rb +4 -38
- data/lib/remarkable/controller/macros/assign_matcher.rb +85 -0
- data/lib/remarkable/controller/macros/filter_params_matcher.rb +63 -0
- data/lib/remarkable/controller/macros/metadata_matcher.rb +63 -0
- data/lib/remarkable/controller/macros/render_with_layout_matcher.rb +75 -0
- data/lib/remarkable/controller/macros/respond_with_content_type_matcher.rb +60 -0
- data/lib/remarkable/controller/macros/respond_with_matcher.rb +62 -0
- data/lib/remarkable/controller/macros/return_from_session_matcher.rb +58 -0
- data/lib/remarkable/controller/macros/route_matcher.rb +75 -0
- data/lib/remarkable/controller/macros/set_the_flash_to_matcher.rb +60 -0
- data/lib/remarkable/controller/macros.rb +78 -0
- data/lib/remarkable/dsl.rb +239 -0
- data/lib/remarkable/example/example_methods.rb +27 -7
- data/lib/remarkable/helpers.rb +28 -0
- data/lib/remarkable/matcher_base.rb +64 -0
- data/lib/remarkable/private_helpers.rb +10 -115
- data/lib/remarkable/rails.rb +27 -0
- data/lib/remarkable.rb +13 -5
- data/remarkable.gemspec +43 -0
- data/spec/controllers/posts_controller_spec.rb +58 -4
- data/spec/controllers/users_controller_spec.rb +1 -0
- data/spec/fixtures/fleas.yml +10 -0
- data/spec/fixtures/users.yml +7 -0
- data/spec/models/address_spec.rb +44 -0
- data/spec/models/dog_spec.rb +64 -3
- data/spec/models/flea_spec.rb +30 -0
- data/spec/models/post_spec.rb +36 -2
- data/spec/models/product_spec.rb +73 -8
- data/spec/models/tag_spec.rb +2 -2
- data/spec/models/tagging_spec.rb +24 -0
- data/spec/models/user_spec.rb +206 -21
- data/spec/other/custom_macros_spec.rb +27 -0
- data/spec/other/my_own_matcher_spec.rb +11 -0
- data/spec/other/private_helpers_spec.rb +31 -0
- data/spec/rails_root/app/controllers/posts_controller.rb +2 -0
- data/spec/rails_root/app/models/address.rb +2 -2
- data/spec/rails_root/app/models/flea.rb +4 -0
- data/spec/rails_root/app/models/pets/dog.rb +12 -0
- data/spec/rails_root/app/models/product.rb +7 -5
- data/spec/rails_root/app/models/tagging.rb +2 -0
- data/spec/rails_root/app/models/user.rb +20 -5
- data/spec/rails_root/app/views/layouts/posts.rhtml +8 -6
- data/spec/rails_root/config/database.yml +1 -2
- data/spec/rails_root/config/environment.rb +3 -1
- data/spec/rails_root/config/environments/{sqlite3.rb → test.rb} +0 -0
- data/spec/rails_root/config/locales/en.yml +8 -0
- data/spec/rails_root/db/migrate/001_create_users.rb +2 -2
- data/spec/rails_root/db/migrate/005_create_dogs.rb +1 -0
- data/spec/rails_root/db/migrate/011_add_fleas_color.rb +10 -0
- data/spec/rails_root/db/migrate/012_add_fleas_address.rb +10 -0
- data/spec/rails_root/spec/remarkable_macros/.keep +0 -0
- data/spec/rails_root/vendor/plugins/my_plugin/remarkable_macros/.keep +0 -0
- data/spec/spec_helper.rb +0 -2
- metadata +63 -43
- data/lib/remarkable/active_record/macros/associations/belong_to.rb +0 -81
- data/lib/remarkable/active_record/macros/associations/have_and_belong_to_many.rb +0 -77
- data/lib/remarkable/active_record/macros/associations/have_many.rb +0 -160
- data/lib/remarkable/active_record/macros/associations/have_one.rb +0 -133
- data/lib/remarkable/active_record/macros/database/have_db_column.rb +0 -81
- data/lib/remarkable/active_record/macros/database/have_db_columns.rb +0 -73
- data/lib/remarkable/active_record/macros/database/have_indices.rb +0 -75
- data/lib/remarkable/active_record/macros/validations/allow_values_for.rb +0 -103
- data/lib/remarkable/active_record/macros/validations/ensure_length_at_least.rb +0 -97
- data/lib/remarkable/active_record/macros/validations/ensure_length_in_range.rb +0 -134
- data/lib/remarkable/active_record/macros/validations/ensure_length_is.rb +0 -106
- data/lib/remarkable/active_record/macros/validations/ensure_value_in_range.rb +0 -117
- data/lib/remarkable/active_record/macros/validations/have_class_methods.rb +0 -74
- data/lib/remarkable/active_record/macros/validations/have_instance_methods.rb +0 -74
- data/lib/remarkable/active_record/macros/validations/have_named_scope.rb +0 -148
- data/lib/remarkable/active_record/macros/validations/have_readonly_attributes.rb +0 -81
- data/lib/remarkable/active_record/macros/validations/only_allow_numeric_values_for.rb +0 -89
- data/lib/remarkable/active_record/macros/validations/protect_attributes.rb +0 -89
- data/lib/remarkable/active_record/macros/validations/require_acceptance_of.rb +0 -94
- data/lib/remarkable/active_record/macros/validations/require_attributes.rb +0 -94
- data/lib/remarkable/active_record/macros/validations/require_unique_attributes.rb +0 -146
- data/lib/remarkable/controller/macros/assign_to.rb +0 -110
- data/lib/remarkable/controller/macros/filter_params.rb +0 -52
- data/lib/remarkable/controller/macros/redirect_to.rb +0 -24
- data/lib/remarkable/controller/macros/render_a_form.rb +0 -23
- data/lib/remarkable/controller/macros/render_template.rb +0 -18
- data/lib/remarkable/controller/macros/render_with_layout.rb +0 -61
- data/lib/remarkable/controller/macros/respond_with.rb +0 -86
- data/lib/remarkable/controller/macros/respond_with_content_type.rb +0 -45
- data/lib/remarkable/controller/macros/return_from_session.rb +0 -45
- data/lib/remarkable/controller/macros/route.rb +0 -91
- data/lib/remarkable/controller/macros/set_the_flash_to.rb +0 -58
- data/spec/rails_root/app/models/dog.rb +0 -5
data/spec/models/post_spec.rb
CHANGED
@@ -7,14 +7,37 @@ describe Post do
|
|
7
7
|
it { should belong_to(:owner) }
|
8
8
|
it { should belong_to(:user, :owner) }
|
9
9
|
|
10
|
+
it { should have_many(:tags).through(:taggings) }
|
10
11
|
it { should have_many(:tags, :through => :taggings) }
|
12
|
+
|
13
|
+
it { should have_many(:through_tags).through(:taggings) }
|
11
14
|
it { should have_many(:through_tags, :through => :taggings) }
|
15
|
+
|
16
|
+
it { should have_many(:tags, :through_tags).through(:taggings) }
|
12
17
|
it { should have_many(:tags, :through_tags, :through => :taggings) }
|
13
18
|
|
14
19
|
it { should require_unique_attributes(:title) }
|
20
|
+
it { should_not require_unique_attributes(:body) }
|
21
|
+
it { should_not require_unique_attributes(:title).scoped_to(:user_id) }
|
22
|
+
it { should_not require_unique_attributes(:title, :scoped_to => :user_id) }
|
23
|
+
|
15
24
|
it { should require_attributes(:body, :message => /wtf/) }
|
25
|
+
it { should require_attributes(:body).message(/wtf/) }
|
26
|
+
it { should_not require_attributes(:body) }
|
16
27
|
it { should require_attributes(:title) }
|
28
|
+
it { should_not require_attributes(:user_id) }
|
29
|
+
|
17
30
|
it { should only_allow_numeric_values_for(:user_id) }
|
31
|
+
|
32
|
+
it { should validate_numericality_of(:user_id) }
|
33
|
+
it { should validate_numericality_of(:user_id).allow_nil(false) }
|
34
|
+
it { should validate_numericality_of(:user_id).allow_blank(false) }
|
35
|
+
|
36
|
+
it { should_not validate_numericality_of(:user_id, :allow_nil => true) }
|
37
|
+
it { should_not validate_numericality_of(:user_id, :allow_blank => true) }
|
38
|
+
|
39
|
+
it { should_not validate_numericality_of(:title) }
|
40
|
+
it { should_not only_allow_numeric_values_for(:title) }
|
18
41
|
end
|
19
42
|
|
20
43
|
describe Post do
|
@@ -23,13 +46,24 @@ describe Post do
|
|
23
46
|
should_belong_to :user
|
24
47
|
should_belong_to :owner
|
25
48
|
should_belong_to :user, :owner
|
26
|
-
|
49
|
+
|
27
50
|
should_have_many :tags, :through => :taggings
|
28
51
|
should_have_many :through_tags, :through => :taggings
|
29
52
|
should_have_many :tags, :through_tags, :through => :taggings
|
30
|
-
|
53
|
+
|
31
54
|
should_require_unique_attributes :title
|
32
55
|
should_require_attributes :body, :message => /wtf/
|
33
56
|
should_require_attributes :title
|
57
|
+
|
34
58
|
should_only_allow_numeric_values_for :user_id
|
59
|
+
|
60
|
+
should_validate_numericality_of :user_id
|
61
|
+
should_validate_numericality_of :user_id, :allow_nil => false
|
62
|
+
should_validate_numericality_of :user_id, :allow_blank => false
|
63
|
+
|
64
|
+
should_not_validate_numericality_of :user_id, :allow_nil => true
|
65
|
+
should_not_validate_numericality_of :user_id, :allow_blank => true
|
66
|
+
|
67
|
+
should_not_validate_numericality_of :title
|
68
|
+
should_not_only_allow_numeric_values_for :title
|
35
69
|
end
|
data/spec/models/product_spec.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
3
|
describe Product do
|
4
|
+
it { should require_attributes(:title) }
|
5
|
+
it { should_not require_attributes(:price) }
|
6
|
+
|
4
7
|
describe "An intangible product" do
|
5
8
|
before(:all) do
|
6
9
|
@product = Product.new(:tangible => false)
|
@@ -9,8 +12,27 @@ describe Product do
|
|
9
12
|
it { @product.should_not allow_values_for(:size, "22") }
|
10
13
|
it { @product.should allow_values_for(:size, "22kb") }
|
11
14
|
|
15
|
+
it { @product.should_not validate_format_of(:size, "22") }
|
16
|
+
it { @product.should validate_format_of(:size, "22kb") }
|
17
|
+
|
18
|
+
it { @product.should validate_exclusion_of(:weight, 10..100) }
|
19
|
+
it { @product.should_not validate_exclusion_of(:weight, 1..9) }
|
20
|
+
|
12
21
|
it { @product.should require_attributes(:title) }
|
22
|
+
it { @product.should_not require_attributes(:price) }
|
23
|
+
|
24
|
+
it { @product.should validate_presence_of(:title) }
|
25
|
+
it { @product.should_not validate_presence_of(:price) }
|
26
|
+
|
13
27
|
it { @product.should ensure_value_in_range(:price, 0..99) }
|
28
|
+
it { @product.should validate_inclusion_of(:price, 0..99) }
|
29
|
+
it { @product.should validate_inclusion_of(:price, 0..99).allow_nil(false) }
|
30
|
+
it { @product.should validate_inclusion_of(:price, 0..99).allow_blank(false) }
|
31
|
+
|
32
|
+
it { @product.should_not ensure_value_in_range(:price, 2..80) }
|
33
|
+
it { @product.should_not validate_inclusion_of(:price, 2..80) }
|
34
|
+
it { @product.should_not validate_inclusion_of(:price, 0..99, :allow_nil => true) }
|
35
|
+
it { @product.should_not validate_inclusion_of(:price, 0..99, :allow_blank => true) }
|
14
36
|
end
|
15
37
|
|
16
38
|
describe "A tangible product" do
|
@@ -18,13 +40,32 @@ describe Product do
|
|
18
40
|
@product = Product.new(:tangible => true)
|
19
41
|
end
|
20
42
|
|
21
|
-
it { @product.
|
22
|
-
it { @product.should
|
43
|
+
it { @product.should validate_inclusion_of(:size, "S", "M", "L", "XL") }
|
44
|
+
it { @product.should validate_inclusion_of(:size, "S", "M", "L", "XL").allow_blank }
|
45
|
+
it { @product.should_not validate_inclusion_of(:size, "XXXL", "XXL") }
|
46
|
+
it { @product.should_not validate_inclusion_of(:size, "S", "M", "L", "XL", :allow_blank => false) }
|
47
|
+
|
48
|
+
it { @product.should validate_exclusion_of(:size, "XS", "XM") }
|
49
|
+
it { @product.should_not validate_exclusion_of(:size, "S", "M", "L", "XL") }
|
50
|
+
|
51
|
+
it { @product.should require_attributes(:price, :title) }
|
52
|
+
it { @product.should validate_presence_of(:price, :title) }
|
23
53
|
|
24
|
-
it { @product.should require_attributes(:price) }
|
25
54
|
it { @product.should ensure_value_in_range(:price, 1..9999) }
|
26
55
|
it { @product.should ensure_value_in_range(:weight, 1..100) }
|
56
|
+
|
57
|
+
it { @product.should validate_inclusion_of(:price, 1..9999) }
|
58
|
+
it { @product.should validate_inclusion_of(:price, 1..9999).allow_nil }
|
59
|
+
it { @product.should_not validate_inclusion_of(:price, 1..9999, :allow_nil => false) }
|
60
|
+
|
61
|
+
it { @product.should validate_inclusion_of(:weight, 1..100) }
|
62
|
+
it { @product.should validate_inclusion_of(:weight, 1..100).allow_blank(true) }
|
63
|
+
it { @product.should_not validate_inclusion_of(:weight, 1..100, :allow_blank => false) }
|
64
|
+
|
27
65
|
it { @product.should ensure_length_in_range(:size, 5..20) }
|
66
|
+
it { @product.should validate_length_of(:size, :in => 5..20).allow_blank }
|
67
|
+
it { @product.should_not validate_length_of(:size, :in => 1..10) }
|
68
|
+
it { @product.should_not validate_length_of(:size, :within => 5..20, :allow_blank => false) }
|
28
69
|
end
|
29
70
|
end
|
30
71
|
|
@@ -36,9 +77,14 @@ describe Product do
|
|
36
77
|
|
37
78
|
should_not_allow_values_for :size, "22"
|
38
79
|
should_allow_values_for :size, "22kb"
|
39
|
-
|
40
|
-
should_require_attributes :title
|
80
|
+
|
41
81
|
should_ensure_value_in_range :price, 0..99
|
82
|
+
|
83
|
+
should_require_attributes(:title)
|
84
|
+
should_not_require_attributes(:price)
|
85
|
+
|
86
|
+
should_validate_presence_of(:title)
|
87
|
+
should_not_validate_presence_of(:price)
|
42
88
|
end
|
43
89
|
|
44
90
|
describe "A tangible product" do
|
@@ -46,12 +92,31 @@ describe Product do
|
|
46
92
|
@product = Product.new(:tangible => true)
|
47
93
|
end
|
48
94
|
|
49
|
-
|
50
|
-
|
95
|
+
should_validate_inclusion_of :size, "S", "M", "L", "XL"
|
96
|
+
should_validate_inclusion_of :size, :allow_blank => true
|
97
|
+
should_not_validate_inclusion_of :size, "XXXL", "XXL"
|
98
|
+
should_not_validate_inclusion_of :size, "S", "M", "L", "XL", :allow_blank => false
|
99
|
+
|
100
|
+
should_validate_exclusion_of :size, "XS", "XM"
|
101
|
+
should_not_validate_exclusion_of :size, "S", "M", "L", "XL"
|
102
|
+
|
103
|
+
should_require_attributes :price, :title
|
104
|
+
should_validate_presence_of :price, :title
|
51
105
|
|
52
|
-
should_require_attributes :price
|
53
106
|
should_ensure_value_in_range :price, 1..9999
|
54
107
|
should_ensure_value_in_range :weight, 1..100
|
108
|
+
|
109
|
+
should_validate_inclusion_of :price, 1..9999
|
110
|
+
should_validate_inclusion_of :price, 1..9999, :allow_nil => true
|
111
|
+
should_not_validate_inclusion_of :price, 1..9999, :allow_nil => false
|
112
|
+
|
113
|
+
should_validate_inclusion_of :weight, 1..100
|
114
|
+
should_validate_inclusion_of :weight, 1..100, :allow_blank => true
|
115
|
+
should_not_validate_inclusion_of :weight, 1..100, :allow_blank => false
|
116
|
+
|
55
117
|
should_ensure_length_in_range :size, 5..20
|
118
|
+
should_validate_length_of :size, :in => 5..20, :allow_blank => true
|
119
|
+
should_not_validate_length_of :size, :in => 1..10
|
120
|
+
should_not_validate_length_of :size, :within =>5..20, :allow_blank => false
|
56
121
|
end
|
57
122
|
end
|
data/spec/models/tag_spec.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
3
|
describe Tag do
|
4
|
+
it { should have_many(:taggings).dependent(:destroy) }
|
4
5
|
it { should have_many(:taggings, :dependent => :destroy) }
|
5
6
|
it { should have_many(:posts) }
|
6
7
|
|
7
8
|
it { should ensure_length_at_least(:name, 2) }
|
8
|
-
|
9
|
+
|
9
10
|
it { should protect_attributes(:secret) }
|
10
|
-
|
11
11
|
it { should_not protect_attributes(:name) }
|
12
12
|
end
|
13
13
|
|
data/spec/models/tagging_spec.rb
CHANGED
@@ -4,10 +4,34 @@ describe Tagging do
|
|
4
4
|
it { should belong_to(:post) }
|
5
5
|
it { should belong_to(:tag) }
|
6
6
|
it { should belong_to(:post, :tag) }
|
7
|
+
|
8
|
+
it { should validate_associated(:post) }
|
9
|
+
it { should validate_associated(:tag) }
|
10
|
+
it { should validate_associated(:tag, :post) }
|
11
|
+
|
12
|
+
it do
|
13
|
+
# Create a Post mock that will return true when saving.
|
14
|
+
# This means that the object Post is always valid, then it can not be validated.
|
15
|
+
@post = mock_model(Post, :save => true, :valid? => true)
|
16
|
+
should_not validate_associated(:post)
|
17
|
+
end
|
18
|
+
|
19
|
+
it do
|
20
|
+
# Create a Tagging mock that will return true when saving.
|
21
|
+
# This means that even the association :post is not valid, :tagging will be valid.
|
22
|
+
# Then the association is not validated.
|
23
|
+
@tagging = Tagging.new
|
24
|
+
@tagging.stub!(:save).and_return(true)
|
25
|
+
should_not validate_associated(:post)
|
26
|
+
end
|
7
27
|
end
|
8
28
|
|
9
29
|
describe Tagging do
|
10
30
|
should_belong_to :post
|
11
31
|
should_belong_to :tag
|
12
32
|
should_belong_to :post, :tag
|
33
|
+
|
34
|
+
should_validate_associated :tag
|
35
|
+
should_validate_associated :post
|
36
|
+
should_validate_associated :tag, :post
|
13
37
|
end
|
data/spec/models/user_spec.rb
CHANGED
@@ -8,50 +8,180 @@ describe User do
|
|
8
8
|
it { should have_many(:friendships) }
|
9
9
|
it { should have_many(:friends) }
|
10
10
|
it { should have_many(:posts, :dogs, :friendships, :friends) }
|
11
|
+
|
12
|
+
it { should validate_associated(:posts) }
|
13
|
+
it { should validate_associated(:address) }
|
14
|
+
it { should validate_associated(:posts, :address) }
|
15
|
+
it { should_not validate_associated(:dogs) }
|
11
16
|
|
12
17
|
it { should have_one(:address) }
|
18
|
+
it { should have_one(:address).dependent(:destroy) }
|
13
19
|
it { should have_one(:address, :dependent => :destroy) }
|
14
20
|
|
15
|
-
it {
|
21
|
+
it { should_not have_index(:foo, :bar) }
|
22
|
+
|
23
|
+
it { should have_indices(:email, :name) }
|
24
|
+
it { should have_index([:email, :name]).unique }
|
25
|
+
it { should have_index([:email, :name]).unique(true) }
|
26
|
+
it { should have_index([:email, :name], :unique => true) }
|
27
|
+
it { should have_index(:age, :unique => false) }
|
28
|
+
|
29
|
+
it { should_not have_index(:phone) }
|
30
|
+
it { should_not have_index(:email, :unique => false) }
|
31
|
+
it { should_not have_index(:age, :unique => true) }
|
32
|
+
|
16
33
|
it { should have_index(:age) }
|
17
|
-
|
34
|
+
it { should_not have_index(:aged) }
|
35
|
+
|
36
|
+
it { should have_named_scope(:old)}
|
18
37
|
it { should have_named_scope(:old, :conditions => "age > 50") }
|
38
|
+
it { should_not have_named_scope(:old, :conditions => "age > 49") }
|
19
39
|
it { should have_named_scope(:eighteen, :conditions => { :age => 18 }) }
|
20
|
-
|
40
|
+
it { should_not have_named_scope(:eighteen, :conditions => { :age => 17 }) }
|
41
|
+
|
42
|
+
it { should have_named_scope('recent(5)') }
|
21
43
|
it { should have_named_scope('recent(5)', :limit => 5) }
|
44
|
+
it { should_not have_named_scope('recent(5)', :limit => 4) }
|
22
45
|
it { should have_named_scope('recent(1)', :limit => 1) }
|
46
|
+
it { should_not have_named_scope('recent(1)', :limit => 2) }
|
23
47
|
it { should have_named_scope('recent_via_method(7)', :limit => 7) }
|
24
|
-
|
48
|
+
it { should_not have_named_scope('recent_via_method(7)', :limit => 8) }
|
49
|
+
|
25
50
|
describe "when given an instance variable" do
|
26
51
|
before(:each) do
|
27
52
|
@count = 2
|
28
53
|
end
|
29
54
|
it { should have_named_scope("recent(#{@count})", :limit => 2) }
|
55
|
+
it { should_not have_named_scope("recent(#{@count})", :limit => 1) }
|
30
56
|
end
|
31
57
|
|
58
|
+
it { should have_after_create_callback(:send_welcome_email) }
|
59
|
+
it { should_not have_after_save_callback(:send_welcome_email) }
|
60
|
+
it { should_not have_after_destroy_callback(:goodbye_jerk) }
|
61
|
+
it { should have_before_validation_on_update_callback(:some_weird_callback) }
|
62
|
+
|
32
63
|
it { should_not allow_values_for(:email, "blah", "b lah") }
|
33
64
|
it { should allow_values_for(:email, "a@b.com", "asdf@asdf.com") }
|
34
|
-
it {
|
35
|
-
it {
|
65
|
+
it { should_not allow_values_for(:email, "a@b.com", "asdf@asdf.com").allow_nil }
|
66
|
+
it { should_not allow_values_for(:email, "a@b.com", "asdf@asdf.com").allow_nil(true) }
|
67
|
+
it { should allow_values_for(:email, "a@b.com", "asdf@asdf.com").allow_nil(false) }
|
68
|
+
|
69
|
+
it { should validate_confirmation_of(:username, :email) }
|
70
|
+
it { should_not validate_confirmation_of(:ssn) }
|
71
|
+
|
72
|
+
it { should ensure_length_in_range(:email, 2..100) }
|
73
|
+
it { should_not ensure_length_in_range(:email, 1..100) }
|
74
|
+
it { should_not ensure_length_in_range(:email, 2..101) }
|
75
|
+
it { should_not ensure_length_in_range(:email, 3..100) }
|
76
|
+
it { should_not ensure_length_in_range(:email, 2..99) }
|
77
|
+
|
78
|
+
it { should validate_size_of(:email, :minimum => 2) }
|
79
|
+
it { should validate_size_of(:email, :maximum => 100) }
|
80
|
+
it { should validate_length_of(:email, :in => 2..100) }
|
81
|
+
it { should validate_length_of(:email, :within => 2..100).allow_nil(false) }
|
82
|
+
it { should validate_length_of(:email, :within => 2..100).allow_blank(false) }
|
83
|
+
|
84
|
+
it { should_not validate_length_of(:email, :is => 2) }
|
85
|
+
it { should_not validate_length_of(:email, :is => 100) }
|
86
|
+
it { should_not validate_length_of(:email, :within => 0..200) }
|
87
|
+
it { should_not validate_length_of(:email, :in => 2..100, :allow_nil => true) }
|
88
|
+
it { should_not validate_length_of(:email, :in => 2..100, :allow_blank => true) }
|
89
|
+
|
90
|
+
it { should ensure_value_in_range(:age, 2..100) }
|
91
|
+
it { should_not ensure_value_in_range(:age, 1..100) }
|
92
|
+
it { should_not ensure_value_in_range(:age, 2..101) }
|
93
|
+
it { should_not ensure_value_in_range(:age, 3..100) }
|
94
|
+
it { should_not ensure_value_in_range(:age, 2..99) }
|
95
|
+
|
36
96
|
it { should protect_attributes(:password) }
|
97
|
+
it { should_not protect_attributes(:name, :age) }
|
98
|
+
|
99
|
+
it { should allow_mass_assignment_of(:name, :age) }
|
100
|
+
it { should_not allow_mass_assignment_of(:password) }
|
101
|
+
|
102
|
+
it { should have_class_methods(:find) }
|
103
|
+
it { should_not have_class_methods(:foo) }
|
37
104
|
it { should have_class_methods(:find, :destroy) }
|
105
|
+
it { should_not have_class_methods(:foo, :bar) }
|
106
|
+
|
107
|
+
it { should have_instance_methods(:email) }
|
108
|
+
it { should_not have_instance_methods(:foo) }
|
38
109
|
it { should have_instance_methods(:email, :age, :email=, :valid?) }
|
110
|
+
it { should_not have_instance_methods(:foo, :bar) }
|
39
111
|
|
112
|
+
it { should_not have_db_column(:foo) }
|
113
|
+
it { should_not have_db_columns(:foo, :bar) }
|
40
114
|
it { should have_db_columns(:name, :email, :age) }
|
41
|
-
it { should
|
42
|
-
it {
|
43
|
-
it { should
|
44
|
-
|
115
|
+
it { should have_db_columns(:name, :email, :type => "string") }
|
116
|
+
it { should_not have_db_columns(:name, :email, :type => "integer") }
|
117
|
+
it { should have_db_columns(:name, :email).type("string") }
|
118
|
+
it { should_not have_db_columns(:foo, :bar).type("string") }
|
45
119
|
|
120
|
+
it { should have_db_column(:name) }
|
121
|
+
it { should have_db_column(:id).type("integer").primary(true) }
|
122
|
+
it { should have_db_column(:id).type("integer").primary }
|
123
|
+
it { should have_db_column(:email).type("string").default(nil).precision(nil).limit(255).null(true).primary(false).scale(nil).sql_type('varchar(255)') }
|
124
|
+
it { should have_db_column(:email).type("string") }
|
125
|
+
it { should_not have_db_column(:email).type("integer") }
|
126
|
+
it { should have_db_column(:email).default(nil) }
|
127
|
+
it { should_not have_db_column(:email).default('foo') }
|
128
|
+
it { should have_db_column(:email).precision(nil) }
|
129
|
+
it { should_not have_db_column(:email).precision(10) }
|
130
|
+
it { should have_db_column(:email).limit(255) }
|
131
|
+
it { should_not have_db_column(:email).limit(254) }
|
132
|
+
it { should have_db_column(:email).null(true) }
|
133
|
+
it { should have_db_column(:email).null }
|
134
|
+
it { should_not have_db_column(:email).null(false) }
|
135
|
+
it { should have_db_column(:email).primary(false) }
|
136
|
+
it { should_not have_db_column(:email).primary }
|
137
|
+
it { should_not have_db_column(:email).primary(true) }
|
138
|
+
it { should have_db_column(:email).scale(nil) }
|
139
|
+
it { should_not have_db_column(:email).scale(2) }
|
140
|
+
it { should have_db_column(:email).sql_type('varchar(255)') }
|
141
|
+
it { should_not have_db_column(:email).sql_type('varchar(254)') }
|
142
|
+
it { should have_db_column(:email, :type => "string").limit(255) }
|
143
|
+
it { should_not have_db_column(:email, :type => "integer").limit(255) }
|
144
|
+
it { should have_db_column(:email, :type => "string", :default => nil, :precision => nil, :limit => 255,
|
145
|
+
:null => true, :primary => false, :scale => nil, :sql_type => 'varchar(255)') }
|
146
|
+
|
46
147
|
it { should require_acceptance_of(:eula) }
|
148
|
+
it { should_not require_acceptance_of(:name) }
|
149
|
+
it { should_not validate_acceptance_of(:name) }
|
150
|
+
|
151
|
+
it { should validate_acceptance_of(:eula) }
|
152
|
+
it { should validate_acceptance_of(:eula, :allow_nil => true) }
|
153
|
+
it { should_not validate_acceptance_of(:eula, :allow_nil => false) }
|
154
|
+
|
155
|
+
it { should validate_acceptance_of(:terms).accept(true) }
|
156
|
+
it { should validate_acceptance_of(:terms).allow_nil(false) }
|
157
|
+
it { should_not validate_acceptance_of(:terms).allow_nil }
|
158
|
+
it { should_not validate_acceptance_of(:terms, :accept => false) }
|
159
|
+
|
160
|
+
it "should rails error when calling allow_blank on validate_acceptance_of matcher" do
|
161
|
+
proc{ should validate_acceptance_of(:terms).allow_nil.allow_blank }.should raise_error(NoMethodError)
|
162
|
+
end
|
163
|
+
|
164
|
+
it { should validate_uniqueness_of(:email, :scoped_to => :name) }
|
47
165
|
it { should require_unique_attributes(:email, :scoped_to => :name) }
|
48
|
-
|
166
|
+
|
49
167
|
it { should ensure_length_is(:ssn, 9, :message => "Social Security Number is not the right length") }
|
168
|
+
it { should ensure_length_is(:ssn, 9).message("Social Security Number is not the right length") }
|
169
|
+
it { should_not ensure_length_is(:ssn, 9) }
|
170
|
+
it { should_not ensure_length_is(:ssn, 8).message("Social Security Number is not the right length") }
|
171
|
+
it { should_not ensure_length_is(:ssn, 10).message("Social Security Number is not the right length") }
|
172
|
+
|
173
|
+
it { should validate_length_of(:ssn, :is => 9).message("Social Security Number is not the right length") }
|
174
|
+
it { should validate_length_of(:ssn, :is => 9, :message => "Social Security Number is not the right length") }
|
175
|
+
|
50
176
|
it { should only_allow_numeric_values_for(:ssn) }
|
51
|
-
|
177
|
+
|
178
|
+
it { should validate_numericality_of(:ssn) }
|
179
|
+
it { should validate_numericality_of(:ssn).equal_to(123456789) }
|
180
|
+
it { should_not validate_numericality_of(:ssn, :equal_to => 123456780) }
|
181
|
+
|
52
182
|
it { should have_readonly_attributes(:name) }
|
53
|
-
|
54
|
-
it { should_not
|
183
|
+
it { should_not have_readonly_attributes(:foo) }
|
184
|
+
it { should_not have_readonly_attributes(:ssn) }
|
55
185
|
end
|
56
186
|
|
57
187
|
describe User do
|
@@ -65,9 +195,20 @@ describe User do
|
|
65
195
|
|
66
196
|
should_have_one :address
|
67
197
|
should_have_one :address, :dependent => :destroy
|
198
|
+
|
199
|
+
should_validate_associated(:posts)
|
200
|
+
should_validate_associated(:address)
|
201
|
+
should_validate_associated(:posts, :address)
|
202
|
+
should_not_validate_associated(:dogs)
|
68
203
|
|
69
|
-
should_have_indices :email, :name
|
204
|
+
should_have_indices :email, :name
|
70
205
|
should_have_index :age
|
206
|
+
should_have_index [:email, :name], :unique => true
|
207
|
+
should_have_index :age, :unique => false
|
208
|
+
|
209
|
+
should_not_have_index :phone
|
210
|
+
should_not_have_index :email, :unique => false
|
211
|
+
should_not_have_index :age, :unique => true
|
71
212
|
|
72
213
|
should_have_named_scope :old, :conditions => "age > 50"
|
73
214
|
should_have_named_scope :eighteen, :conditions => { :age => 18 }
|
@@ -80,28 +221,72 @@ describe User do
|
|
80
221
|
before(:each) do
|
81
222
|
@count = 2
|
82
223
|
end
|
83
|
-
should_have_named_scope "recent(@count)", :limit => 2
|
224
|
+
# should_have_named_scope "recent(@count)", :limit => 2
|
84
225
|
end
|
226
|
+
|
227
|
+
should_have_after_create_callback(:send_welcome_email)
|
228
|
+
should_not_have_after_save_callback(:send_welcome_email)
|
229
|
+
should_not_have_after_destroy_callback(:goodbye_jerk)
|
230
|
+
should_have_before_validation_on_update_callback(:some_weird_callback)
|
85
231
|
|
86
232
|
should_not_allow_values_for :email, "blah", "b lah"
|
87
233
|
should_allow_values_for :email, "a@b.com", "asdf@asdf.com"
|
88
|
-
|
89
|
-
should_ensure_value_in_range :age, 1..100
|
234
|
+
should_ensure_value_in_range :age, 2..100
|
90
235
|
should_protect_attributes :password
|
91
236
|
should_have_class_methods :find, :destroy
|
92
237
|
should_have_instance_methods :email, :age, :email=, :valid?
|
238
|
+
|
239
|
+
should_allow_mass_assignment_of :email
|
240
|
+
should_not_allow_mass_assignment_of :password
|
241
|
+
|
242
|
+
should_ensure_length_in_range :email, 2..100
|
243
|
+
|
244
|
+
should_validate_size_of :email, :minimum => 2
|
245
|
+
should_validate_size_of :email, :maximum => 100
|
246
|
+
should_validate_length_of :email, :in => 2..100
|
247
|
+
should_validate_length_of :email, :within => 2..100 , :allow_nil => false
|
248
|
+
should_validate_length_of :email, :within => 2..100, :allow_blank => false
|
249
|
+
|
250
|
+
should_not_validate_length_of :email, :is => 2
|
251
|
+
should_not_validate_length_of :email, :is => 100
|
252
|
+
should_not_validate_length_of :email, :within => 0..200
|
253
|
+
should_not_validate_length_of :email, :in => 2..100, :allow_nil => true
|
254
|
+
should_not_validate_length_of :email, :in => 2..100, :allow_blank => true
|
255
|
+
|
256
|
+
should_validate_confirmation_of :username, :email
|
257
|
+
should_not_validate_confirmation_of :ssn
|
93
258
|
|
94
259
|
should_have_db_columns :name, :email, :age
|
260
|
+
should_have_db_columns :name, :email, :type => "string"
|
261
|
+
|
95
262
|
should_have_db_column :name
|
96
263
|
should_have_db_column :id, :type => "integer", :primary => true
|
97
264
|
should_have_db_column :email, :type => "string", :default => nil, :precision => nil, :limit => 255,
|
98
265
|
:null => true, :primary => false, :scale => nil, :sql_type => 'varchar(255)'
|
99
|
-
|
266
|
+
|
100
267
|
should_require_acceptance_of :eula
|
268
|
+
should_validate_acceptance_of :eula
|
269
|
+
should_validate_acceptance_of :eula, :allow_nil => true
|
270
|
+
should_not_validate_acceptance_of :eula, :allow_nil => false
|
271
|
+
|
272
|
+
should_validate_acceptance_of :terms
|
273
|
+
should_validate_acceptance_of :terms, :accept => true
|
274
|
+
should_validate_acceptance_of :terms, :allow_nil => false
|
275
|
+
should_not_validate_acceptance_of :terms, :allow_nil => true
|
276
|
+
should_not_validate_acceptance_of :terms, :accept => false
|
277
|
+
|
278
|
+
should_not_validate_acceptance_of :name
|
279
|
+
should_not_require_acceptance_of :name
|
280
|
+
|
281
|
+
should_validate_uniqueness_of :email, :scoped_to => :name
|
101
282
|
should_require_unique_attributes :email, :scoped_to => :name
|
102
|
-
|
283
|
+
|
103
284
|
should_ensure_length_is :ssn, 9, :message => "Social Security Number is not the right length"
|
104
285
|
should_only_allow_numeric_values_for :ssn
|
105
|
-
|
286
|
+
|
287
|
+
should_validate_numericality_of :ssn
|
288
|
+
should_validate_numericality_of :ssn, :equal_to => 123456789
|
289
|
+
should_not_validate_numericality_of :ssn, :equal_to => 123456780
|
290
|
+
|
106
291
|
should_have_readonly_attributes :name
|
107
292
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "Custom Macros" do
|
4
|
+
before(:all) do
|
5
|
+
custom_macro = File.join(RAILS_ROOT, "spec", "remarkable_macros", "run_my_custom_macro.rb")
|
6
|
+
plugin_macro = File.join(RAILS_ROOT, "vendor", "plugins", "my_plugin", "remarkable_macros", "run_my_plugin_macro.rb")
|
7
|
+
|
8
|
+
[custom_macro, plugin_macro].each do |macro_file|
|
9
|
+
File.open(macro_file, "w") do |f|
|
10
|
+
f.puts("it 'should run my macro' do\t true.should be_true\tend")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
load File.expand_path(File.dirname(__FILE__) + '/../../lib/remarkable/rails.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
it { self.class.should respond_to(:should_run_my_custom_macro) }
|
18
|
+
it { should run_my_custom_macro }
|
19
|
+
|
20
|
+
it { self.class.should respond_to(:should_run_my_plugin_macro) }
|
21
|
+
it { should run_my_plugin_macro }
|
22
|
+
|
23
|
+
after(:all) do
|
24
|
+
FileUtils.rm(File.join(RAILS_ROOT, "spec", "remarkable_macros", "run_my_custom_macro.rb"), :force => true)
|
25
|
+
FileUtils.rm(File.join(RAILS_ROOT, "vendor", "plugins", "my_plugin", "remarkable_macros", "run_my_plugin_macro.rb"), :force => true)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "my own matcher" do
|
4
|
+
it { "abc".should first_three_letters_of_alphabet }
|
5
|
+
end
|
6
|
+
|
7
|
+
def first_three_letters_of_alphabet
|
8
|
+
simple_matcher "be the first three letters of alphabet" do |spec|
|
9
|
+
spec.should == "abc"
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
#
|
3
|
+
# describe "PrivateHelpers" do
|
4
|
+
# describe "get_options!" do
|
5
|
+
# it "remove opts from args" do
|
6
|
+
# args = [:a, :b, {}]
|
7
|
+
# get_options!(args)
|
8
|
+
# args.should == [:a, :b]
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# it "return wanted opts in order" do
|
12
|
+
# args = [{:one => 1, :two => 2}]
|
13
|
+
# one, two = get_options!(args, :one, :two)
|
14
|
+
# one.should == 1
|
15
|
+
# two.should == 2
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# it "raise ArgumentError if given unwanted option" do
|
19
|
+
# args = [{:one => 1, :two => 2}]
|
20
|
+
# lambda { get_options!(args, :one) }.should raise_error(ArgumentError)
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# class ::SomeModel; end
|
25
|
+
# describe "subject_class" do
|
26
|
+
# it "sniff the class constant from the test class" do
|
27
|
+
# self.should_receive(:described_type).and_return(SomeModel)
|
28
|
+
# subject_class.should == SomeModel
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
# end
|
@@ -4,6 +4,7 @@ class PostsController < ApplicationController
|
|
4
4
|
|
5
5
|
def index
|
6
6
|
@posts = @user.posts
|
7
|
+
@some_text = "foo bar"
|
7
8
|
|
8
9
|
respond_to do |format|
|
9
10
|
format.html # index.rhtml
|
@@ -19,6 +20,7 @@ class PostsController < ApplicationController
|
|
19
20
|
|
20
21
|
def show
|
21
22
|
@post = @user.posts.find(params[:id])
|
23
|
+
@false_flag = false
|
22
24
|
|
23
25
|
respond_to do |format|
|
24
26
|
format.html { render :layout => 'wide' }
|
@@ -2,6 +2,6 @@ class Address < ActiveRecord::Base
|
|
2
2
|
belongs_to :addressable, :polymorphic => true
|
3
3
|
validates_uniqueness_of :title, :scope => [:addressable_type, :addressable_id]
|
4
4
|
|
5
|
-
validates_length_of :zip, :minimum => 5
|
6
|
-
validates_numericality_of :zip
|
5
|
+
validates_length_of :zip, :minimum => 5, :allow_nil => true
|
6
|
+
validates_numericality_of :zip, :less_than => 20, :greater_than => 10
|
7
7
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Pets
|
2
|
+
class Dog < ActiveRecord::Base
|
3
|
+
belongs_to :user, :foreign_key => :owner_id
|
4
|
+
belongs_to :address
|
5
|
+
has_and_belongs_to_many :fleas, :join_table => :fleas
|
6
|
+
|
7
|
+
validates_numericality_of :age, :allow_blank => true, :only_integer => true, :odd => true, :greater_than_or_equal_to => 10
|
8
|
+
validates_numericality_of :owner_id, :allow_nil => true, :even => true, :less_than_or_equal_to => 10
|
9
|
+
|
10
|
+
validates_presence_of :owner_id
|
11
|
+
end
|
12
|
+
end
|