usaidwat 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,6 +16,18 @@ module USaidWat
16
16
  end
17
17
  end
18
18
 
19
+ class MockSubmission
20
+ attr_reader :subreddit, :title, :created_utc, :permalink
21
+
22
+ def initialize(dict)
23
+ data = dict['data']
24
+ @subreddit = data['subreddit']
25
+ @title = data['title']
26
+ @created_utc = data['created_utc']
27
+ @permalink = data['permalink']
28
+ end
29
+ end
30
+
19
31
  class MockUser
20
32
  def initialize(username)
21
33
  @username = username
@@ -30,6 +42,11 @@ module USaidWat
30
42
  json['data']['children'].map { |d| MockComment.new(d) }
31
43
  end
32
44
 
45
+ def posts
46
+ json = load_data("submissions_#{@username}.json")
47
+ json['data']['children'].map { |d| MockSubmission.new(d) }
48
+ end
49
+
33
50
  private
34
51
 
35
52
  def load_data(data_file)
@@ -1,3 +1,3 @@
1
1
  module USaidWat
2
- VERSION = "1.3.0"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'usaidwat/ext/array'
3
+
4
+ module USaidWat
5
+ module Ext
6
+ describe Array do
7
+ it "should split args separated by spaces" do
8
+ v = %W{one two three}
9
+ expected = v
10
+ actual = v.subreddits
11
+ expect(actual).to eq(expected)
12
+ end
13
+
14
+ it "should split args separated by commas" do
15
+ v = ['one,two,three']
16
+ expected = %W{one two three}
17
+ actual = v.subreddits
18
+ expect(actual).to eq(expected)
19
+ end
20
+
21
+ it "should split args separated by plus signs" do
22
+ v = ['one+two+three']
23
+ expected = %W{one two three}
24
+ actual = v.subreddits
25
+ expect(actual).to eq(expected)
26
+ end
27
+
28
+ it "should downcase all args" do
29
+ v = %W{one Two Three}
30
+ expected = %W{one two three}
31
+ actual = v.subreddits
32
+ expect(actual).to eq(expected)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -26,6 +26,8 @@ module USaidWat
26
26
  to_return(:body => IO.read(File.join(root, "mipadi.json")))
27
27
  stub_request(:get, "http://www.reddit.com/user/mipadi/about.json").
28
28
  to_return(:body => IO.read(File.join(root, "user_mipadi.json")))
29
+ stub_request(:get, "http://www.reddit.com/user/mipadi/submitted.json?after=&limit=25").
30
+ to_return(:body => IO.read(File.join(root, "submissions_mipadi.json")))
29
31
 
30
32
  Timecop.freeze(Time.new(2015, 9, 15, 11, 14, 30, "-07:00"))
31
33
  end
@@ -34,6 +36,12 @@ module USaidWat
34
36
  Timecop.return
35
37
  end
36
38
 
39
+ describe "#posts" do
40
+ it "retrieves 25 posts" do
41
+ expect(redditor.posts.count).to eq(25)
42
+ end
43
+ end
44
+
37
45
  describe "#comments" do
38
46
  it "retrieves 100 comments" do
39
47
  expect(redditor.comments.count).to eq(100)
@@ -76,6 +84,14 @@ module USaidWat
76
84
  to_return(:status => 404, :body => IO.read(File.join(root, "testuser.json")))
77
85
  stub_request(:get, "http://www.reddit.com/user/testuser/about.json").
78
86
  to_return(:status => 404, :body => IO.read(File.join(root, "user_testuser.json")))
87
+ stub_request(:get, "http://www.reddit.com/user/testuser/submitted.json?after=&limit=25").
88
+ to_return(:status => 404, :body => IO.read(File.join(root, "submissions_testuser.json")))
89
+ end
90
+
91
+ describe "#posts" do
92
+ it "raises an exception if the user does not exist" do
93
+ expect { Redditor.new("testuser").comments }.to raise_error(NoSuchUserError, /testuser/)
94
+ end
79
95
  end
80
96
 
81
97
  describe "#comments" do
@@ -117,6 +133,14 @@ module USaidWat
117
133
  to_return(:status => 500)
118
134
  stub_request(:get, "http://www.reddit.com/user/mipadi/about.json").
