browsing_history 0.0.2
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 +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +89 -0
- data/.rubocop_todo.yml +28 -0
- data/.ruby-version +1 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +180 -0
- data/LICENSE +21 -0
- data/MIT-LICENSE +20 -0
- data/README.md +2 -0
- data/README.rdoc +3 -0
- data/Rakefile +28 -0
- data/browsing_history.gemspec +34 -0
- data/dump.rdb +1 -0
- data/lib/browsing_history/browser.rb +66 -0
- data/lib/browsing_history/configuration.rb +38 -0
- data/lib/browsing_history/error.rb +2 -0
- data/lib/browsing_history/historizable.rb +26 -0
- data/lib/browsing_history/history.rb +85 -0
- data/lib/browsing_history/storage.rb +44 -0
- data/lib/browsing_history/storages/active_record.rb +12 -0
- data/lib/browsing_history/storages/base.rb +40 -0
- data/lib/browsing_history/storages/redis.rb +113 -0
- data/lib/browsing_history/version.rb +3 -0
- data/lib/browsing_history.rb +12 -0
- data/lib/generators/active_record/migration_generator.rb +12 -0
- data/lib/generators/active_record/templates/migration.rb +15 -0
- data/lib/tasks/browsing_history_tasks.rake +4 -0
- data/spec/browsing_history/browser_spec.rb +156 -0
- data/spec/browsing_history/configration_spec.rb +16 -0
- data/spec/browsing_history/fixtures/article.rb +10 -0
- data/spec/browsing_history/fixtures/user.rb +10 -0
- data/spec/browsing_history/historizable_spec.rb +27 -0
- data/spec/browsing_history/history_spec.rb +273 -0
- data/spec/browsing_history/storage_spec.rb +45 -0
- data/spec/browsing_history/storages/base_spec.rb +35 -0
- data/spec/browsing_history/storages/redis_spec.rb +141 -0
- data/spec/browsing_history_spec.rb +4 -0
- data/spec/generator_spec.rb +34 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/test_app/README.rdoc +28 -0
- data/spec/test_app/Rakefile +6 -0
- data/spec/test_app/app/assets/images/.keep +0 -0
- data/spec/test_app/app/assets/javascripts/application.js +13 -0
- data/spec/test_app/app/assets/stylesheets/application.css +15 -0
- data/spec/test_app/app/controllers/application_controller.rb +10 -0
- data/spec/test_app/app/controllers/articles_controller.rb +17 -0
- data/spec/test_app/app/controllers/concerns/.keep +0 -0
- data/spec/test_app/app/helpers/application_helper.rb +2 -0
- data/spec/test_app/app/mailers/.keep +0 -0
- data/spec/test_app/app/models/.keep +0 -0
- data/spec/test_app/app/models/concerns/.keep +0 -0
- data/spec/test_app/app/views/layouts/application.html.erb +14 -0
- data/spec/test_app/bin/bundle +3 -0
- data/spec/test_app/bin/rails +4 -0
- data/spec/test_app/bin/rake +4 -0
- data/spec/test_app/bin/setup +29 -0
- data/spec/test_app/config/application.rb +19 -0
- data/spec/test_app/config/boot.rb +5 -0
- data/spec/test_app/config/database.yml +12 -0
- data/spec/test_app/config/environment.rb +5 -0
- data/spec/test_app/config/environments/development.rb +18 -0
- data/spec/test_app/config/environments/test.rb +21 -0
- data/spec/test_app/config/initializers/assets.rb +11 -0
- data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/test_app/config/initializers/cookies_serializer.rb +3 -0
- data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/test_app/config/initializers/inflections.rb +16 -0
- data/spec/test_app/config/initializers/mime_types.rb +4 -0
- data/spec/test_app/config/initializers/session_store.rb +3 -0
- data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/test_app/config/locales/en.yml +23 -0
- data/spec/test_app/config/routes.rb +2 -0
- data/spec/test_app/config/secrets.yml +5 -0
- data/spec/test_app/config.ru +4 -0
- data/spec/test_app/db/development.sqlite3 +0 -0
- data/spec/test_app/db/test.sqlite3 +0 -0
- data/spec/test_app/lib/assets/.keep +0 -0
- data/spec/test_app/log/.keep +0 -0
- data/spec/test_app/log/development.log +0 -0
- data/spec/test_app/log/test.log +0 -0
- data/spec/test_app/public/404.html +67 -0
- data/spec/test_app/public/422.html +67 -0
- data/spec/test_app/public/500.html +66 -0
- data/spec/test_app/public/favicon.ico +0 -0
- metadata +342 -0
@@ -0,0 +1,273 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fixtures/user'
|
3
|
+
require 'fixtures/article'
|
4
|
+
|
5
|
+
describe BrowsingHistory::History do
|
6
|
+
let(:user) { User.new }
|
7
|
+
let(:article) { Article.new }
|
8
|
+
let(:articles) { Array.new(50) { |i| Article.new(i) } }
|
9
|
+
let(:history) { described_class.new(browser: user, historizable: article) }
|
10
|
+
let(:invalid_object) { Struct.new(:_).new }
|
11
|
+
|
12
|
+
describe 'responses' do
|
13
|
+
describe 'instance_methods' do
|
14
|
+
subject { history }
|
15
|
+
|
16
|
+
it { is_expected.to respond_to(:browser) }
|
17
|
+
it { is_expected.to respond_to(:historizable) }
|
18
|
+
it { is_expected.to respond_to(:save) }
|
19
|
+
it { is_expected.to respond_to(:save!) }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'instance_methods' do
|
23
|
+
subject { described_class }
|
24
|
+
|
25
|
+
it { is_expected.to respond_to(:create) }
|
26
|
+
it { is_expected.to respond_to(:create!) }
|
27
|
+
it { is_expected.to respond_to(:where) }
|
28
|
+
it { is_expected.to respond_to(:count) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#save' do
|
33
|
+
let(:new_history_with_valid_objects) do
|
34
|
+
described_class.new(
|
35
|
+
browser: user,
|
36
|
+
historizable: article
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:new_history_with_invalid_browser) do
|
41
|
+
described_class.new(
|
42
|
+
browser: invalid_object,
|
43
|
+
historizable: article
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:new_history_with_invalid_historizable) do
|
48
|
+
described_class.new(
|
49
|
+
browser: user,
|
50
|
+
historizable: invalid_object
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when save with valid objects' do
|
55
|
+
it "should return #{described_class} instance" do
|
56
|
+
expect(
|
57
|
+
new_history_with_valid_objects.save
|
58
|
+
).to be(true)
|
59
|
+
|
60
|
+
expect(
|
61
|
+
new_history_with_valid_objects.save!
|
62
|
+
).to be(true)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when save with invalid object' do
|
67
|
+
it 'should return nil' do
|
68
|
+
expect(
|
69
|
+
new_history_with_invalid_browser.save
|
70
|
+
).to be_falsey
|
71
|
+
|
72
|
+
expect(
|
73
|
+
new_history_with_invalid_historizable.save
|
74
|
+
).to be_falsey
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when save! with invalid object' do
|
79
|
+
it 'should raise error' do
|
80
|
+
expect do
|
81
|
+
new_history_with_invalid_browser.save!
|
82
|
+
end.to raise_error(BrowsingHistory::History::ArgumentError)
|
83
|
+
|
84
|
+
expect do
|
85
|
+
new_history_with_invalid_historizable.save!
|
86
|
+
end.to raise_error(BrowsingHistory::History::ArgumentError)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'after save hitorizables' do
|
91
|
+
before(:each) do
|
92
|
+
articles.each do |article|
|
93
|
+
described_class.new(browser: user, historizable: article).save
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
let(:saved_articles) do
|
98
|
+
described_class.where(
|
99
|
+
browser: user,
|
100
|
+
historizable: article
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should equal original historizable' do
|
105
|
+
saved_articles.each_with_index do |saved_article, i|
|
106
|
+
original = articles.reverse[i]
|
107
|
+
|
108
|
+
expect(saved_article.id).to eq(original.id)
|
109
|
+
expect(saved_article.title).to eq(original.title)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'after save! hitorizables' do
|
115
|
+
before(:each) do
|
116
|
+
articles.each do |article|
|
117
|
+
described_class.new(browser: user, historizable: article).save!
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
let(:saved_articles) do
|
122
|
+
described_class.where(
|
123
|
+
browser: user,
|
124
|
+
historizable: article
|
125
|
+
)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should equal original historizable' do
|
129
|
+
saved_articles.each_with_index do |saved_article, i|
|
130
|
+
original = articles.reverse[i]
|
131
|
+
|
132
|
+
expect(saved_article.id).to eq(original.id)
|
133
|
+
expect(saved_article.title).to eq(original.title)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe '.create' do
|
140
|
+
context 'when create with valid objects' do
|
141
|
+
subject do
|
142
|
+
described_class.create(
|
143
|
+
browser: user,
|
144
|
+
historizable: article
|
145
|
+
)
|
146
|
+
end
|
147
|
+
it { is_expected.to be_a(described_class) }
|
148
|
+
|
149
|
+
subject do
|
150
|
+
described_class.create!(
|
151
|
+
browser: user,
|
152
|
+
historizable: article
|
153
|
+
)
|
154
|
+
end
|
155
|
+
it { is_expected.to be_a(described_class) }
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'when create with invalid object' do
|
159
|
+
it 'should return nil' do
|
160
|
+
expect(
|
161
|
+
described_class.create(
|
162
|
+
browser: invalid_object,
|
163
|
+
historizable: article
|
164
|
+
)
|
165
|
+
).to be_falsey
|
166
|
+
|
167
|
+
expect(
|
168
|
+
described_class.create(
|
169
|
+
browser: user,
|
170
|
+
historizable: invalid_object
|
171
|
+
)
|
172
|
+
).to be_falsey
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'when create! with invalid object' do
|
177
|
+
it 'should raise error' do
|
178
|
+
expect do
|
179
|
+
described_class.create!(
|
180
|
+
browser: invalid_object,
|
181
|
+
historizable: article
|
182
|
+
)
|
183
|
+
end.to raise_error(BrowsingHistory::History::ArgumentError)
|
184
|
+
|
185
|
+
expect do
|
186
|
+
described_class.create!(
|
187
|
+
browser: user,
|
188
|
+
historizable: invalid_object
|
189
|
+
)
|
190
|
+
end.to raise_error(BrowsingHistory::History::ArgumentError)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '.count' do
|
196
|
+
subject { described_class.current_storage.count(user, article) }
|
197
|
+
it { is_expected.to eq(0) }
|
198
|
+
end
|
199
|
+
|
200
|
+
describe '.where' do
|
201
|
+
it 'should default empty' do
|
202
|
+
expect(
|
203
|
+
BrowsingHistory::History.where(
|
204
|
+
browser: user,
|
205
|
+
historizable: article
|
206
|
+
)
|
207
|
+
).to be_empty
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'with limit option' do
|
211
|
+
before do
|
212
|
+
5.times do |i|
|
213
|
+
described_class.create(browser: user, historizable: Article.new(i))
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
let(:historizables) do
|
218
|
+
described_class.where(
|
219
|
+
browser: user,
|
220
|
+
historizable: article,
|
221
|
+
limit: 3
|
222
|
+
)
|
223
|
+
end
|
224
|
+
|
225
|
+
let(:historizables_excess_limit) do
|
226
|
+
described_class.where(
|
227
|
+
browser: user,
|
228
|
+
historizable: article,
|
229
|
+
limit: 100
|
230
|
+
)
|
231
|
+
end
|
232
|
+
|
233
|
+
it { expect(historizables).to be_a(Array) }
|
234
|
+
it { expect(historizables.size).to eq(3) }
|
235
|
+
|
236
|
+
it { expect(historizables_excess_limit).to be_a(Array) }
|
237
|
+
it { expect(historizables_excess_limit.size).to eq(5) }
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'with between option' do
|
241
|
+
before do
|
242
|
+
5.times.map.with_index(1) do |i|
|
243
|
+
described_class.create(browser: user, historizable: Article.new(i))
|
244
|
+
end
|
245
|
+
|
246
|
+
sleep(6)
|
247
|
+
described_class.create(browser: user, historizable: Article.new(100))
|
248
|
+
end
|
249
|
+
|
250
|
+
let(:historizables) do
|
251
|
+
described_class.where(
|
252
|
+
browser: user,
|
253
|
+
historizable: article,
|
254
|
+
between: Time.now..5.seconds.ago
|
255
|
+
)
|
256
|
+
end
|
257
|
+
|
258
|
+
let(:historizables_unhit) do
|
259
|
+
described_class.where(
|
260
|
+
browser: user,
|
261
|
+
historizable: article,
|
262
|
+
between: 1.day.ago..2.days.ago
|
263
|
+
)
|
264
|
+
end
|
265
|
+
|
266
|
+
it { expect(historizables).to be_a(Array) }
|
267
|
+
it { expect(historizables.size).to eq(1) }
|
268
|
+
|
269
|
+
it { expect(historizables_unhit).to be_a(Array) }
|
270
|
+
it { expect(historizables_unhit.size).to eq(0) }
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BrowsingHistory::Storage do
|
4
|
+
describe '#attach_storage' do
|
5
|
+
let(:default_storage) { :redis }
|
6
|
+
|
7
|
+
let(:include_class) do
|
8
|
+
Struct.new(:_) do
|
9
|
+
include BrowsingHistory::Storage
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:include_class_attached_activerecord) do
|
14
|
+
Struct.new(:_) do
|
15
|
+
include BrowsingHistory::Storage
|
16
|
+
attach_storage :active_record
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:include_class_invalid_storage) do
|
21
|
+
Struct.new(:_) do
|
22
|
+
include BrowsingHistory::Storage
|
23
|
+
attach_storage :invalid_storage
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should be attached redis storage default' do
|
28
|
+
expect(include_class.current_storage_type).to eql(default_storage)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should attached activerecord' do
|
32
|
+
expect(
|
33
|
+
include_class_attached_activerecord.current_storage_type
|
34
|
+
).to eql(:active_record)
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when passed invalid storage' do
|
38
|
+
it 'should raise error' do
|
39
|
+
expect do
|
40
|
+
include_class_invalid_storage
|
41
|
+
end.to raise_error(BrowsingHistory::Storage::InvalidStorage)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fixtures/user'
|
3
|
+
require 'fixtures/article'
|
4
|
+
|
5
|
+
describe BrowsingHistory::Storages::Base do
|
6
|
+
let(:user) { User.new }
|
7
|
+
let(:article) { Article.new }
|
8
|
+
let(:described_instance) { described_class.new(user, article) }
|
9
|
+
let(:test_options) { Hash.new }
|
10
|
+
|
11
|
+
before do
|
12
|
+
described_class.connect
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'io_methods' do
|
16
|
+
it 'should be defined on class' do
|
17
|
+
BrowsingHistory::Storages::IOMethods.each do |method|
|
18
|
+
expect(
|
19
|
+
described_class.respond_to?(method)
|
20
|
+
).to be(true)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should raise not overide error' do
|
25
|
+
BrowsingHistory::Storages::IOMethods.each do |method|
|
26
|
+
expect do
|
27
|
+
described_instance.send(method)
|
28
|
+
end.to raise_error(BrowsingHistory::Storages::NotOverideError)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '.connect' do
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fixtures/user'
|
3
|
+
require 'fixtures/article'
|
4
|
+
|
5
|
+
describe BrowsingHistory::Storages::Redis do
|
6
|
+
articles_size = 5
|
7
|
+
|
8
|
+
let(:user) { User.new }
|
9
|
+
let(:articles) do
|
10
|
+
articles_size.times.map.with_index(1) { |i| Article.new(i) }
|
11
|
+
end
|
12
|
+
let(:article) { articles.first }
|
13
|
+
|
14
|
+
let(:storage) do
|
15
|
+
Struct.new(:_) do
|
16
|
+
include BrowsingHistory::Storage
|
17
|
+
attach_storage :redis
|
18
|
+
end.current_storage
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'method_defined?' do
|
22
|
+
describe 'public_instance_methods' do
|
23
|
+
subject { storage.new(user, article) }
|
24
|
+
|
25
|
+
it { is_expected.to respond_to(:fetch) }
|
26
|
+
it { is_expected.to respond_to(:add) }
|
27
|
+
it { is_expected.to respond_to(:update) }
|
28
|
+
it { is_expected.to respond_to(:clear) }
|
29
|
+
it { is_expected.to respond_to(:interface) }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'private_instance_methods' do
|
33
|
+
subject { storage.private_instance_methods }
|
34
|
+
|
35
|
+
it { is_expected.to include(:history) }
|
36
|
+
it { is_expected.to include(:fetch_between) }
|
37
|
+
it { is_expected.to include(:clear_all) }
|
38
|
+
it { is_expected.to include(:clear_expiration) }
|
39
|
+
it { is_expected.to include(:score) }
|
40
|
+
it { is_expected.to include(:parse_between) }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'singleton_methods' do
|
44
|
+
subject { storage }
|
45
|
+
it { is_expected.to respond_to(:connect) }
|
46
|
+
it { is_expected.to respond_to(:default_options) }
|
47
|
+
it { is_expected.to respond_to(:default_connect_options) }
|
48
|
+
|
49
|
+
it { is_expected.to respond_to(:redis) }
|
50
|
+
it { is_expected.to respond_to(:set) }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#fetch' do
|
55
|
+
context 'when add 1 object' do
|
56
|
+
it 'should return articles' do
|
57
|
+
expect { storage.add(user, article) }
|
58
|
+
.to change { storage.fetch(user, article).size }.by(1)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when add #{articles_size} object" do
|
63
|
+
it 'should return articles' do
|
64
|
+
expect do
|
65
|
+
articles.each { |article| storage.add(user, article) }
|
66
|
+
end.to change { storage.fetch(user, article).size }.by(articles_size)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#add' do
|
72
|
+
let(:history_key) do
|
73
|
+
%(\
|
74
|
+
#{user.browser_type}/\
|
75
|
+
#{user.browser_id}/\
|
76
|
+
#{article.historizable_type}\
|
77
|
+
).delete(' ')
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when add 1 object' do
|
81
|
+
before { storage.add(user, article) }
|
82
|
+
it { expect(storage.redis.exists(history_key)).to be(true) }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#update' do
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#clear' do
|
90
|
+
before(:each) { articles.each { |article| storage.add(user, article) } }
|
91
|
+
|
92
|
+
it 'should clear 1 historizable' do
|
93
|
+
expect { storage.clear(user, article, article) }
|
94
|
+
.to change { storage.fetch(user, article).size }.by(-1)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should celar all historizables' do
|
98
|
+
expect { storage.clear(user, article, all: true) }
|
99
|
+
.to change { storage.fetch(user, article).size }.to(0)
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'and add 1 historizable after 6 seconds' do
|
103
|
+
before do
|
104
|
+
sleep(6)
|
105
|
+
storage.add(user, Article.new(100))
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should celar 5 historizables' do
|
109
|
+
expect { storage.clear(user, article, expiration: 5.seconds.ago) }
|
110
|
+
.to change { storage.fetch(user, article).size }.to(1)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#count' do
|
116
|
+
before(:each) { articles.each { |article| storage.add(user, article) } }
|
117
|
+
|
118
|
+
context "when exist #{articles_size} historizable" do
|
119
|
+
subject { storage.count(user, article) }
|
120
|
+
it { is_expected.to be(articles_size) }
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'and add 1 historizable after 6 seconds' do
|
124
|
+
before do
|
125
|
+
sleep(6)
|
126
|
+
storage.add(user, Article.new(100))
|
127
|
+
end
|
128
|
+
|
129
|
+
subject { storage.count(user, article, between: Time.now..5.seconds.ago) }
|
130
|
+
it { is_expected.to be(1) }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#interface' do
|
135
|
+
subject { storage.set }
|
136
|
+
it { is_expected.to be(Redis::SortedSet) }
|
137
|
+
end
|
138
|
+
|
139
|
+
describe '.connect' do
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'generator_spec'
|
3
|
+
require 'generator_spec/test_case'
|
4
|
+
|
5
|
+
require 'generators/active_record/migration_generator'
|
6
|
+
|
7
|
+
describe BrowsingHistory::MigrationGenerator, type: :generator do
|
8
|
+
include GeneratorSpec::TestCase
|
9
|
+
destination File.expand_path('tmp', __dir__)
|
10
|
+
|
11
|
+
after(:all) { prepare_destination } # cleanup the tmp directory
|
12
|
+
|
13
|
+
describe 'no options' do
|
14
|
+
before(:all) do
|
15
|
+
prepare_destination
|
16
|
+
run_generator
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'generates a migration for creating browsing_histories table' do
|
20
|
+
expect(destination_root).to have_structure do
|
21
|
+
directory 'db' do
|
22
|
+
directory 'migrate' do
|
23
|
+
migration 'create_browsing_histories' do
|
24
|
+
contains 'class CreateBrowsingHistories'
|
25
|
+
contains 'def up'
|
26
|
+
contains 'create_table :browsing_histories'
|
27
|
+
contains 'def down'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
ENV['RAILS_ENV'] ||= 'test'
|
2
|
+
ENV['DB'] ||= 'sqlite'
|
3
|
+
|
4
|
+
require 'pry'
|
5
|
+
require 'rails/all'
|
6
|
+
require 'rspec/rails'
|
7
|
+
require 'database_cleaner'
|
8
|
+
|
9
|
+
require 'browsing_history'
|
10
|
+
|
11
|
+
$LOAD_PATH.unshift File.expand_path(__dir__)
|
12
|
+
$LOAD_PATH.unshift File.expand_path('browsing_history', __dir__)
|
13
|
+
|
14
|
+
require File.expand_path('test_app/config/environment', __dir__)
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
redis = BrowsingHistory::History.storages[:redis].redis
|
18
|
+
|
19
|
+
config.mock_with :rspec
|
20
|
+
config.before(:suite) do
|
21
|
+
DatabaseCleaner[:redis].db = redis.client.id
|
22
|
+
DatabaseCleaner.strategy = :truncation
|
23
|
+
DatabaseCleaner.clean_with(:truncation)
|
24
|
+
end
|
25
|
+
|
26
|
+
config.before(:each) do
|
27
|
+
DatabaseCleaner.start
|
28
|
+
DatabaseCleaner.clean
|
29
|
+
redis.flushdb
|
30
|
+
end
|
31
|
+
|
32
|
+
config.after(:each) do
|
33
|
+
DatabaseCleaner.clean
|
34
|
+
redis.redis.quit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def random_string(length = 8)
|
39
|
+
(0...length).map { (65 + rand(26)).chr }.join
|
40
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|