usaidwat 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +7 -2
- data/features/fixtures/user_mipadi.json +16 -0
- data/features/fixtures/user_testuser.json +3 -0
- data/features/log.feature +485 -0
- data/features/step_definitions/reddit_steps.rb +1 -1
- data/features/tally.feature +117 -0
- data/features/user.feature +33 -0
- data/lib/usaidwat/application.rb +88 -18
- data/lib/usaidwat/client.rb +32 -1
- data/lib/usaidwat/either.rb +41 -0
- data/lib/usaidwat/ext/time.rb +55 -4
- data/lib/usaidwat/formatter.rb +38 -14
- data/lib/usaidwat/service.rb +17 -9
- data/lib/usaidwat/version.rb +1 -1
- data/spec/usaidwat/client_spec.rb +92 -6
- data/spec/usaidwat/either_spec.rb +52 -0
- data/spec/usaidwat/formatter_spec.rb +94 -1
- data/spec/usaidwat/time_spec.rb +165 -1
- data/usaidwat.gemspec +5 -3
- metadata +34 -21
- data/features/browse.feature +0 -361
@@ -0,0 +1,33 @@
|
|
1
|
+
Feature: Display user information
|
2
|
+
|
3
|
+
As a Redditor
|
4
|
+
I want to be able to list basic information about another Redditor
|
5
|
+
In order to learn more about them
|
6
|
+
|
7
|
+
Scenario: List user information
|
8
|
+
Given the Reddit service returns information for the user "mipadi"
|
9
|
+
And time is frozen at Sep 15, 2015 3:16 PM
|
10
|
+
When I run `usaidwat info mipadi`
|
11
|
+
Then the exit status should be 0
|
12
|
+
And the output should match:
|
13
|
+
"""
|
14
|
+
Created: [A-Z][a-z]{2} \d{2}, \d{4} \d{2}:\d{2} (A|P)M \(over 7 years ago\)
|
15
|
+
Link Karma: 4892
|
16
|
+
Comment Karma: 33440
|
17
|
+
"""
|
18
|
+
|
19
|
+
Scenario: List user information for a non-existent user
|
20
|
+
Given the Reddit service does not have a user "testuser"
|
21
|
+
When I run `usaidwat info testuser`
|
22
|
+
Then it should fail with:
|
23
|
+
"""
|
24
|
+
No such user: testuser
|
25
|
+
"""
|
26
|
+
|
27
|
+
Scenario: Fail to pass a username when querying for information
|
28
|
+
Given the Reddit service returns information for the user "mipadi"
|
29
|
+
When I run `usaidwat info`
|
30
|
+
Then it should fail with:
|
31
|
+
"""
|
32
|
+
You must specify a username
|
33
|
+
"""
|
data/lib/usaidwat/application.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'usaidwat/algo'
|
2
2
|
require 'usaidwat/client'
|
3
|
+
require 'usaidwat/either'
|
3
4
|
require 'usaidwat/pager'
|
4
5
|
require 'sysexits'
|
5
6
|
|
@@ -38,11 +39,37 @@ module USaidWat
|
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
42
|
+
class Info < Command
|
43
|
+
def initialize(prog)
|
44
|
+
prog.command(:info) do |c|
|
45
|
+
c.action do |args, options|
|
46
|
+
process(options, args)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
def process(options, args)
|
53
|
+
raise ArgumentError.new('You must specify a username') if args.empty?
|
54
|
+
username = args.shift
|
55
|
+
|
56
|
+
redditor = client.new(username)
|
57
|
+
created_at = redditor.created_at.strftime("%b %d, %Y %H:%M %p")
|
58
|
+
puts "Created: #{created_at} (#{redditor.age})"
|
59
|
+
printf "Link Karma: %d\n", redditor.link_karma
|
60
|
+
printf "Comment Karma: %d\n", redditor.comment_karma
|
61
|
+
rescue USaidWat::Client::NoSuchUserError
|
62
|
+
quit "No such user: #{username}", :no_such_user
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
41
66
|
class Log < Command
|
42
67
|
def initialize(prog)
|
43
68
|
prog.command(:log) do |c|
|
44
69
|
c.alias :l
|
70
|
+
c.option 'date', '--date FORMAT', 'Show dates in "absolute" or "relative" format'
|
45
71
|
c.option 'grep', '--grep STRING', 'Show only comments matching STRING'
|
72
|
+
c.option 'limit', '-n LIMIT', 'Only show n comments'
|
46
73
|
c.option 'oneline', '--oneline', 'Output log in a more compact form'
|
47
74
|
c.option 'raw', '--raw', 'Print raw comment bodies'
|
48
75
|
|
@@ -56,31 +83,69 @@ module USaidWat
|
|
56
83
|
def process(options, args)
|
57
84
|
raise ArgumentError.new('You must specify a username') if args.empty?
|
58
85
|
username = args.shift
|
59
|
-
|
86
|
+
subreddits = args.join(' ').split(/[ ,\+]/).map { |sr| sr.downcase }
|
60
87
|
|
61
88
|
redditor = client.new(username)
|
62
89
|
comments = redditor.comments
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
if
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
90
|
+
|
91
|
+
res = filter_comments(redditor, comments, subreddits) >>
|
92
|
+
lambda { |r| grep_comments(redditor, r.value, options['grep']) } >>
|
93
|
+
lambda { |r| limit_comments(redditor, r.value, options['limit']) } >>
|
94
|
+
lambda { |r| ensure_comments(redditor, r.value) }
|
95
|
+
|
96
|
+
quit res.value if res.left?
|
97
|
+
|
98
|
+
opts = {
|
99
|
+
:date_format => (options['date'] || :relative).to_sym,
|
100
|
+
:oneline => !options['oneline'].nil?,
|
101
|
+
:pattern => options['grep'],
|
102
|
+
:raw => !options['raw'].nil?,
|
103
|
+
}
|
104
|
+
list_comments(res.value, opts)
|
76
105
|
rescue USaidWat::Client::NoSuchUserError
|
77
106
|
quit "No such user: #{username}", :no_such_user
|
78
107
|
end
|
79
108
|
|
80
109
|
private
|
81
110
|
|
82
|
-
def
|
83
|
-
|
111
|
+
def filter_comments(redditor, comments, subreddits)
|
112
|
+
return USaidWat::Right.new(comments) if subreddits.empty?
|
113
|
+
comments = comments.find_all { |c| subreddits.include?(c.subreddit.downcase) }
|
114
|
+
if comments.empty?
|
115
|
+
USaidWat::Left.new("No comments by #{redditor.username} for #{subreddits.join(', ')}.")
|
116
|
+
else
|
117
|
+
USaidWat::Right.new(comments)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def grep_comments(redditor, comments, grep)
|
122
|
+
return USaidWat::Right.new(comments) if grep.nil?
|
123
|
+
comments = comments.select { |c| c.body =~ /#{grep}/i }
|
124
|
+
if comments.empty?
|
125
|
+
msg = "#{redditor.username} has no comments matching /#{grep}/."
|
126
|
+
USaidWat::Left.new(msg)
|
127
|
+
else
|
128
|
+
USaidWat::Right.new(comments)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def limit_comments(redditor, comments, n)
|
133
|
+
return USaidWat::Right.new(comments) if n.nil?
|
134
|
+
comments = comments[0...n.to_i]
|
135
|
+
USaidWat::Right.new(comments)
|
136
|
+
end
|
137
|
+
|
138
|
+
def ensure_comments(redditor, comments)
|
139
|
+
if comments.empty?
|
140
|
+
USaidWat::Left.new("#{redditor.username} has no comments.")
|
141
|
+
else
|
142
|
+
USaidWat::Right.new(comments)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def list_comments(comments, options = {})
|
147
|
+
oneline = options[:oneline]
|
148
|
+
formatter = (oneline ? USaidWat::CLI::CompactCommentFormatter : USaidWat::CLI::CommentFormatter).new(options)
|
84
149
|
page
|
85
150
|
comments.each { |c| print formatter.format(c) }
|
86
151
|
end
|
@@ -105,7 +170,6 @@ module USaidWat
|
|
105
170
|
username = args.first
|
106
171
|
|
107
172
|
redditor = client.new(username)
|
108
|
-
algo_cls = options['count'] ? USaidWat::Algorithms::CountAlgorithm : USaidWat::Algorithms::LexicographicalAlgorithm
|
109
173
|
quit "#{redditor.username} has no comments." if redditor.comments.empty?
|
110
174
|
# Unfortunately Snooby cannot return comments for a specific
|
111
175
|
# user in a specific subreddit, so for now we have to sort them
|
@@ -117,7 +181,7 @@ module USaidWat
|
|
117
181
|
longest_subreddit = subreddit.length if subreddit.length > longest_subreddit
|
118
182
|
buckets[subreddit] += 1
|
119
183
|
end
|
120
|
-
algo =
|
184
|
+
algo = algorithm(options['count']).new(buckets)
|
121
185
|
subreddits = buckets.keys.sort { |a,b| algo.sort(a, b) }
|
122
186
|
subreddits.each do |subreddit|
|
123
187
|
tally = buckets[subreddit]
|
@@ -126,6 +190,12 @@ module USaidWat
|
|
126
190
|
rescue USaidWat::Client::NoSuchUserError
|
127
191
|
quit "No such user: #{username}", :no_such_user
|
128
192
|
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
def algorithm(count)
|
197
|
+
count ? USaidWat::Algorithms::CountAlgorithm : USaidWat::Algorithms::LexicographicalAlgorithm
|
198
|
+
end
|
129
199
|
end
|
130
200
|
end
|
131
201
|
end
|
data/lib/usaidwat/client.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'snooby'
|
2
2
|
require 'usaidwat/service'
|
3
|
+
require 'usaidwat/ext/time'
|
3
4
|
|
4
5
|
module USaidWat
|
5
6
|
module Client
|
@@ -15,16 +16,46 @@ module USaidWat
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def comments
|
18
|
-
|
19
|
+
user.comments(100)
|
19
20
|
rescue NoMethodError
|
20
21
|
raise NoSuchUserError, username
|
21
22
|
rescue TypeError
|
22
23
|
raise ReachabilityError, "Reddit unreachable"
|
23
24
|
end
|
24
25
|
|
26
|
+
def link_karma
|
27
|
+
about('link_karma')
|
28
|
+
end
|
29
|
+
|
30
|
+
def comment_karma
|
31
|
+
about('comment_karma')
|
32
|
+
end
|
33
|
+
|
34
|
+
def created_at
|
35
|
+
Time.at(about('created_utc'))
|
36
|
+
end
|
37
|
+
|
38
|
+
def age
|
39
|
+
(Time.now - created_at).ago
|
40
|
+
end
|
41
|
+
|
25
42
|
def to_s
|
26
43
|
"#{username}"
|
27
44
|
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def user
|
49
|
+
@service.user(username)
|
50
|
+
end
|
51
|
+
|
52
|
+
def about(key)
|
53
|
+
user.about[key]
|
54
|
+
rescue NoMethodError
|
55
|
+
raise NoSuchUserError, username
|
56
|
+
rescue TypeError
|
57
|
+
raise ReachabilityError, "Reddit unreachable"
|
58
|
+
end
|
28
59
|
end
|
29
60
|
|
30
61
|
class Redditor < BaseRedditor
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module USaidWat
|
2
|
+
class Either
|
3
|
+
attr_reader :value
|
4
|
+
|
5
|
+
def initialize(value)
|
6
|
+
@value = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def >>(&block)
|
10
|
+
raise NoMethodError, 'subclasses must define >>'
|
11
|
+
end
|
12
|
+
|
13
|
+
def left?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def right?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Left < Either
|
23
|
+
def >>(callable)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def left?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Right < Either
|
33
|
+
def >>(callable)
|
34
|
+
callable.call(self)
|
35
|
+
end
|
36
|
+
|
37
|
+
def right?
|
38
|
+
true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/usaidwat/ext/time.rb
CHANGED
@@ -2,9 +2,60 @@ require 'usaidwat/ext/string'
|
|
2
2
|
|
3
3
|
class Time
|
4
4
|
def ago
|
5
|
-
|
5
|
+
delta.ago
|
6
|
+
end
|
7
|
+
|
8
|
+
def seconds_ago
|
9
|
+
delta.seconds_ago
|
10
|
+
end
|
11
|
+
|
12
|
+
def minutes_ago
|
13
|
+
delta.minutes_ago
|
14
|
+
end
|
15
|
+
|
16
|
+
def hours_ago
|
17
|
+
delta.hours_ago
|
18
|
+
end
|
19
|
+
|
20
|
+
def days_ago
|
21
|
+
delta.days_ago
|
22
|
+
end
|
23
|
+
|
24
|
+
def weeks_ago
|
25
|
+
delta.weeks_ago
|
26
|
+
end
|
27
|
+
|
28
|
+
def months_ago
|
29
|
+
delta.months_ago
|
30
|
+
end
|
31
|
+
|
32
|
+
def years_ago
|
33
|
+
delta.years_ago
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def delta
|
39
|
+
Time.now - self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Numeric
|
44
|
+
def negative?
|
45
|
+
self < 0
|
46
|
+
end
|
47
|
+
|
48
|
+
def positive?
|
49
|
+
self > 0
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Float
|
54
|
+
def ago
|
55
|
+
raise ArgumentError, "Delta is negative: #{self}" if negative?
|
56
|
+
case minutes_ago.to_i
|
6
57
|
when 0..1
|
7
|
-
case seconds_ago
|
58
|
+
case seconds_ago.to_i
|
8
59
|
when 0..5 then "less than 5 seconds ago"
|
9
60
|
when 6..10 then "less than 10 seconds ago"
|
10
61
|
when 11..20 then "less than 20 seconds ago"
|
@@ -20,12 +71,12 @@ class Time
|
|
20
71
|
when 10081..43220 then "about #{weeks_ago.round} #{"week".pluralize(weeks_ago.round)} ago"
|
21
72
|
when 43221..525960 then "about #{months_ago.round} #{"month".pluralize(months_ago.round)} ago"
|
22
73
|
when 525960..1051920 then "about a year ago"
|
23
|
-
else "over #{years_ago.
|
74
|
+
else "over #{years_ago.to_i} years ago"
|
24
75
|
end
|
25
76
|
end
|
26
77
|
|
27
78
|
def seconds_ago
|
28
|
-
|
79
|
+
self
|
29
80
|
end
|
30
81
|
|
31
82
|
def minutes_ago
|
data/lib/usaidwat/formatter.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'downterm'
|
3
|
-
require 'highline'
|
4
3
|
require 'rainbow/ext/string'
|
5
4
|
require 'redcarpet'
|
6
5
|
require 'stringio'
|
6
|
+
require 'tty-screen'
|
7
7
|
require 'usaidwat/ext/string'
|
8
8
|
require 'usaidwat/ext/time'
|
9
9
|
|
@@ -12,25 +12,36 @@ Rainbow.enabled = true unless ENV['USAIDWAT_ENV'] == 'cucumber'
|
|
12
12
|
module USaidWat
|
13
13
|
module CLI
|
14
14
|
class BaseFormatter
|
15
|
-
|
16
|
-
|
17
|
-
def initialize(pattern = nil, raw = false)
|
18
|
-
@pattern = pattern
|
19
|
-
@raw = raw
|
15
|
+
def initialize(options = {})
|
16
|
+
@options = options
|
20
17
|
@count = 0
|
21
18
|
end
|
22
19
|
|
20
|
+
def pattern
|
21
|
+
@options[:pattern]
|
22
|
+
end
|
23
|
+
|
23
24
|
def pattern?
|
24
|
-
|
25
|
+
!!@options[:pattern]
|
25
26
|
end
|
26
27
|
|
27
28
|
def raw?
|
28
|
-
|
29
|
+
!!@options[:raw]
|
29
30
|
end
|
31
|
+
|
32
|
+
def relative_dates?
|
33
|
+
@options[:date_format].nil? || @options[:date_format].to_sym != :absolute
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def tty
|
39
|
+
@tty || TTY::Screen.new
|
40
|
+
end
|
30
41
|
end
|
31
42
|
|
32
43
|
class CommentFormatter < BaseFormatter
|
33
|
-
def initialize(
|
44
|
+
def initialize(options = {})
|
34
45
|
@markdown = Redcarpet::Markdown.new(Downterm::Render::Terminal, :autolink => true,
|
35
46
|
:strikethrough => true,
|
36
47
|
:superscript => true)
|
@@ -38,13 +49,15 @@ module USaidWat
|
|
38
49
|
end
|
39
50
|
|
40
51
|
def format(comment)
|
41
|
-
cols =
|
52
|
+
cols = tty.width
|
42
53
|
out = StringIO.new
|
43
54
|
out.write("\n\n") unless @count == 0
|
44
55
|
out.write("#{comment.subreddit}\n".color(:green))
|
45
56
|
out.write("#{comment_link(comment)}\n".color(:yellow))
|
46
57
|
out.write("#{comment.link_title.strip.truncate(cols)}\n".color(:magenta))
|
47
|
-
out.write("#{comment_date(comment)}
|
58
|
+
out.write("#{comment_date(comment)}".color(:blue))
|
59
|
+
out.write(" \u2022 ".color(:cyan))
|
60
|
+
out.write(sprintf("%+d\n", comment_karma(comment)).color(:blue))
|
48
61
|
out.write("\n")
|
49
62
|
out.write("#{comment_body(comment)}\n")
|
50
63
|
@count += 1
|
@@ -54,7 +67,7 @@ module USaidWat
|
|
54
67
|
|
55
68
|
private
|
56
69
|
def comment_body(comment)
|
57
|
-
body = comment.body
|
70
|
+
body = comment.body.strip
|
58
71
|
body = @markdown.render(body) unless raw?
|
59
72
|
if pattern?
|
60
73
|
body.highlight(pattern)
|
@@ -69,13 +82,24 @@ module USaidWat
|
|
69
82
|
end
|
70
83
|
|
71
84
|
def comment_date(comment)
|
72
|
-
DateTime.strptime(comment.created_utc.to_s, "%s").to_time.localtime
|
85
|
+
d = DateTime.strptime(comment.created_utc.to_s, "%s").to_time.localtime
|
86
|
+
if relative_dates?
|
87
|
+
d.ago
|
88
|
+
else
|
89
|
+
d_part = d.strftime("%-d %b %Y")
|
90
|
+
t_part = d.strftime("%l:%M %p").strip
|
91
|
+
"#{d_part} #{t_part}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def comment_karma(comment)
|
96
|
+
comment.ups - comment.downs
|
73
97
|
end
|
74
98
|
end
|
75
99
|
|
76
100
|
class CompactCommentFormatter < BaseFormatter
|
77
101
|
def format(comment)
|
78
|
-
cols =
|
102
|
+
cols = tty.width
|
79
103
|
out = StringIO.new
|
80
104
|
subreddit = comment.subreddit
|
81
105
|
cols -= subreddit.length + 1
|
data/lib/usaidwat/service.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module USaidWat
|
2
2
|
module Service
|
3
3
|
class MockComment
|
4
|
-
attr_reader :subreddit, :body, :id, :link_id, :created_utc, :link_title
|
4
|
+
attr_reader :subreddit, :body, :id, :link_id, :created_utc, :link_title, :ups, :downs
|
5
5
|
|
6
6
|
def initialize(dict)
|
7
7
|
data = dict['data']
|
@@ -11,6 +11,8 @@ module USaidWat
|
|
11
11
|
@link_id = data['link_id']
|
12
12
|
@created_utc = data['created_utc']
|
13
13
|
@link_title = data['link_title']
|
14
|
+
@ups = data['ups']
|
15
|
+
@downs = data['downs']
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
@@ -19,15 +21,21 @@ module USaidWat
|
|
19
21
|
@username = username
|
20
22
|
end
|
21
23
|
|
24
|
+
def about
|
25
|
+
load_data("user_#{@username}.json")['data']
|
26
|
+
end
|
27
|
+
|
22
28
|
def comments(n)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
json = load_data("#{@username}.json")
|
30
|
+
json['data']['children'].map { |d| MockComment.new(d) }
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def load_data(data_file)
|
36
|
+
path = File.join(File.dirname(__FILE__), "..", "..", "features", "fixtures", data_file)
|
37
|
+
raise USaidWat::Client::NoSuchUserError, @username unless File.exists?(path)
|
38
|
+
JSON.parse(IO.read(path))
|
31
39
|
end
|
32
40
|
end
|
33
41
|
|
data/lib/usaidwat/version.rb
CHANGED
@@ -4,19 +4,19 @@ module USaidWat
|
|
4
4
|
module Client
|
5
5
|
describe Client do
|
6
6
|
let(:redditor) { Redditor.new("mipadi") }
|
7
|
-
|
7
|
+
|
8
8
|
describe "#username" do
|
9
9
|
it "returns the Redditor's username" do
|
10
10
|
expect(redditor.username).to eq("mipadi")
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
describe "#to_s" do
|
15
15
|
it "returns a string representing the Redditor" do
|
16
16
|
expect("#{redditor}").to eq("mipadi")
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
context "when Reddit is up" do
|
21
21
|
before(:each) do
|
22
22
|
WebMock.disable_net_connect!
|
@@ -24,13 +24,47 @@ module USaidWat
|
|
24
24
|
root = File.expand_path("../../../features/fixtures", __FILE__)
|
25
25
|
stub_request(:get, "http://www.reddit.com/user/mipadi/comments.json?after=&limit=100").
|
26
26
|
to_return(:body => IO.read(File.join(root, "mipadi.json")))
|
27
|
+
stub_request(:get, "http://www.reddit.com/user/mipadi/about.json").
|
28
|
+
to_return(:body => IO.read(File.join(root, "user_mipadi.json")))
|
29
|
+
|
30
|
+
Timecop.freeze(Time.new(2015, 9, 15, 11, 14, 30, "-07:00"))
|
27
31
|
end
|
28
|
-
|
32
|
+
|
33
|
+
after(:each) do
|
34
|
+
Timecop.return
|
35
|
+
end
|
36
|
+
|
29
37
|
describe "#comments" do
|
30
38
|
it "retrieves 100 comments" do
|
31
39
|
expect(redditor.comments.count).to eq(100)
|
32
40
|
end
|
33
41
|
end
|
42
|
+
|
43
|
+
describe "#link_karma" do
|
44
|
+
it "returns the user's link karma" do
|
45
|
+
expect(redditor.link_karma).to eq(4892)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#comment_karma" do
|
50
|
+
it "returns the user's comment karma" do
|
51
|
+
expect(redditor.comment_karma).to eq(33440)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#created_at" do
|
56
|
+
it "returns the date the account was created" do
|
57
|
+
expected = Time.new(2008, 3, 31, 15, 55, 26, "-07:00")
|
58
|
+
expect(redditor.created_at).to eq(expected)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#age" do
|
63
|
+
it "returns a string describing the age of the account" do
|
64
|
+
expected = "over 7 years ago"
|
65
|
+
expect(redditor.age).to eq(expected)
|
66
|
+
end
|
67
|
+
end
|
34
68
|
end
|
35
69
|
|
36
70
|
context "when a Reddit user does not exist" do
|
@@ -40,6 +74,8 @@ module USaidWat
|
|
40
74
|
root = File.expand_path("../../../features/fixtures", __FILE__)
|
41
75
|
stub_request(:get, "http://www.reddit.com/user/testuser/comments.json?after=&limit=100").
|
42
76
|
to_return(:status => 404, :body => IO.read(File.join(root, "testuser.json")))
|
77
|
+
stub_request(:get, "http://www.reddit.com/user/testuser/about.json").
|
78
|
+
to_return(:status => 404, :body => IO.read(File.join(root, "user_testuser.json")))
|
43
79
|
end
|
44
80
|
|
45
81
|
describe "#comments" do
|
@@ -47,21 +83,71 @@ module USaidWat
|
|
47
83
|
expect { Redditor.new("testuser").comments }.to raise_error(NoSuchUserError, /testuser/)
|
48
84
|
end
|
49
85
|
end
|
86
|
+
|
87
|
+
describe "#link_karma" do
|
88
|
+
it "raises an exception if the user does not exist" do
|
89
|
+
expect { Redditor.new("testuser").link_karma }.to raise_error(NoSuchUserError, /testuser/)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#comment_karma" do
|
94
|
+
it "raises an exception if the user does not exist" do
|
95
|
+
expect { Redditor.new("testuser").comment_karma }.to raise_error(NoSuchUserError, /testuser/)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#created_at" do
|
100
|
+
it "raises an exception if the user does not exist" do
|
101
|
+
expect { Redditor.new("testuser").created_at }.to raise_error(NoSuchUserError, /testuser/)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#age" do
|
106
|
+
it "raises an exception if the user does not exist" do
|
107
|
+
expect { Redditor.new("testuser").age }.to raise_error(NoSuchUserError, /testuser/)
|
108
|
+
end
|
109
|
+
end
|
50
110
|
end
|
51
|
-
|
111
|
+
|
52
112
|
context "when Reddit is down" do
|
53
113
|
before(:each) do
|
54
114
|
WebMock.disable_net_connect!
|
55
115
|
WebMock.reset!
|
56
116
|
stub_request(:get, "http://www.reddit.com/user/mipadi/comments.json?after=&limit=100").
|
57
117
|
to_return(:status => 500)
|
118
|
+
stub_request(:get, "http://www.reddit.com/user/mipadi/about.json").
|
119
|
+
to_return(:status => 500)
|
58
120
|
end
|
59
|
-
|
121
|
+
|
60
122
|
describe "#comments" do
|
61
123
|
it "raises 'Reddit unreachable' error" do
|
62
124
|
expect { redditor.comments }.to raise_error(ReachabilityError, /Reddit unreachable/)
|
63
125
|
end
|
64
126
|
end
|
127
|
+
|
128
|
+
describe "#link_karma" do
|
129
|
+
it "raises 'Reddit unreachable' error" do
|
130
|
+
expect { redditor.link_karma }.to raise_error(ReachabilityError, /Reddit unreachable/)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "#comment_karma" do
|
135
|
+
it "raises 'Reddit unreachable' error" do
|
136
|
+
expect { redditor.comment_karma }.to raise_error(ReachabilityError, /Reddit unreachable/)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "#created_at" do
|
141
|
+
it "raises 'Reddit unreachable' error" do
|
142
|
+
expect { redditor.created_at }.to raise_error(ReachabilityError, /Reddit unreachable/)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "#age" do
|
147
|
+
it "raises 'Reddit unreachable' error" do
|
148
|
+
expect { redditor.age }.to raise_error(ReachabilityError, /Reddit unreachable/)
|
149
|
+
end
|
150
|
+
end
|
65
151
|
end
|
66
152
|
end
|
67
153
|
end
|