montage_rails 0.3.2 → 0.4.1
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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -0
- data/Rakefile +28 -0
- data/lib/montage_rails/base/column.rb +57 -0
- data/lib/montage_rails/base.rb +406 -0
- data/lib/montage_rails/errors.rb +7 -0
- data/lib/montage_rails/log_subscriber.rb +48 -0
- data/lib/montage_rails/query_cache.rb +44 -0
- data/lib/montage_rails/railtie.rb +0 -0
- data/lib/montage_rails/relation.rb +88 -0
- data/lib/montage_rails/version.rb +3 -0
- data/lib/montage_rails.rb +57 -0
- data/lib/tasks/montage_rails_tasks.rake +4 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/actor.rb +3 -0
- data/test/dummy/app/models/movie.rb +30 -0
- data/test/dummy/app/models/studio.rb +3 -0
- data/test/dummy/app/models/test.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +25 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/montage.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +56 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +16 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/RAILS_ENV=development.log +0 -0
- data/test/dummy/log/development.log +1038 -0
- data/test/dummy/log/test.log +12368 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/montage_rails/base/column_test.rb +59 -0
- data/test/montage_rails/base_test.rb +375 -0
- data/test/montage_rails/query_cache_test.rb +68 -0
- data/test/montage_rails/relation_test.rb +114 -0
- data/test/montage_rails_test.rb +97 -0
- data/test/resources/actor_resource.rb +141 -0
- data/test/resources/movie_resource.rb +160 -0
- data/test/resources/studio_resource.rb +56 -0
- data/test/test_helper.rb +196 -0
- metadata +123 -3
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/404.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
62
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/422.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The change you wanted was rejected.</h1>
|
62
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/500.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
62
|
+
</div>
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
File without changes
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'montage_rails/base/column'
|
3
|
+
|
4
|
+
class MontageRails::Base::ColumnTest < Minitest::Test
|
5
|
+
context "#value_valid?" do
|
6
|
+
should "return false if the value is required and nil is passed in" do
|
7
|
+
@column = MontageRails::Base::Column.new("foo", "integer", true)
|
8
|
+
assert !@column.value_valid?(nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "return true if the value is required and a proper value is passed in" do
|
12
|
+
@column = MontageRails::Base::Column.new("foo", "integer", true)
|
13
|
+
assert @column.value_valid?(1)
|
14
|
+
end
|
15
|
+
|
16
|
+
should "return true if the value is not required and nil is passed in" do
|
17
|
+
@column = MontageRails::Base::Column.new("foo", "integer", false)
|
18
|
+
assert @column.value_valid?(nil)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "#coerce" do
|
23
|
+
should "not perform a coercion if the value is already in the right format" do
|
24
|
+
column = MontageRails::Base::Column.new("foo", "numeric")
|
25
|
+
Virtus::Attribute.expects(:build).never
|
26
|
+
assert_equal 4.0, column.coerce(4.0)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "coerce a float to a float" do
|
30
|
+
column = MontageRails::Base::Column.new("foo", "float")
|
31
|
+
assert_equal 4.0, column.coerce("4.0")
|
32
|
+
end
|
33
|
+
|
34
|
+
should "coerce an integer to an integer" do
|
35
|
+
column = MontageRails::Base::Column.new("foo", "float")
|
36
|
+
assert_equal 4, column.coerce("4")
|
37
|
+
end
|
38
|
+
|
39
|
+
should "coerce a date time to a date time" do
|
40
|
+
column = MontageRails::Base::Column.new("foo", "datetime")
|
41
|
+
assert_equal DateTime.new(2015, 4, 20), column.coerce("2015-04-20")
|
42
|
+
end
|
43
|
+
|
44
|
+
should "coerce an integer to an integer when the type is numeric" do
|
45
|
+
column = MontageRails::Base::Column.new("foo", "numeric")
|
46
|
+
assert_equal 4, column.coerce("4")
|
47
|
+
end
|
48
|
+
|
49
|
+
should "coerce a float to a float when the type is numeric" do
|
50
|
+
column = MontageRails::Base::Column.new("foo", "numeric")
|
51
|
+
assert_equal 4.0, column.coerce("4.0")
|
52
|
+
end
|
53
|
+
|
54
|
+
should "coerce a string to a string" do
|
55
|
+
column = MontageRails::Base::Column.new("foo", "float")
|
56
|
+
assert_equal "foo", column.coerce("foo")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,375 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'montage_rails/relation'
|
3
|
+
require 'montage_rails/base'
|
4
|
+
|
5
|
+
class MontageRails::BaseTest < MiniTest::Test
|
6
|
+
context "initialization" do
|
7
|
+
should "initialize all the variables with nil when nothing is passed in" do
|
8
|
+
@movie = Movie.new
|
9
|
+
|
10
|
+
assert_nil @movie.rank
|
11
|
+
assert_nil @movie.rating
|
12
|
+
assert_nil @movie.title
|
13
|
+
assert_nil @movie.votes
|
14
|
+
assert_nil @movie.year
|
15
|
+
end
|
16
|
+
|
17
|
+
should "initialize with the passed in parameters" do
|
18
|
+
@movie = Movie.new(MontageRails::MovieResource.to_hash)
|
19
|
+
|
20
|
+
assert_equal 4, @movie.rank
|
21
|
+
assert_equal 2.0, @movie.rating
|
22
|
+
assert_equal "The Jerk", @movie.title
|
23
|
+
assert_equal 500, @movie.votes
|
24
|
+
assert_equal 1983, @movie.year
|
25
|
+
end
|
26
|
+
|
27
|
+
should "set persisted to the value passed in if it is passed in" do
|
28
|
+
@movie = Movie.new(persisted: true)
|
29
|
+
|
30
|
+
assert @movie.persisted?
|
31
|
+
end
|
32
|
+
|
33
|
+
should "default persisted to false" do
|
34
|
+
@movie = Movie.new
|
35
|
+
|
36
|
+
assert !@movie.persisted?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "class setup" do
|
41
|
+
setup do
|
42
|
+
class FooBar < MontageRails::Base
|
43
|
+
self.table_name = "movies"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
should "allow the table_name to be overriden" do
|
48
|
+
assert_equal "movies", FooBar.table_name
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "callbacks" do
|
53
|
+
should "respond to the before_save callback and before_create callback when it's not persisted" do
|
54
|
+
@movie = Movie.new(MontageRails::MovieResource.to_hash)
|
55
|
+
|
56
|
+
@movie.save
|
57
|
+
|
58
|
+
assert_equal "FOO", @movie.before_save_var
|
59
|
+
assert_equal "BAR", @movie.before_create_var
|
60
|
+
end
|
61
|
+
|
62
|
+
should "only call the before_create callback if the record is not persisted" do
|
63
|
+
@movie = Movie.create(MontageRails::MovieResource.to_hash)
|
64
|
+
|
65
|
+
@movie.before_create_var = nil
|
66
|
+
@movie.before_save_var = nil
|
67
|
+
|
68
|
+
@movie.votes = 600
|
69
|
+
@movie.save
|
70
|
+
|
71
|
+
assert_nil @movie.before_create_var
|
72
|
+
assert_equal "FOO", @movie.before_save_var
|
73
|
+
end
|
74
|
+
|
75
|
+
should "call the before_create callback on creation" do
|
76
|
+
@movie = Movie.create(MontageRails::MovieResource.to_hash)
|
77
|
+
|
78
|
+
assert_equal "BAR", @movie.before_create_var
|
79
|
+
end
|
80
|
+
|
81
|
+
should "respond to the after_save callback and after_create callback when it's not persisted" do
|
82
|
+
@movie = Movie.new(MontageRails::MovieResource.to_hash)
|
83
|
+
|
84
|
+
@movie.save
|
85
|
+
|
86
|
+
assert_equal "AFTER SAVE", @movie.after_save_var
|
87
|
+
assert_equal "AFTER CREATE", @movie.after_create_var
|
88
|
+
end
|
89
|
+
|
90
|
+
should "only call the after_create callback if the record is not persisted" do
|
91
|
+
@movie = Movie.create(MontageRails::MovieResource.to_hash)
|
92
|
+
|
93
|
+
@movie.after_create_var = nil
|
94
|
+
@movie.after_save_var = nil
|
95
|
+
|
96
|
+
@movie.votes = 600
|
97
|
+
@movie.save
|
98
|
+
|
99
|
+
assert_nil @movie.after_create_var
|
100
|
+
assert_equal "AFTER SAVE", @movie.after_save_var
|
101
|
+
end
|
102
|
+
|
103
|
+
should "call the after_create callback on creation" do
|
104
|
+
@movie = Movie.create(MontageRails::MovieResource.to_hash)
|
105
|
+
|
106
|
+
assert_equal "AFTER CREATE", @movie.after_create_var
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "delegation" do
|
111
|
+
should "delegate the first query method called to a Relation object and return a relation" do
|
112
|
+
assert_equal MontageRails::Relation, Movie.where(foo: "bar").class
|
113
|
+
assert_equal MontageRails::Relation, Movie.limit(10).class
|
114
|
+
assert_equal MontageRails::Relation, Movie.offset(10).class
|
115
|
+
assert_equal MontageRails::Relation, Movie.order(foo: :asc).class
|
116
|
+
end
|
117
|
+
|
118
|
+
should "create finder methods for all the column names" do
|
119
|
+
assert Movie.respond_to?(:find_by_rank)
|
120
|
+
assert Movie.respond_to?(:find_by_title)
|
121
|
+
assert Movie.respond_to?(:find_by_votes)
|
122
|
+
assert Movie.respond_to?(:find_by_id)
|
123
|
+
assert Movie.respond_to?(:find_by_year)
|
124
|
+
assert Movie.respond_to?(:find_by_rating)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "column methods" do
|
129
|
+
setup do
|
130
|
+
@movie = Movie.new
|
131
|
+
end
|
132
|
+
|
133
|
+
should "respond to method names that correspond to column names" do
|
134
|
+
assert @movie.respond_to?(:rank)
|
135
|
+
assert @movie.respond_to?(:rating)
|
136
|
+
assert @movie.respond_to?(:title)
|
137
|
+
assert @movie.respond_to?(:votes)
|
138
|
+
assert @movie.respond_to?(:year)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context ".has_many" do
|
143
|
+
setup do
|
144
|
+
@movie = Movie.create(MontageRails::MovieResource.to_hash)
|
145
|
+
@actor = Actor.create(MontageRails::ActorResource.steve_martin)
|
146
|
+
@actor2 = Actor.create(MontageRails::ActorResource.mark_hamill)
|
147
|
+
end
|
148
|
+
|
149
|
+
should "define an instance method for the given table name" do
|
150
|
+
assert @movie.respond_to?(:actors)
|
151
|
+
|
152
|
+
assert_equal 1, @movie.actors.count
|
153
|
+
assert_equal @actor.attributes, @movie.actors.first.attributes
|
154
|
+
end
|
155
|
+
|
156
|
+
should "allow the resulting relation to be chainable" do
|
157
|
+
assert_equal @actor.attributes, @movie.actors.where(name: "Steve Martin").first.attributes
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when the table name has been overridden" do
|
161
|
+
setup do
|
162
|
+
class TestClass < MontageRails::Base
|
163
|
+
self.table_name = "movies"
|
164
|
+
|
165
|
+
has_many :actors
|
166
|
+
end
|
167
|
+
|
168
|
+
@test = TestClass.where(title: "The Jerk").first
|
169
|
+
end
|
170
|
+
|
171
|
+
should "use the new table name to define the methods" do
|
172
|
+
assert_equal "Steve Martin", @test.actors.first.name
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context ".belongs_to" do
|
178
|
+
should "define an instance method for the given table name" do
|
179
|
+
@movie = Movie.find_by_title("The Jerk")
|
180
|
+
@studio = Studio.create(name: "Universal")
|
181
|
+
|
182
|
+
assert @movie.respond_to?(:studio)
|
183
|
+
assert @movie.respond_to?(:studio=)
|
184
|
+
assert_equal @studio.attributes, @movie.studio.attributes
|
185
|
+
|
186
|
+
@movie.studio = @studio
|
187
|
+
@movie.save
|
188
|
+
|
189
|
+
assert_equal @studio.attributes, @movie.studio.attributes
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context ".columns" do
|
194
|
+
should "retrieve the column names from the database if they have not been already" do
|
195
|
+
Movie.columns.each_with_index do |column, index|
|
196
|
+
assert_equal column.name, Movie.columns[index].name
|
197
|
+
assert_equal column.type, Movie.columns[index].type
|
198
|
+
assert_equal column.required, Movie.columns[index].required
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
should "not call out to the database if the columns have already been retrieved" do
|
203
|
+
Movie.columns
|
204
|
+
|
205
|
+
MontageRails.connection.expects(:schemas).never
|
206
|
+
|
207
|
+
Movie.columns
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context ".create" do
|
212
|
+
should "save a new object and return an instance of the class" do
|
213
|
+
@movie = Movie.create(MontageRails::MovieResource.to_hash)
|
214
|
+
|
215
|
+
assert @movie.persisted?
|
216
|
+
assert_equal 4, @movie.rank
|
217
|
+
assert_equal 2.0, @movie.rating
|
218
|
+
assert_equal "The Jerk", @movie.title
|
219
|
+
assert_equal 600, @movie.votes
|
220
|
+
assert_equal 1983, @movie.year
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context ".find_or_initialize_by" do
|
225
|
+
context "when the document is found" do
|
226
|
+
should "return an instance of the document" do
|
227
|
+
@movie = Movie.find_or_initialize_by(title: "The Jerk")
|
228
|
+
|
229
|
+
assert @movie.persisted?
|
230
|
+
assert_equal 4, @movie.rank
|
231
|
+
assert_equal 2.0, @movie.rating
|
232
|
+
assert_equal "The Jerk", @movie.title
|
233
|
+
assert_equal 600, @movie.votes
|
234
|
+
assert_equal 1983, @movie.year
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context "when the document is not found" do
|
239
|
+
should "return a new instance of the document" do
|
240
|
+
@movie = Movie.find_or_initialize_by(title: "Foo")
|
241
|
+
|
242
|
+
assert !@movie.persisted?
|
243
|
+
assert_equal "Foo", @movie.title
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context ".all" do
|
249
|
+
setup do
|
250
|
+
@movies = Movie.all
|
251
|
+
end
|
252
|
+
|
253
|
+
should "fetch all the movies" do
|
254
|
+
refute @movies.empty?
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context ".column_names" do
|
259
|
+
setup do
|
260
|
+
@column_names = Movie.column_names
|
261
|
+
|
262
|
+
@expected = %w(id created_at updated_at studio_id rank rating title votes year)
|
263
|
+
end
|
264
|
+
|
265
|
+
should "return an array of strings that contains the column names" do
|
266
|
+
assert_equal @expected, @column_names
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context "#inspect" do
|
271
|
+
setup do
|
272
|
+
@inspect = Movie.inspect
|
273
|
+
end
|
274
|
+
|
275
|
+
should "return a Rails style formatted inspect string" do
|
276
|
+
assert_equal "Movie(id: text, created_at: datetime, updated_at: datetime, studio_id: text, rank: numeric, rating: numeric, title: text, votes: numeric, year: numeric)", @inspect
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
context "#attributes_valid?" do
|
281
|
+
should "return false if there is an invalid attribute" do
|
282
|
+
@movie = Movie.new(rank: nil, rating: 2.0, title: "Foo", votes: 1, year: 1983, studio_id: "19442e09-5c2d-4e5d-8f34-675570e81414")
|
283
|
+
|
284
|
+
assert !@movie.attributes_valid?
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context "#save" do
|
289
|
+
context "when valid attributes are provided" do
|
290
|
+
setup do
|
291
|
+
@movie = Movie.new(MontageRails::MovieResource.to_hash)
|
292
|
+
end
|
293
|
+
|
294
|
+
should "successfully save the document, return a copy of itself, and set persisted to true" do
|
295
|
+
@movie.save
|
296
|
+
|
297
|
+
assert @movie.persisted?
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
context "when valid attributes are not provided" do
|
302
|
+
setup do
|
303
|
+
@movie = Movie.new
|
304
|
+
end
|
305
|
+
|
306
|
+
should "not save the document and return nil" do
|
307
|
+
@movie.save
|
308
|
+
|
309
|
+
assert !@movie.persisted?
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
context "#update_attributes" do
|
315
|
+
setup do
|
316
|
+
@movie = Movie.create(MontageRails::MovieResource.to_hash)
|
317
|
+
end
|
318
|
+
|
319
|
+
context "when valid attributes are given" do
|
320
|
+
should "update the attributes and return a copy of self" do
|
321
|
+
@movie.update_attributes(votes: 600)
|
322
|
+
|
323
|
+
assert_equal 600, @movie.votes
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
context "when the document is not yet persisted and the attributes are valid" do
|
328
|
+
setup do
|
329
|
+
@movie = Movie.new
|
330
|
+
end
|
331
|
+
|
332
|
+
should "create a new document" do
|
333
|
+
@movie.update_attributes(MontageRails::MovieResource.to_hash)
|
334
|
+
|
335
|
+
assert @movie.persisted?
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context "when invalid attributes are given" do
|
340
|
+
should "not update any attributes and return false" do
|
341
|
+
assert !@movie.update_attributes(votes: nil)
|
342
|
+
|
343
|
+
assert_equal 600, @movie.votes
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
context "when none of the attributes have changed" do
|
348
|
+
should "not update the document" do
|
349
|
+
MontageRails.connection.expects(:update_document).never
|
350
|
+
@movie.update_attributes(MontageRails::MovieResource.update_body.shift)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
context "when only one, unchanged attribute is passed in" do
|
355
|
+
should "not update the document" do
|
356
|
+
MontageRails.connection.expects(:update_document).never
|
357
|
+
@movie.update_attributes(rank: 4)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
context "when two, unchanged attributes are passed in" do
|
362
|
+
should "not update the document" do
|
363
|
+
MontageRails.connection.expects(:update_document).never
|
364
|
+
@movie.update_attributes(rank: 4, rating: 2.0)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
context "when data types passed in don't match and attributes haven't changed" do
|
369
|
+
should "not update the document" do
|
370
|
+
MontageRails.connection.expects(:update_document).never
|
371
|
+
@movie.update_attributes(rank: "4", rating: "2.0")
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'montage_rails/query_cache'
|
3
|
+
|
4
|
+
class QueryCacheTest < Minitest::Test
|
5
|
+
context "#get_or_set_query" do
|
6
|
+
setup do
|
7
|
+
@meth = Struct.new(:foo)
|
8
|
+
@cache = MontageRails::QueryCache.new
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when the query is already cached" do
|
12
|
+
setup do
|
13
|
+
@cache.cache["foo/bar"] = "foobar"
|
14
|
+
end
|
15
|
+
|
16
|
+
should "not run the query, and return the cached value" do
|
17
|
+
@meth.expects(:foo).never
|
18
|
+
@cache.get_or_set_query("foo", "bar") do
|
19
|
+
@meth.foo
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when the query is not already cached, and set the cached value" do
|
25
|
+
should "run the query" do
|
26
|
+
@meth.expects(:foo).once.returns("bar")
|
27
|
+
@cache.get_or_set_query("foo", "bar") do
|
28
|
+
@meth.foo
|
29
|
+
end
|
30
|
+
|
31
|
+
assert_equal @cache.cache["foo/bar"], "bar"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "#clear" do
|
37
|
+
setup do
|
38
|
+
@meth = Struct.new(:foo)
|
39
|
+
@cache = MontageRails::QueryCache.new
|
40
|
+
end
|
41
|
+
|
42
|
+
should "clear the cache" do
|
43
|
+
@meth.stubs(:foo).once.returns("bar")
|
44
|
+
@cache.get_or_set_query("foo", "bar") { @meth.foo }
|
45
|
+
@cache.clear
|
46
|
+
|
47
|
+
assert @cache.cache.empty?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "#remove" do
|
52
|
+
setup do
|
53
|
+
@meth = Struct.new(:foo)
|
54
|
+
@meth.stubs(:foo).returns("bar")
|
55
|
+
@cache = MontageRails::QueryCache.new
|
56
|
+
@cache.get_or_set_query("foo", "bar") { @meth.foo }
|
57
|
+
end
|
58
|
+
|
59
|
+
should "remove the cache key and return the cached value if the key exists" do
|
60
|
+
assert_equal "bar", @cache.remove("foo/bar")
|
61
|
+
assert_nil @cache.cache["foo/bar"]
|
62
|
+
end
|
63
|
+
|
64
|
+
should "return nil if the key does not exist" do
|
65
|
+
assert_nil @cache.remove("foobar")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|