119
135
  to_return(:status => 500)
136
+ stub_request(:get, "http://www.reddit.com/user/mipadi/submitted.json?after=&limit=25").
137
+ to_return(:status => 500)
138
+ end
139
+
140
+ describe "#posts" do
141
+ it "raises 'Reddit unreachable' error" do
142
+ expect { redditor.comments }.to raise_error(ReachabilityError, /Reddit unreachable/)
143
+ end
120
144
  end
121
145
 
122
146
  describe "#comments" do
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'usaidwat/algo'
3
+ require 'usaidwat/count'
4
+
5
+
6
+ module USaidWat
7
+ module Application
8
+ describe CountCommand do
9
+ before(:all) do
10
+ Struct.new('Comment', :subreddit, :body)
11
+ end
12
+
13
+ let (:stub) { Class.new { include CountCommand }.new }
14
+
15
+ let(:comments) do
16
+ c1 = Array.new(20) { Struct::Comment.new('AskReddit') }
17
+ c2 = Array.new(20) { Struct::Comment.new('programming') }
18
+ c3 = Array.new(19) { Struct::Comment.new('Python') }
19
+ c4 = Array.new(20) { Struct::Comment.new('books') }
20
+ c5 = Array.new(21) { Struct::Comment.new('ruby') }
21
+ c1 + c2 + c3 + c4 + c5
22
+ end
23
+
24
+ describe '#algorithm' do
25
+ it 'sorts entries by subreddit name' do
26
+ expect(stub.algorithm(true)).to eq(USaidWat::Algorithms::CountAlgorithm)
27
+ end
28
+
29
+ it 'sorts entries by count' do
30
+ expect(stub.algorithm(false)).to eq(USaidWat::Algorithms::LexicographicalAlgorithm)
31
+ end
32
+ end
33
+
34
+ describe '#partition' do
35
+ it 'partitions data and returns the longest subreddit' do
36
+ res = stub.partition(comments, false)
37
+ expect(res.longest).to eq('programming'.length)
38
+ end
39
+
40
+ it 'partitions data and returns the partitioned data' do
41
+ res = stub.partition(comments, false)
42
+ expect(res.counts.count).to eq(5)
43
+ expect(res.counts.first.first).to eq('AskReddit')
44
+ expect(res.counts.last.first).to eq('ruby')
45
+ end
46
+
47
+ it 'partitions data, sorting by count, and returns the longest subreddit' do
48
+ res = stub.partition(comments, true)
49
+ expect(res.longest).to eq('programming'.length)
50
+ end
51
+
52
+ it 'partitions data, sorting by count, and returns the partitioned data' do
53
+ res = stub.partition(comments, true)
54
+ expect(res.counts.count).to eq(5)
55
+ expect(res.counts.first.first).to eq('ruby')
56
+ expect(res.counts.last.first).to eq('Python')
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require 'usaidwat/filter'
3
+
4
+ module USaidWat
5
+ module Application
6
+ describe FilterCommand do
7
+ before(:all) do
8
+ Struct.new('Redditor', :username)
9
+ Struct.new('Comment', :subreddit, :body) unless Struct::const_defined? 'Comment'
10
+ end
11
+
12
+ let (:stub) { Class.new { include FilterCommand }.new }
13
+ let (:redditor) { Struct::Redditor.new('mipadi') }
14
+
15
+ let (:comments) do
16
+ c1 = Array.new(50) { Struct::Comment.new('AskReddit', 'The quick brown fox jumps over the lazy dog.') }
17
+ c2 = Array.new(50) { Struct::Comment.new('Python', 'How razorback-jumping frogs can level six piqued gynmasts!') }
18
+ c1 + c2
19
+ end
20
+
21
+ describe '#filter_entries' do
22
+ it 'returns entries filtered by subreddit' do
23
+ res = stub.filter_entries('', redditor, comments, ['python'])
24
+ expect(res.right?).to be true
25
+ expect(res.value.count).to eq(50)
26
+ end
27
+
28
+ it 'returns an empty object if all entries are filtered' do
29
+ res = stub.filter_entries('', redditor, comments, ['nsfw'])
30
+ expect(res.left?).to be true
31
+ end
32
+
33
+ it 'returns all the entries if no subreddit is specified' do
34
+ res = stub.filter_entries('', redditor, comments, [])
35
+ expect(res.right?).to be true
36
+ expect(res.value).to eq(comments)
37
+ end
38
+ end
39
+
40
+ describe '#grep_entries' do
41
+ it 'returns entries filtered by search string' do
42
+ res = stub.grep_entries('', redditor, comments, 'fox')
43
+ expect(res.right?).to be true
44
+ expect(res.value.count).to eq(50)
45
+ end
46
+
47
+ it 'returns an empty object if all entries are filtered' do
48
+ res = stub.grep_entries('', redditor, comments, 'blah')
49
+ expect(res.left?).to be true
50
+ end
51
+
52
+ it 'returns all the entries if no search string is specified' do
53
+ res = stub.grep_entries('', redditor, comments, nil)
54
+ expect(res.right?).to be true
55
+ expect(res.value).to eq(comments)
56
+ end
57
+ end
58
+
59
+ describe '#limit_entries' do
60
+ it 'returns a specified number of entries' do
61
+ entries = (1..100).to_a
62
+ res = stub.limit_entries('', nil, entries, 10)
63
+ expect(res.right?).to be true
64
+ expect(res.value.count).to eq(10)
65
+ end
66
+
67
+ it 'returns all the entries if the limit is nil' do
68
+ entries = (1..100).to_a
69
+ res = stub.limit_entries('', nil, entries, nil)
70
+ expect(res.right?).to be true
71
+ expect(res.value.count).to eq(entries.count)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -88,6 +88,74 @@ module USaidWat
88
88
  end
