unread 0.10.0 → 0.10.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/lib/unread/version.rb +1 -1
- data/unread.gemspec +8 -6
- metadata +21 -46
- data/spec/app/models/customer.rb +0 -2
- data/spec/app/models/different_reader.rb +0 -5
- data/spec/app/models/document.rb +0 -4
- data/spec/app/models/email.rb +0 -2
- data/spec/app/models/multi_level_sti_readable.rb +0 -2
- data/spec/app/models/reader.rb +0 -12
- data/spec/app/models/sti_reader.rb +0 -3
- data/spec/database.yml +0 -12
- data/spec/spec_helper.rb +0 -82
- data/spec/support/matchers/perform_queries.rb +0 -19
- data/spec/support/query_counter.rb +0 -17
- data/spec/support/spec_migration.rb +0 -23
- data/spec/support/timecop.rb +0 -3
- data/spec/unread/base_spec.rb +0 -61
- data/spec/unread/garbage_collector_spec.rb +0 -52
- data/spec/unread/read_mark_spec.rb +0 -11
- data/spec/unread/readable_spec.rb +0 -345
- data/spec/unread/reader_scopes_spec.rb +0 -9
- data/spec/unread/reader_spec.rb +0 -181
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05b6ec999b0b08aecbed6fc07c6e1d8e24fa5220d9b360b1fb6a1aa7293cbadc
|
4
|
+
data.tar.gz: be06fff51e62ecdaeddb2d5d86e89c950c3080db70dbed8b4736d976e17ab1a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b0c1ac98cdf02095d66c6b77959a039083f5dc9e0a5d350aff8274ba9d6589cf873a46872a32c9a09080bc52f5dce4ab4fcf9450fbe0f4088f2efe6bec80224
|
7
|
+
data.tar.gz: '0879f93f42eee16f150e64bce7a1271dce8dc5c728f1ece62d7da2ed8c47d7d034c98a7a3619564fb6f8e4a4d35e7e111d123c0dad6e7e0234328e73b47321da'
|
data/lib/unread/version.rb
CHANGED
data/unread.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
4
|
require "unread/version"
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
@@ -13,15 +14,16 @@ Gem::Specification.new do |s|
|
|
13
14
|
s.description = %q{This gem creates a scope for unread objects and adds methods to mark objects as read }
|
14
15
|
s.required_ruby_version = '>= 2.2'
|
15
16
|
|
16
|
-
s.
|
17
|
-
|
18
|
-
|
19
|
-
s.
|
20
|
-
s.executables =
|
17
|
+
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
s.bindir = "exe"
|
21
|
+
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
22
|
s.require_paths = ["lib"]
|
22
23
|
|
23
24
|
s.add_dependency 'activerecord', '>= 3'
|
24
25
|
|
26
|
+
s.add_development_dependency 'bundler'
|
25
27
|
s.add_development_dependency 'rake'
|
26
28
|
s.add_development_dependency 'timecop'
|
27
29
|
s.add_development_dependency 'sqlite3'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unread
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Georg Ledermann
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,8 +182,7 @@ description: 'This gem creates a scope for unread objects and adds methods to ma
|
|
168
182
|
objects as read '
|
169
183
|
email:
|
170
184
|
- mail@georg-ledermann.de
|
171
|
-
executables:
|
172
|
-
- console
|
185
|
+
executables: []
|
173
186
|
extensions: []
|
174
187
|
extra_rdoc_files: []
|
175
188
|
files:
|
@@ -201,25 +214,6 @@ files:
|
|
201
214
|
- lib/unread/reader.rb
|
202
215
|
- lib/unread/reader_scopes.rb
|
203
216
|
- lib/unread/version.rb
|
204
|
-
- spec/app/models/customer.rb
|
205
|
-
- spec/app/models/different_reader.rb
|
206
|
-
- spec/app/models/document.rb
|
207
|
-
- spec/app/models/email.rb
|
208
|
-
- spec/app/models/multi_level_sti_readable.rb
|
209
|
-
- spec/app/models/reader.rb
|
210
|
-
- spec/app/models/sti_reader.rb
|
211
|
-
- spec/database.yml
|
212
|
-
- spec/spec_helper.rb
|
213
|
-
- spec/support/matchers/perform_queries.rb
|
214
|
-
- spec/support/query_counter.rb
|
215
|
-
- spec/support/spec_migration.rb
|
216
|
-
- spec/support/timecop.rb
|
217
|
-
- spec/unread/base_spec.rb
|
218
|
-
- spec/unread/garbage_collector_spec.rb
|
219
|
-
- spec/unread/read_mark_spec.rb
|
220
|
-
- spec/unread/readable_spec.rb
|
221
|
-
- spec/unread/reader_scopes_spec.rb
|
222
|
-
- spec/unread/reader_spec.rb
|
223
217
|
- unread.gemspec
|
224
218
|
homepage: https://github.com/ledermann/unread
|
225
219
|
licenses:
|
@@ -240,28 +234,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
240
234
|
- !ruby/object:Gem::Version
|
241
235
|
version: '0'
|
242
236
|
requirements: []
|
243
|
-
rubyforge_project:
|
244
|
-
rubygems_version: 2.7.
|
237
|
+
rubyforge_project:
|
238
|
+
rubygems_version: 2.7.6
|
245
239
|
signing_key:
|
246
240
|
specification_version: 4
|
247
241
|
summary: Manages read/unread status of ActiveRecord objects
|
248
|
-
test_files:
|
249
|
-
- spec/app/models/customer.rb
|
250
|
-
- spec/app/models/different_reader.rb
|
251
|
-
- spec/app/models/document.rb
|
252
|
-
- spec/app/models/email.rb
|
253
|
-
- spec/app/models/multi_level_sti_readable.rb
|
254
|
-
- spec/app/models/reader.rb
|
255
|
-
- spec/app/models/sti_reader.rb
|
256
|
-
- spec/database.yml
|
257
|
-
- spec/spec_helper.rb
|
258
|
-
- spec/support/matchers/perform_queries.rb
|
259
|
-
- spec/support/query_counter.rb
|
260
|
-
- spec/support/spec_migration.rb
|
261
|
-
- spec/support/timecop.rb
|
262
|
-
- spec/unread/base_spec.rb
|
263
|
-
- spec/unread/garbage_collector_spec.rb
|
264
|
-
- spec/unread/read_mark_spec.rb
|
265
|
-
- spec/unread/readable_spec.rb
|
266
|
-
- spec/unread/reader_scopes_spec.rb
|
267
|
-
- spec/unread/reader_spec.rb
|
242
|
+
test_files: []
|
data/spec/app/models/customer.rb
DELETED
data/spec/app/models/document.rb
DELETED
data/spec/app/models/email.rb
DELETED
data/spec/app/models/reader.rb
DELETED
data/spec/database.yml
DELETED
data/spec/spec_helper.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'simplecov'
|
2
|
-
require 'coveralls'
|
3
|
-
|
4
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
5
|
-
SimpleCov::Formatter::HTMLFormatter,
|
6
|
-
Coveralls::SimpleCov::Formatter
|
7
|
-
])
|
8
|
-
SimpleCov.start do
|
9
|
-
add_filter '/spec/'
|
10
|
-
end
|
11
|
-
|
12
|
-
require 'timecop'
|
13
|
-
require 'unread'
|
14
|
-
require 'generators/unread/migration/templates/migration.rb'
|
15
|
-
|
16
|
-
require 'app/models/reader'
|
17
|
-
require 'app/models/different_reader'
|
18
|
-
require 'app/models/customer'
|
19
|
-
require 'app/models/sti_reader'
|
20
|
-
require 'app/models/document'
|
21
|
-
require 'app/models/email'
|
22
|
-
require 'app/models/multi_level_sti_readable'
|
23
|
-
|
24
|
-
# Requires supporting ruby files with custom matchers and macros, etc,
|
25
|
-
# in spec/support/ and its subdirectories.
|
26
|
-
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
|
27
|
-
|
28
|
-
# This file was generated by the `rspec --init` command. Conventionally, all
|
29
|
-
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
30
|
-
# Require this file using `require "spec_helper"` to ensure that it is only
|
31
|
-
# loaded once.
|
32
|
-
#
|
33
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
34
|
-
RSpec.configure do |config|
|
35
|
-
# Run specs in random order to surface order dependencies. If you find an
|
36
|
-
# order dependency and want to debug it, you can fix the order by providing
|
37
|
-
# the seed, which is printed after each run.
|
38
|
-
# --seed 1234
|
39
|
-
# config.order = 'random'
|
40
|
-
|
41
|
-
config.before :each do
|
42
|
-
clear_db
|
43
|
-
end
|
44
|
-
|
45
|
-
config.after :each do
|
46
|
-
Timecop.return
|
47
|
-
end
|
48
|
-
|
49
|
-
config.after :suite do
|
50
|
-
UnreadMigration.down
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
if I18n.respond_to?(:enforce_available_locales=)
|
55
|
-
I18n.enforce_available_locales = false
|
56
|
-
end
|
57
|
-
|
58
|
-
def setup_db
|
59
|
-
configs = YAML.load_file('spec/database.yml')
|
60
|
-
ActiveRecord::Base.configurations = configs
|
61
|
-
|
62
|
-
db_name = ENV['DB'] || 'sqlite'
|
63
|
-
|
64
|
-
puts "Testing with ActiveRecord #{ActiveRecord::VERSION::STRING} on #{db_name}"
|
65
|
-
|
66
|
-
ActiveRecord::Base.establish_connection(db_name.to_sym)
|
67
|
-
ActiveRecord::Base.default_timezone = :utc
|
68
|
-
ActiveRecord::Migration.verbose = false
|
69
|
-
|
70
|
-
UnreadMigration.up
|
71
|
-
SpecMigration.up
|
72
|
-
end
|
73
|
-
|
74
|
-
def clear_db
|
75
|
-
Reader.delete_all
|
76
|
-
DifferentReader.delete_all
|
77
|
-
StiReader.delete_all
|
78
|
-
Email.delete_all
|
79
|
-
ReadMark.delete_all
|
80
|
-
end
|
81
|
-
|
82
|
-
setup_db
|
@@ -1,19 +0,0 @@
|
|
1
|
-
RSpec::Matchers.define :perform_queries do |expected|
|
2
|
-
supports_block_expectations
|
3
|
-
|
4
|
-
match do |block|
|
5
|
-
query_count(&block) == expected
|
6
|
-
end
|
7
|
-
|
8
|
-
failure_message do |actual|
|
9
|
-
"Expected to run #{expected} queries, got #{@counter.query_count}"
|
10
|
-
end
|
11
|
-
|
12
|
-
def query_count(&block)
|
13
|
-
@counter = ActiveRecord::QueryCounter.new
|
14
|
-
ActiveSupport::Notifications.subscribe('sql.active_record', @counter.to_proc)
|
15
|
-
yield
|
16
|
-
ActiveSupport::Notifications.unsubscribe(@counter.to_proc)
|
17
|
-
@counter.query_count
|
18
|
-
end
|
19
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
class QueryCounter
|
3
|
-
attr_reader :query_count
|
4
|
-
|
5
|
-
def initialize
|
6
|
-
@query_count = 0
|
7
|
-
end
|
8
|
-
|
9
|
-
def to_proc
|
10
|
-
lambda(&method(:callback))
|
11
|
-
end
|
12
|
-
|
13
|
-
def callback(name, start, finish, message_id, values)
|
14
|
-
@query_count += 1 unless %w(CACHE SCHEMA).include?(values[:name]) || values[:sql] =~ /^begin/i || values[:sql] =~ /^commit/i
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
class SpecMigration < Unread::MIGRATION_BASE_CLASS
|
2
|
-
def self.up
|
3
|
-
create_table Reader, primary_key: 'number', force: true do |t|
|
4
|
-
t.string :name
|
5
|
-
end
|
6
|
-
|
7
|
-
create_table DifferentReader, primary_key: 'number', force: true do |t|
|
8
|
-
t.string :name
|
9
|
-
end
|
10
|
-
|
11
|
-
create_table Customer, force: true do |t|
|
12
|
-
t.string :type
|
13
|
-
end
|
14
|
-
|
15
|
-
create_table Document, primary_key: 'uid', force: true do |t|
|
16
|
-
t.string :type
|
17
|
-
t.string :subject
|
18
|
-
t.text :content
|
19
|
-
t.datetime :created_at
|
20
|
-
t.datetime :updated_at
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
data/spec/support/timecop.rb
DELETED
data/spec/unread/base_spec.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Unread::Base do
|
4
|
-
before :each do
|
5
|
-
@email = Email.create!
|
6
|
-
wait
|
7
|
-
@reader = Reader.create! name: 'John'
|
8
|
-
end
|
9
|
-
|
10
|
-
describe :acts_as_reader do
|
11
|
-
it "should create global read mark" do
|
12
|
-
expect(@reader.read_marks.count).to eq 1
|
13
|
-
expect(@reader.read_marks.global.count).to eq 1
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should define association for ReadMark" do
|
17
|
-
expect(@reader.read_marks.first.reader).to eq(@reader)
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should reset read_marks for created reader" do
|
21
|
-
expect(Email.unread_by(@reader)).to be_empty
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should memoize read_mark_global" do
|
25
|
-
expect {
|
26
|
-
rm1 = @reader.read_mark_global(Email)
|
27
|
-
rm2 = @reader.read_mark_global(Email)
|
28
|
-
}.to perform_queries(1)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should be idempotent" do
|
32
|
-
expect {
|
33
|
-
Reader.acts_as_reader
|
34
|
-
Reader.acts_as_reader
|
35
|
-
Reader.acts_as_reader
|
36
|
-
}.to_not change { ReadMark.reader_classes }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
describe :acts_as_readable do
|
41
|
-
it "should define association" do
|
42
|
-
expect(@email.read_marks.count).to eq 0
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should add class to ReadMark.readable_classes" do
|
46
|
-
expect(ReadMark.readable_classes).to eq [ Document ]
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should use default options" do
|
50
|
-
expect(Email.readable_options).to eq({ on: :updated_at })
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should be idempotent" do
|
54
|
-
expect {
|
55
|
-
Document.acts_as_readable
|
56
|
-
Document.acts_as_readable
|
57
|
-
Document.acts_as_readable
|
58
|
-
}.to_not change { ReadMark.readable_classes }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Unread::GarbageCollector do
|
4
|
-
before :each do
|
5
|
-
@reader = Reader.create! name: 'David'
|
6
|
-
@other_reader = Reader.create name: 'Matz'
|
7
|
-
@sti_reader = StiReader.create!
|
8
|
-
wait
|
9
|
-
@email1 = Email.create!
|
10
|
-
wait
|
11
|
-
@email2 = MultiLevelStiReadable.create!
|
12
|
-
end
|
13
|
-
|
14
|
-
describe :run! do
|
15
|
-
it "should delete all single read marks" do
|
16
|
-
expect(@reader.read_marks.single.count).to eq 0
|
17
|
-
|
18
|
-
@email1.mark_as_read! for: @reader
|
19
|
-
|
20
|
-
expect(Email.unread_by(@reader)).to eq [@email2]
|
21
|
-
expect(@reader.read_marks.single.count).to eq 1
|
22
|
-
|
23
|
-
Unread::GarbageCollector.new(Email).run!
|
24
|
-
|
25
|
-
@reader.reload
|
26
|
-
expect(@reader.read_marks.single.count).to eq 0
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should reset if all objects are read" do
|
30
|
-
@email1.mark_as_read! for: @reader
|
31
|
-
@email2.mark_as_read! for: @reader
|
32
|
-
|
33
|
-
expect(@reader.read_marks.single.count).to eq 2
|
34
|
-
|
35
|
-
Unread::GarbageCollector.new(Email).run!
|
36
|
-
|
37
|
-
expect(@reader.read_marks.single.count).to eq 0
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should not delete read marks from other readables" do
|
41
|
-
other_read_mark = @reader.read_marks.create! do |rm|
|
42
|
-
rm.readable_type = 'Foo'
|
43
|
-
rm.readable_id = 42
|
44
|
-
rm.timestamp = 5.years.ago
|
45
|
-
end
|
46
|
-
|
47
|
-
Unread::GarbageCollector.new(Email).run!
|
48
|
-
|
49
|
-
expect(ReadMark.exists?(other_read_mark.id)).to be_truthy
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ReadMark do
|
4
|
-
it "should have reader_class" do
|
5
|
-
expect(ReadMark.reader_classes).to eq [Reader, DifferentReader, StiReader]
|
6
|
-
end
|
7
|
-
|
8
|
-
it "should have readable_classes" do
|
9
|
-
expect(ReadMark.readable_classes).to eq [Document]
|
10
|
-
end
|
11
|
-
end
|
@@ -1,345 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Unread::Readable do
|
4
|
-
before :each do
|
5
|
-
@reader = Reader.create! name: 'David'
|
6
|
-
@other_reader = Reader.create name: 'Matz'
|
7
|
-
@sti_reader = StiReader.create!
|
8
|
-
wait
|
9
|
-
@email1 = Email.create!
|
10
|
-
wait
|
11
|
-
@email2 = MultiLevelStiReadable.create!
|
12
|
-
end
|
13
|
-
|
14
|
-
describe :unread_by do
|
15
|
-
it "should return all objects" do
|
16
|
-
expect(Email.unread_by(@reader)).to eq [@email1, @email2]
|
17
|
-
expect(Email.unread_by(@other_reader)).to eq [@email1, @email2]
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should return unread records" do
|
21
|
-
@email1.mark_as_read! for: @reader
|
22
|
-
|
23
|
-
expect(Email.unread_by(@reader)).to eq [@email2]
|
24
|
-
expect(Email.unread_by(@reader).count).to eq 1
|
25
|
-
|
26
|
-
expect(Email.unread_by(@other_reader)).to eq [@email1, @email2]
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should return empty array directly after marking all as read" do
|
30
|
-
Email.mark_as_read! :all, for: @reader
|
31
|
-
expect(Email.unread_by(@reader)).to eq([])
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should not allow invalid parameter" do
|
35
|
-
[ 42, nil, 'foo', :foo, {} ].each do |not_a_reader|
|
36
|
-
expect {
|
37
|
-
Email.unread_by(not_a_reader)
|
38
|
-
}.to raise_error(ArgumentError)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should not allow unsaved reader" do
|
43
|
-
unsaved_reader = Reader.new
|
44
|
-
|
45
|
-
expect {
|
46
|
-
Email.unread_by(unsaved_reader)
|
47
|
-
}.to raise_error(ArgumentError)
|
48
|
-
end
|
49
|
-
|
50
|
-
describe "should work without any read_marks" do
|
51
|
-
before do
|
52
|
-
ReadMark.delete_all
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should return all objects" do
|
56
|
-
expect(Email.unread_by(@reader)).to eq [@email1, @email2]
|
57
|
-
expect(Email.unread_by(@other_reader)).to eq [@email1, @email2]
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should return unread records" do
|
61
|
-
@email1.mark_as_read! for: @reader
|
62
|
-
|
63
|
-
expect(Email.unread_by(@reader)).to eq [@email2]
|
64
|
-
expect(Email.unread_by(@reader).count).to eq 1
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should not allow invalid parameter" do
|
68
|
-
[ 42, nil, 'foo', :foo, {} ].each do |not_a_reader|
|
69
|
-
expect {
|
70
|
-
Email.unread_by(not_a_reader)
|
71
|
-
}.to raise_error(ArgumentError)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should not allow unsaved reader" do
|
76
|
-
unsaved_reader = Reader.new
|
77
|
-
|
78
|
-
expect {
|
79
|
-
Email.unread_by(unsaved_reader)
|
80
|
-
}.to raise_error(ArgumentError)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
describe :read_by do
|
86
|
-
it "should return an empty array" do
|
87
|
-
expect(Email.read_by(@reader)).to be_empty
|
88
|
-
expect(Email.read_by(@other_reader)).to be_empty
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should return read records" do
|
92
|
-
@email1.mark_as_read! for: @reader
|
93
|
-
|
94
|
-
expect(Email.read_by(@reader)).to eq [@email1]
|
95
|
-
expect(Email.read_by(@reader).count).to eq 1
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should return all records when all read" do
|
99
|
-
Email.mark_as_read! :all, for: @reader
|
100
|
-
|
101
|
-
expect(Email.read_by(@reader)).to eq [@email1, @email2]
|
102
|
-
end
|
103
|
-
|
104
|
-
it "should not allow invalid parameter" do
|
105
|
-
[ 42, nil, 'foo', :foo, {} ].each do |not_a_reader|
|
106
|
-
expect {
|
107
|
-
Email.read_by(not_a_reader)
|
108
|
-
}.to raise_error(ArgumentError)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should not allow unsaved reader" do
|
113
|
-
unsaved_reader = Reader.new
|
114
|
-
|
115
|
-
expect {
|
116
|
-
Email.read_by(unsaved_reader)
|
117
|
-
}.to raise_error(ArgumentError)
|
118
|
-
end
|
119
|
-
|
120
|
-
describe "should work without any read_marks" do
|
121
|
-
before do
|
122
|
-
ReadMark.delete_all
|
123
|
-
end
|
124
|
-
|
125
|
-
it "should return an empty array" do
|
126
|
-
expect(Email.read_by(@reader)).to be_empty
|
127
|
-
expect(Email.read_by(@other_reader)).to be_empty
|
128
|
-
end
|
129
|
-
|
130
|
-
it "should return read records" do
|
131
|
-
@email1.mark_as_read! for: @reader
|
132
|
-
|
133
|
-
expect(Email.read_by(@reader)).to eq [@email1]
|
134
|
-
expect(Email.read_by(@reader).count).to eq 1
|
135
|
-
end
|
136
|
-
|
137
|
-
it "should return all records when all read" do
|
138
|
-
Email.mark_as_read! :all, for: @reader
|
139
|
-
|
140
|
-
expect(Email.read_by(@reader)).to eq [@email1, @email2]
|
141
|
-
end
|
142
|
-
|
143
|
-
it "should not allow invalid parameter" do
|
144
|
-
[ 42, nil, 'foo', :foo, {} ].each do |not_a_reader|
|
145
|
-
expect {
|
146
|
-
Email.read_by(not_a_reader)
|
147
|
-
}.to raise_error(ArgumentError)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
it "should not allow unsaved reader" do
|
152
|
-
unsaved_reader = Reader.new
|
153
|
-
|
154
|
-
expect {
|
155
|
-
Email.read_by(unsaved_reader)
|
156
|
-
}.to raise_error(ArgumentError)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
describe :with_read_marks_for do
|
162
|
-
it "should return readables" do
|
163
|
-
expect(Email.with_read_marks_for(@reader).to_a).to eq([@email1, @email2])
|
164
|
-
end
|
165
|
-
|
166
|
-
it "should be countable" do
|
167
|
-
expect(Email.with_read_marks_for(@reader).count(:uid)).to eq(2)
|
168
|
-
end
|
169
|
-
|
170
|
-
it "should not allow invalid parameter" do
|
171
|
-
[ 42, nil, 'foo', :foo, {} ].each do |not_a_reader|
|
172
|
-
expect {
|
173
|
-
Email.with_read_marks_for(not_a_reader)
|
174
|
-
}.to raise_error(ArgumentError)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
it "should not allow unsaved reader" do
|
179
|
-
unsaved_reader = Reader.new
|
180
|
-
|
181
|
-
expect {
|
182
|
-
Email.with_read_marks_for(unsaved_reader)
|
183
|
-
}.to raise_error(ArgumentError)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
describe :unread? do
|
188
|
-
it "should recognize unread object" do
|
189
|
-
expect(@email1.unread?(@reader)).to be_truthy
|
190
|
-
expect(@email1.unread?(@other_reader)).to be_truthy
|
191
|
-
end
|
192
|
-
|
193
|
-
it "should handle updating object" do
|
194
|
-
@email1.mark_as_read! for: @reader
|
195
|
-
wait
|
196
|
-
expect(@email1.unread?(@reader)).to be_falsey
|
197
|
-
|
198
|
-
@email1.update_attributes! subject: 'changed'
|
199
|
-
expect(@email1.unread?(@reader)).to be_truthy
|
200
|
-
end
|
201
|
-
|
202
|
-
it "should raise error for invalid argument" do
|
203
|
-
expect {
|
204
|
-
@email1.unread?(42)
|
205
|
-
}.to raise_error(ArgumentError)
|
206
|
-
end
|
207
|
-
|
208
|
-
it "should work with eager-loaded read marks" do
|
209
|
-
@email1.mark_as_read! for: @reader
|
210
|
-
|
211
|
-
expect {
|
212
|
-
emails = Email.with_read_marks_for(@reader).to_a
|
213
|
-
|
214
|
-
expect(emails[0].unread?(@reader)).to be_falsey
|
215
|
-
expect(emails[1].unread?(@reader)).to be_truthy
|
216
|
-
}.to perform_queries(1)
|
217
|
-
end
|
218
|
-
|
219
|
-
it "should work without any read_marks" do
|
220
|
-
ReadMark.delete_all
|
221
|
-
|
222
|
-
emails = Email.with_read_marks_for(@reader).to_a
|
223
|
-
expect(emails[0].unread?(@reader)).to be_truthy
|
224
|
-
expect(emails[1].unread?(@reader)).to be_truthy
|
225
|
-
end
|
226
|
-
|
227
|
-
it "should work with eager-loaded read marks for the correct reader" do
|
228
|
-
@email1.mark_as_read! for: @reader
|
229
|
-
|
230
|
-
emails = Email.with_read_marks_for(@reader).to_a
|
231
|
-
expect(emails[0].unread?(@reader)).to be_falsey
|
232
|
-
expect(emails[0].unread?(@other_reader)).to be_truthy
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
describe '#mark_as_read!' do
|
237
|
-
it "should mark a single object as read" do
|
238
|
-
@email1.mark_as_read! for: @reader
|
239
|
-
|
240
|
-
expect(@email1.unread?(@reader)).to be_falsey
|
241
|
-
expect(Email.unread_by(@reader)).to eq [@email2]
|
242
|
-
|
243
|
-
expect(@email1.unread?(@other_reader)).to be_truthy
|
244
|
-
expect(Email.unread_by(@other_reader)).to eq [@email1, @email2]
|
245
|
-
|
246
|
-
expect(@reader.read_marks.single.count).to eq 1
|
247
|
-
expect(@reader.read_marks.single.first.readable).to eq @email1
|
248
|
-
end
|
249
|
-
|
250
|
-
it "should be idempotent" do
|
251
|
-
@email1.mark_as_read! for: @reader
|
252
|
-
@email1.mark_as_read! for: @reader
|
253
|
-
|
254
|
-
expect(@reader.read_marks.single.count).to eq 1
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
describe '.mark_as_read!' do
|
259
|
-
it "should mark multi objects as read" do
|
260
|
-
expect(@email1.unread?(@reader)).to be_truthy
|
261
|
-
expect(@email2.unread?(@reader)).to be_truthy
|
262
|
-
|
263
|
-
Email.mark_as_read! [ @email1, @email2 ], for: @reader
|
264
|
-
|
265
|
-
expect(@email1.unread?(@reader)).to be_falsey
|
266
|
-
expect(@email2.unread?(@reader)).to be_falsey
|
267
|
-
end
|
268
|
-
|
269
|
-
it "should mark the rest as read when the first record is not unique" do
|
270
|
-
Email.mark_as_read! [ @email1 ], for: @reader
|
271
|
-
|
272
|
-
allow(@email1).to receive_message_chain("read_marks.find_or_initialize_by")
|
273
|
-
.and_return(@email1.read_marks.build(reader: @reader))
|
274
|
-
|
275
|
-
expect do
|
276
|
-
Email.mark_as_read! [ @email1, @email2 ], for: @reader
|
277
|
-
end.to change(ReadMark, :count).by(1)
|
278
|
-
|
279
|
-
expect(@email1.unread?(@reader)).to be_falsey
|
280
|
-
expect(@email2.unread?(@reader)).to be_falsey
|
281
|
-
end
|
282
|
-
|
283
|
-
it "should perform less queries if the objects are already read" do
|
284
|
-
Email.mark_as_read! :all, for: @reader
|
285
|
-
|
286
|
-
expect {
|
287
|
-
Email.mark_as_read! [ @email1, @email2 ], for: @reader
|
288
|
-
}.to perform_queries(1)
|
289
|
-
end
|
290
|
-
|
291
|
-
it "should allow a collection of records to be marked as read" do
|
292
|
-
Email.mark_as_read! Email.all, for: @reader
|
293
|
-
|
294
|
-
expect(@email1.unread?(@reader)).to be_falsey
|
295
|
-
expect(@email2.unread?(@reader)).to be_falsey
|
296
|
-
end
|
297
|
-
|
298
|
-
it "should mark all objects as read" do
|
299
|
-
Email.mark_as_read! :all, for: @reader
|
300
|
-
|
301
|
-
expect(@reader.read_mark_global(Email).timestamp).to eq Time.current
|
302
|
-
expect(@reader.read_marks.single).to eq []
|
303
|
-
expect(ReadMark.single.count).to eq 0
|
304
|
-
expect(ReadMark.global.count).to eq 3
|
305
|
-
end
|
306
|
-
|
307
|
-
it "should mark all objects as read with existing read objects" do
|
308
|
-
wait
|
309
|
-
|
310
|
-
Email.mark_as_read! :all, for: @reader
|
311
|
-
@email1.mark_as_read! for: @reader
|
312
|
-
|
313
|
-
expect(@reader.read_marks.single).to eq []
|
314
|
-
end
|
315
|
-
|
316
|
-
it "should reset memoized global read mark" do
|
317
|
-
rm_global = @reader.read_mark_global(Email)
|
318
|
-
|
319
|
-
Email.mark_as_read! :all, for: @reader
|
320
|
-
expect(@reader.read_mark_global(Email)).not_to eq(rm_global)
|
321
|
-
end
|
322
|
-
|
323
|
-
it "should not allow invalid arguments" do
|
324
|
-
expect {
|
325
|
-
Email.mark_as_read! :foo, for: @reader
|
326
|
-
}.to raise_error(ArgumentError)
|
327
|
-
|
328
|
-
expect {
|
329
|
-
Email.mark_as_read! :foo, :bar
|
330
|
-
}.to raise_error(ArgumentError)
|
331
|
-
end
|
332
|
-
|
333
|
-
it "should work with STI readers" do
|
334
|
-
Email.mark_as_read! [ @email1 ], for: Customer.find(@sti_reader.id)
|
335
|
-
expect(@email1.unread?(@sti_reader)).to be_falsey
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
describe :cleanup_read_marks! do
|
340
|
-
it "should run garbage collector" do
|
341
|
-
expect(Unread::GarbageCollector).to receive(:new).with(Email).and_return(double :run! => true)
|
342
|
-
Email.cleanup_read_marks!
|
343
|
-
end
|
344
|
-
end
|
345
|
-
end
|
@@ -1,9 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Unread::Reader::Scopes do
|
4
|
-
it 'should define reader_scope' do
|
5
|
-
expect(Reader.reader_scope).to eq Reader.not_foo.not_bar
|
6
|
-
expect(DifferentReader.reader_scope).to eq DifferentReader
|
7
|
-
expect(StiReader.reader_scope).to eq StiReader
|
8
|
-
end
|
9
|
-
end
|
data/spec/unread/reader_spec.rb
DELETED
@@ -1,181 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Unread::Reader do
|
4
|
-
before :each do
|
5
|
-
@reader = Reader.create! name: 'David'
|
6
|
-
@other_reader = Reader.create name: 'Matz'
|
7
|
-
@different_reader = DifferentReader.create! name: 'Behrooz', number: @reader.number
|
8
|
-
wait
|
9
|
-
@email1 = Email.create!
|
10
|
-
wait
|
11
|
-
@email2 = MultiLevelStiReadable.create!
|
12
|
-
end
|
13
|
-
|
14
|
-
describe :have_not_read do
|
15
|
-
it "should return all readers that have not read a given object" do
|
16
|
-
expect(Reader.have_not_read(@email1)).to eq [@reader, @other_reader]
|
17
|
-
expect(Reader.have_not_read(@email2)).to eq [@reader, @other_reader]
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should return *only* the readers that have not read a given object" do
|
21
|
-
@email1.mark_as_read! for: @reader
|
22
|
-
|
23
|
-
expect(Reader.have_not_read(@email1)).to eq [@other_reader]
|
24
|
-
expect(Reader.have_not_read(@email1).count).to eq 1
|
25
|
-
|
26
|
-
expect(Reader.have_not_read(@email2)).to eq [@reader, @other_reader]
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should take the type of reader into account" do
|
30
|
-
# even though the id of @reader and @different_reader is the same because
|
31
|
-
# they are different object types, the @email1 should only be marked as
|
32
|
-
# read for @reader.
|
33
|
-
@email1.mark_as_read! for: @reader
|
34
|
-
|
35
|
-
expect(Reader.have_not_read(@email1)).to eq [@other_reader]
|
36
|
-
expect(Reader.have_not_read(@email1).count).to eq 1
|
37
|
-
|
38
|
-
expect(DifferentReader.have_not_read(@email1)).to eq [@different_reader]
|
39
|
-
expect(DifferentReader.have_not_read(@email1).count).to eq 1
|
40
|
-
|
41
|
-
@email1.mark_as_read! for: @different_reader
|
42
|
-
|
43
|
-
expect(DifferentReader.have_not_read(@email1).count).to eq 0
|
44
|
-
|
45
|
-
expect(Reader.have_not_read(@email2)).to eq [@reader, @other_reader]
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should not allow invalid parameter" do
|
49
|
-
[ 42, nil, 'foo', :foo, {} ].each do |not_a_readable|
|
50
|
-
expect {
|
51
|
-
Reader.have_not_read(not_a_readable)
|
52
|
-
}.to raise_error(ArgumentError)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should not allow unsaved readable" do
|
57
|
-
unsaved_readable = Email.new
|
58
|
-
|
59
|
-
expect {
|
60
|
-
Reader.have_not_read(unsaved_readable)
|
61
|
-
}.to raise_error(ArgumentError)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe :have_read do
|
66
|
-
it "should return an empty array" do
|
67
|
-
expect(Reader.have_read(@email1)).to be_empty
|
68
|
-
expect(Reader.have_read(@email2)).to be_empty
|
69
|
-
end
|
70
|
-
|
71
|
-
it "should return *only* the readers that have read the given object" do
|
72
|
-
@email1.mark_as_read! for: @reader
|
73
|
-
|
74
|
-
expect(Reader.have_read(@email1)).to eq [@reader]
|
75
|
-
expect(Reader.have_read(@email1).count).to eq 1
|
76
|
-
|
77
|
-
expect(Reader.have_read(@email2)).to be_empty
|
78
|
-
end
|
79
|
-
|
80
|
-
it "should return the reader for all the object when all read" do
|
81
|
-
Email.mark_as_read! :all, for: @reader
|
82
|
-
|
83
|
-
expect(Reader.have_read(@email1)).to eq [@reader]
|
84
|
-
expect(Reader.have_read(@email1).count).to eq 1
|
85
|
-
|
86
|
-
expect(Reader.have_read(@email2)).to eq [@reader]
|
87
|
-
expect(Reader.have_read(@email2).count).to eq 1
|
88
|
-
end
|
89
|
-
|
90
|
-
it "should not allow invalid parameter" do
|
91
|
-
[ 42, nil, 'foo', :foo, {} ].each do |not_a_readable|
|
92
|
-
expect {
|
93
|
-
Reader.have_read(not_a_readable)
|
94
|
-
}.to raise_error(ArgumentError)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should not allow unsaved readable" do
|
99
|
-
unsaved_readable = Email.new
|
100
|
-
|
101
|
-
expect {
|
102
|
-
Reader.have_read(unsaved_readable)
|
103
|
-
}.to raise_error(ArgumentError)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
describe :with_read_marks_for do
|
108
|
-
it "should return readers" do
|
109
|
-
expect(Reader.with_read_marks_for(@email1).to_a).to eq([@reader, @other_reader])
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should have elements that respond to :read_mark_id" do
|
113
|
-
all_respond_to_read_mark_id = Reader.with_read_marks_for(@email1).to_a.all? do |reader|
|
114
|
-
reader.respond_to?(:read_mark_id)
|
115
|
-
end
|
116
|
-
|
117
|
-
expect(all_respond_to_read_mark_id).to be_truthy
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should be countable" do
|
121
|
-
expect(Reader.with_read_marks_for(@email1).count(:number)).to eq(2)
|
122
|
-
end
|
123
|
-
|
124
|
-
it "should not allow invalid parameter" do
|
125
|
-
[ 42, nil, 'foo', :foo, {} ].each do |not_a_readable|
|
126
|
-
expect {
|
127
|
-
Reader.with_read_marks_for(not_a_readable)
|
128
|
-
}.to raise_error(ArgumentError)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should not allow unsaved readable" do
|
133
|
-
unsaved_readable = Email.new
|
134
|
-
|
135
|
-
expect {
|
136
|
-
Reader.with_read_marks_for(unsaved_readable)
|
137
|
-
}.to raise_error(ArgumentError)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
describe :have_read? do
|
142
|
-
it "should recognize read objects" do
|
143
|
-
expect(@reader.have_read?(@email1)).to be_falsey
|
144
|
-
expect(@reader.have_read?(@email2)).to be_falsey
|
145
|
-
end
|
146
|
-
|
147
|
-
it "should handle updating object" do
|
148
|
-
@email1.mark_as_read! for: @reader
|
149
|
-
wait
|
150
|
-
expect(@reader.have_read?(@email1)).to be_truthy
|
151
|
-
|
152
|
-
@email1.update_attributes! subject: 'changed'
|
153
|
-
expect(@reader.have_read?(@email1)).to be_falsey
|
154
|
-
end
|
155
|
-
|
156
|
-
it "should raise error for invalid argument" do
|
157
|
-
expect {
|
158
|
-
@reader.have_read?(42)
|
159
|
-
}.to raise_error(ArgumentError)
|
160
|
-
end
|
161
|
-
|
162
|
-
it "should work with eager-loaded read marks" do
|
163
|
-
@email1.mark_as_read! for: @reader
|
164
|
-
|
165
|
-
expect {
|
166
|
-
readers = Reader.with_read_marks_for(@email1).to_a
|
167
|
-
|
168
|
-
expect(readers[0].have_read?(@email1)).to be_truthy
|
169
|
-
expect(readers[1].have_read?(@email1)).to be_falsey
|
170
|
-
}.to perform_queries(1)
|
171
|
-
end
|
172
|
-
|
173
|
-
it "should work with eager-loaded read marks for the correct readable" do
|
174
|
-
@email1.mark_as_read! for: @reader
|
175
|
-
|
176
|
-
readers = Reader.with_read_marks_for(@email1).to_a
|
177
|
-
expect(readers[0].have_read?(@email1)).to be_truthy
|
178
|
-
expect(readers[0].have_read?(@email2)).to be_falsey
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|