89
89
  end
90
90
 
91
+ describe PostFormatter do
92
+ let(:formatter) { PostFormatter.new }
93
+
94
+ before do
95
+ Timecop.freeze(Time.new(2015, 11, 19, 15, 27))
96
+ end
97
+
98
+ after do
99
+ Timecop.return
100
+ end
101
+
102
+ describe "#format" do
103
+ it "should return a string containing the formatted post" do
104
+ post = double("post")
105
+ expect(post).to receive(:subreddit).and_return("Games")
106
+ expect(post).to receive(:permalink).and_return("/r/Games/comments/3ovldc/the_xbox_one_is_garbage_and_the_future_is_bullshit/")
107
+ expect(post).to receive(:title).and_return("The Xbox One Is Garbage And The Future Is Bullshit")
108
+ expect(post).to receive(:created_utc).and_return(1444928064)
109
+ expected = <<-EXPECTED
110
+ Games
111
+ https://www.reddit.com/r/Games/comments/3ovldc
112
+ The Xbox One Is Garbage And The Future Is Bullshit
113
+ about 1 month ago
114
+ EXPECTED
115
+ expected = expected.strip
116
+ actual = formatter.format(post).delete_ansi_color_codes
117
+ expect(actual).to eq(expected)
118
+ end
119
+
120
+ it "should print two spaces between posts" do
121
+ post1 = double("first post")
122
+ expect(post1).to receive(:subreddit).and_return("Games")
123
+ expect(post1).to receive(:permalink).and_return("/r/Games/comments/3ovldc/the_xbox_one_is_garbage_and_the_future_is_bullshit/")
124
+ expect(post1).to receive(:title).and_return("The Xbox One Is Garbage And The Future Is Bullshit")
125
+ expect(post1).to receive(:created_utc).and_return(1444928064)
126
+ post2 = double("second post")
127
+ expect(post2).to receive(:subreddit).and_return("technology")
128
+ expect(post2).to receive(:permalink).and_return("/r/technology/comments/3o0vrh/mozilla_lays_out_a_proposed_set_of_rules_for/")
129
+ expect(post2).to receive(:title).and_return("Mozilla lays out a proposed set of rules for content blockers")
130
+ expect(post2).to receive(:created_utc).and_return(1444340278)
131
+ s = formatter.format(post1)
132
+ s = formatter.format(post2)
133
+ lines = s.split("\n")
134
+ expect(lines[0]).to eq('')
135
+ expect(lines[1]).to eq('')
136
+ expect(lines[2]).to eq('')
137
+ expect(lines[3]).not_to eq('')
138
+ end
139
+
140
+ it "should truncate titles to 80 characters" do
141
+ post = double("post")
142
+ expect(post).to receive(:subreddit).and_return("webdev")
143
+ expect(post).to receive(:permalink).and_return("/r/webdev/comments/29og3m/sick_of_ruby_dynamic_typing_side_effects_and/")
144
+ expect(post).to receive(:title).and_return("Sick of Ruby, dynamic typing, side effects, and basically object-oriented programming")
145
+ expect(post).to receive(:created_utc).and_return(1404331670)
146
+ expected = <<-EXPECTED
147
+ webdev
148
+ https://www.reddit.com/r/webdev/comments/29og3m
149
+ Sick of Ruby, dynamic typing, side effects, and basically object-oriented progra
150
+ about a year ago
151
+ EXPECTED
152
+ expected = expected.strip
153
+ actual = formatter.format(post).delete_ansi_color_codes
154
+ expect(actual).to eq(expected)
155
+ end
156
+ end
157
+ end
158
+
91
159
  describe CommentFormatter do
92
160
  let(:formatter) { CommentFormatter.new }
93
161
 
@@ -200,5 +268,29 @@ EXPECTED
200
268
  end
201
269
  end
202
270
  end
271
+
272
+ describe TallyFormatter do
273
+ before(:all) do
274
+ Struct.new('PartitionData', :longest, :counts)
275
+ end
276
+
277
+ let (:formatter) { TallyFormatter.new }
278
+
279
+ describe '#format' do
280
+ it 'should format partitioned data' do
281
+ longest_subreddit = 'writing'.length
282
+ count_data = [['apple', 5], ['Bass', 1], ['Python', 3], ['writing', 10]]
283
+ partition = Struct::PartitionData.new(longest_subreddit, count_data)
284
+ expected = <<-EOS
285
+ apple 5
286
+ Bass 1
287
+ Python 3
288
+ writing 10
289
+ EOS
290
+ actual = formatter.format(partition)
291
+ expect(actual).to eq(expected)
292
+ end
293
+ end
294
+ end
203
295
  end
204
296
  end
data/usaidwat.gemspec CHANGED
@@ -28,12 +28,12 @@ Gem::Specification.new do |gem|
28
28
 
29
29
  gem.required_ruby_version = '>= 1.9.3'
30
30
 
31
- gem.add_runtime_dependency('downterm', '~> 0.1.3')
32
- gem.add_runtime_dependency('highline', '~> 1.7')
31
+ gem.add_runtime_dependency('downterm', '~> 0.1.4')
33
32
  gem.add_runtime_dependency('mercenary', '~> 0.3.5')
34
33
  gem.add_runtime_dependency('rainbow', '~> 2.0')
35
34
  gem.add_runtime_dependency('snooby', '~> 0.1.5')
36
35
  gem.add_runtime_dependency('sysexits', '~> 1.2')
36
+ gem.add_runtime_dependency('ttycaca', '~> 1.0')
37
37
 
38
38
  gem.add_development_dependency('aruba', '~> 0.9')
39
39
  gem.add_development_dependency('cucumber', '~> 2.0')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usaidwat
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Dippery
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-04 00:00:00.000000000 Z
11
+ date: 2016-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: downterm
@@ -16,28 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.3
19
+ version: 0.1.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.3
27
- - !ruby/object:Gem::Dependency
28
- name: highline
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.7'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.7'
26
+ version: 0.1.4
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: mercenary
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +80,20 @@ dependencies:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
82
  version: '1.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ttycaca
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: aruba
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -172,6 +172,7 @@ executables:
172
172
  extensions: []
173
173
  extra_rdoc_files: []
174
174
  files:
175
+ - ".gitattributes"
175
176
  - ".gitignore"
176
177
  - Gemfile
177
178
  - LICENSE.txt
@@ -180,46 +181,54 @@ files:
180
181
  - bin/usaidwat
181
182
  - features/fixtures/blank.json
182
183
  - features/fixtures/mipadi.json
184
+ - features/fixtures/submissions_blank.json
185
+ - features/fixtures/submissions_mipadi.json
186
+ - features/fixtures/submissions_testuser.json
183
187
  - features/fixtures/testuser.json
184
188
  - features/fixtures/user_mipadi.json
185
189
  - features/fixtures/user_testuser.json
186
190
  - features/help.feature
187
191
  - features/log.feature
192
+ - features/posts.feature
188
193
  - features/step_definitions/reddit_steps.rb
189
194
  - features/step_definitions/time_steps.rb
190
195
  - features/support/aruba.rb
191
- - features/support/time.rb
192
196
  - features/tally.feature
193
197
  - features/user.feature
194
198
  - lib/usaidwat.rb
195
199
  - lib/usaidwat/algo.rb
196
200
  - lib/usaidwat/application.rb
197
201
  - lib/usaidwat/client.rb
202
+ - lib/usaidwat/count.rb
198
203
  - lib/usaidwat/either.rb
204
+ - lib/usaidwat/ext/array.rb
205
+ - lib/usaidwat/ext/mercenary.rb
199
206
  - lib/usaidwat/ext/string.rb
200
207
  - lib/usaidwat/ext/time.rb
208
+ - lib/usaidwat/filter.rb
201
209
  - lib/usaidwat/formatter.rb
202
210
  - lib/usaidwat/pager.rb
203
211
  - lib/usaidwat/service.rb
204
- - lib/usaidwat/terminal.rb
205
212
  - lib/usaidwat/version.rb
206
213
  - spec/spec_helper.rb
207
214
  - spec/usaidwat/algo_spec.rb
215
+ - spec/usaidwat/array_spec.rb
208
216
  - spec/usaidwat/client_spec.rb
217
+ - spec/usaidwat/count_spec.rb
209
218
  - spec/usaidwat/either_spec.rb
219
+ - spec/usaidwat/filter_spec.rb
210
220
  - spec/usaidwat/formatter_spec.rb
211
221
  - spec/usaidwat/service_spec.rb
212
222
  - spec/usaidwat/string_spec.rb
213
- - spec/usaidwat/terminal_spec.rb
214
223
  - spec/usaidwat/time_spec.rb
215
224
  - usaidwat.gemspec
216
225
  homepage: https://github.com/mdippery/usaidwat
217
226
  licenses:
218
227
  - MIT
219
228
  metadata:
220
- build_date: 2015-11-03 19:55:52 PST
221
- commit: v1.3.0
222
- commit_hash: 2ac920497d08c42b67f40bda4e78496e1b9ad6c4
229
+ build_date: 2016-01-06 19:17:01 PST
230
+ commit: v1.4.0
231
+ commit_hash: 7ce44f2d344c06795cac025f343bd8d23f7faa95
223
232
  post_install_message:
224
233
  rdoc_options: []
225
234
  require_paths:
@@ -243,23 +252,28 @@ summary: Answers the age-old question, "Where does a Redditor comment the most?"
243
252
  test_files:
244
253
  - features/fixtures/blank.json
245
254
  - features/fixtures/mipadi.json
255
+ - features/fixtures/submissions_blank.json
256
+ - features/fixtures/submissions_mipadi.json
257
+ - features/fixtures/submissions_testuser.json
246
258
  - features/fixtures/testuser.json
247
259
  - features/fixtures/user_mipadi.json
248
260
  - features/fixtures/user_testuser.json
249
261
  - features/help.feature
250
262
  - features/log.feature
263
+ - features/posts.feature
251
264
  - features/step_definitions/reddit_steps.rb
252
265
  - features/step_definitions/time_steps.rb
253
266
  - features/support/aruba.rb
254
- - features/support/time.rb
255
267
  - features/tally.feature
256
268
  - features/user.feature
257
269
  - spec/spec_helper.rb
258
270
  - spec/usaidwat/algo_spec.rb
271
+ - spec/usaidwat/array_spec.rb
259
272
  - spec/usaidwat/client_spec.rb
273
+ - spec/usaidwat/count_spec.rb
260
274
  - spec/usaidwat/either_spec.rb
275
+ - spec/usaidwat/filter_spec.rb
261
276
  - spec/usaidwat/formatter_spec.rb
262
277
  - spec/usaidwat/service_spec.rb
263
278
  - spec/usaidwat/string_spec.rb
264
- - spec/usaidwat/terminal_spec.rb
265
279
  - spec/usaidwat/time_spec.rb