usaidwat 1.0.1 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef237332f70848558231f2efa1d72ae670c0b1d2
4
- data.tar.gz: c79816dfb00af261f512ff612330a5e86d2b46b2
3
+ metadata.gz: 04536acd69f58116dbc58388d79dea104407598c
4
+ data.tar.gz: acb24952c11f213b5677808eda93bfe65329a4b9
5
5
  SHA512:
6
- metadata.gz: f899ceb86532ec8f506f6318ac5afeeba0251b466a7c0bbe5c0289f3d9cd307924d1f63af14c408f646155dfe0d1b2299a23593568ea5b28bd069badd5177e3c
7
- data.tar.gz: a91b962fe4a7de6bcc5c4ba69b6a8c695672fad3e895b59e175880efa5b415c3b309684cfd8df80c3a892da0ae6f56af0fc72d198786a82c1a20d96b783fa856
6
+ metadata.gz: 3c6b186e4d3f45c2697e4eb6e76b46187dfc9c1217757b3d3058af9319f9bb6b6910a17cd68abc29e7e2408b4c5966da308aa61150d77de93fa1ee5ab9a93de8
7
+ data.tar.gz: 85719e6d25ad91a891fd28478cf638a85ff7fd53600dc859f6f863451aef84f34424968ffe5064ea2c93e04eebac120ad96dfc27708378ab62906abccc22f1b4
data/Rakefile CHANGED
@@ -6,10 +6,15 @@ GEMSPEC = `git ls-files | grep gemspec`.chomp
6
6
  GEM = "usaidwat-#{USaidWat::VERSION}.gem"
7
7
 
8
8
  desc "Build usaidwat.gem"
9
- task :build do
9
+ task :build => :perms do
10
10
  system "gem", "build", GEMSPEC
11
11
  end
12
12
 
13
+ desc "Ensure correct permissions for usaidwat.gem"
14
+ task :perms do
15
+ system "chmod", "-R", "a+rX", *`git ls-files`.chomp.split("\n")
16
+ end
17
+
13
18
  desc "Install usaidwat.gem"
14
19
  task :install => :build do
15
20
  system "gem", "install", GEM
data/bin/usaidwat CHANGED
@@ -1,5 +1,21 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'usaidwat'
4
+ require 'mercenary'
4
5
 
5
- USaidWat::Application.start(ARGV)
6
+ Mercenary.program(:usaidwat) do |p|
7
+ p.version USaidWat::VERSION
8
+ p.description 'Answers the age-old question, "Where does a Redditor comment the most?"'
9
+ p.syntax 'usaidwat <command> [options] <args>'
10
+
11
+ USaidWat::Application::Command.subclasses.each { |c| c.new(p) }
12
+
13
+ p.action do |args, options|
14
+ if args.empty?
15
+ puts p.to_s
16
+ exit 0
17
+ else
18
+ abort "Invalid command: #{args.first}"
19
+ end
20
+ end
21
+ end
@@ -18,6 +18,36 @@ Feature: Browse comments
18
18
  Yep. My first experience with a Heisenbug occurred in a C++ program, and disappeared when I tried to print a variable with printf (only to reappear when that call was removed).
19
19
 
20
20
 
21
+ nyc
22
+ http://www.reddit.com/r/nyc/comments/141zqc/z/c79dxg6
23
+ NYC taxi roof lights get overhaul - A light simply will mean the cab is availab
24
+ over 3 years ago
25
+
26
+ It has a fare when the lights are off.
27
+
28
+
29
+ worldnews
30
+ http://www.reddit.com/r/worldnews/comments/140mra/z/c797jq4
31
+ Palestinians win upgraded UN status by wide margin
32
+ over 3 years ago
33
+
34
+ The Judgment of Solomon Accords.
35
+ """
36
+
37
+ Scenario: List all comments with comment bodies unformatted
38
+ Given the Reddit service returns comments for the user "mipadi"
39
+ And time is frozen at Jun 24, 2015 11:05 AM
40
+ When I run `usaidwat log --raw mipadi`
41
+ Then it should pass with:
42
+ """
43
+ wikipedia
44
+ http://www.reddit.com/r/wikipedia/comments/142t4w/z/c79peed
45
+ Heisenbug: a software bug that seems to disappear or alter its behavior when one
46
+ over 3 years ago
47
+
48
+ Yep. My first experience with a Heisenbug occurred in a C++ program, and disappeared when I tried to print a variable with printf (only to reappear when that call was removed).
49
+
50
+
21
51
  nyc
22
52
  http://www.reddit.com/r/nyc/comments/141zqc/z/c79dxg6
23
53
  NYC taxi roof lights get overhaul - A light simply will mean the cab is availab
@@ -34,6 +64,54 @@ Feature: Browse comments
34
64
  The Judgment of Solomon Accords.
35
65
  """
36
66
 
67
+ Scenario: Output comments on line line
68
+ Given the Reddit service returns comments for the user "mipadi"
69
+ And time is frozen at Jun 24, 2015 11:05 AM
70
+ When I run `usaidwat log --oneline mipadi`
71
+ Then it should pass with:
72
+ """
73
+ wikipedia Heisenbug: a software bug that seems to disappear or alter its behavio
74
+ nyc NYC taxi roof lights get overhaul - A light simply will mean the cab is ava
75
+ worldnews Palestinians win upgraded UN status by wide margin
76
+ """
77
+
78
+ Scenario: Search for a specific comment
79
+ Given the Reddit service returns comments for the user "mipadi"
80
+ And time is frozen at Jun 24, 2015 11:05 AM
81
+ When I run `usaidwat log --grep='Heisenbug' mipadi`
82
+ Then it should pass with:
83
+ """
84
+ wikipedia
85
+ http://www.reddit.com/r/wikipedia/comments/142t4w/z/c79peed
86
+ Heisenbug: a software bug that seems to disappear or alter its behavior when one
87
+ over 3 years ago
88
+
89
+ Yep. My first experience with a Heisenbug occurred in a C++ program, and disappeared when I tried to print a variable with printf (only to reappear when that call was removed).
90
+ """
91
+
92
+ Scenario: Search for a specific comment with wrong case
93
+ Given the Reddit service returns comments for the user "mipadi"
94
+ And time is frozen at Jun 24, 2015 11:05 AM
95
+ When I run `usaidwat log --grep='heisenbug' mipadi`
96
+ Then it should pass with:
97
+ """
98
+ wikipedia
99
+ http://www.reddit.com/r/wikipedia/comments/142t4w/z/c79peed
100
+ Heisenbug: a software bug that seems to disappear or alter its behavior when one
101
+ over 3 years ago
102
+
103
+ Yep. My first experience with a Heisenbug occurred in a C++ program, and disappeared when I tried to print a variable with printf (only to reappear when that call was removed).
104
+ """
105
+
106
+ Scenario: Search for a specific comment with no matches
107
+ Given the Reddit service returns comments for the user "mipadi"
108
+ And time is frozen at Jun 24, 2015 11:05 AM
109
+ When I run `usaidwat log --grep='oogabooga' mipadi`
110
+ Then it should pass with:
111
+ """
112
+ mipadi has no comments matching /oogabooga/.
113
+ """
114
+
37
115
  Scenario: List all comments for a user that does not exist
38
116
  Given the Reddit service does not have a user "testuser"
39
117
  When I run `usaidwat log testuser`
@@ -50,6 +128,22 @@ Feature: Browse comments
50
128
  blank has no comments.
51
129
  """
52
130
 
131
+ Scenario: Search for a comment for a user that does not exist
132
+ Given the Reddit service does not have a user "testuser"
133
+ When I run `usaidwat log --grep='Heisenbug' testuser`
134
+ Then it should fail with:
135
+ """
136
+ No such user: testuser
137
+ """
138
+
139
+ Scenario: Search for a comment when user has no comments
140
+ Given the Reddit service returns comments for the user "blank"
141
+ When I run `usaidwat log --grep='Heisenbug' blank`
142
+ Then it should pass with:
143
+ """
144
+ blank has no comments matching /Heisenbug/.
145
+ """
146
+
53
147
  Scenario: Tally comments
54
148
  Given the Reddit service returns comments for the user "mipadi"
55
149
  When I run `usaidwat tally mipadi`
@@ -106,6 +200,22 @@ Feature: Browse comments
106
200
  blank has no comments.
107
201
  """
108
202
 
203
+ Scenario: Search for a comment when tallying
204
+ Given the Reddit service returns comments for the user "mipadi"
205
+ When I run `usaidwat tally --grep='Heisenbug' mipadi`
206
+ Then it should fail with:
207
+ """
208
+ invalid option: --grep=Heisenbug
209
+ """
210
+
211
+ Scenario: Search for a comment when sorting
212
+ Given the Reddit service returns comments for the user "mipadi"
213
+ When I run `usaidwat tally -c --grep='Heisenbug' mipadi`
214
+ Then it should fail with:
215
+ """
216
+ invalid option: --grep=Heisenbug
217
+ """
218
+
109
219
  Scenario: Sort comments when a user does not exist
110
220
  Given the Reddit service does not have a user "testuser"
111
221
  When I run `usaidwat tally testuser`
@@ -144,6 +254,34 @@ Feature: Browse comments
144
254
  You didn't slow down for very long though, did you?
145
255
  """
146
256
 
257
+ Scenario: Search in comments for a particular subreddit
258
+ Given the Reddit service returns comments for the user "mipadi"
259
+ And time is frozen at Jun 24, 2015 11:05 AM
260
+ When I run `usaidwat log --grep='New Jersey' mipadi AskReddit`
261
+ Then it should pass with:
262
+ """
263
+ AskReddit
264
+ http://www.reddit.com/r/AskReddit/comments/140t5c/z/c795nw3
265
+ I'm from Tennessee and most of our jokes are geared toward Mississippi and Alaba
266
+ over 3 years ago
267
+
268
+ You're from New Jersey? Which exit?
269
+ """
270
+
271
+ Scenario: Search in comments for a particular subreddit with wrong case
272
+ Given the Reddit service returns comments for the user "mipadi"
273
+ And time is frozen at Jun 24, 2015 11:05 AM
274
+ When I run `usaidwat log --grep='new jersey' mipadi AskReddit`
275
+ Then it should pass with:
276
+ """
277
+ AskReddit
278
+ http://www.reddit.com/r/AskReddit/comments/140t5c/z/c795nw3
279
+ I'm from Tennessee and most of our jokes are geared toward Mississippi and Alaba
280
+ over 3 years ago
281
+
282
+ You're from New Jersey? Which exit?
283
+ """
284
+
147
285
  Scenario: List comments for a particular subreddit specified with the wrong case
148
286
  Given the Reddit service returns comments for the user "mipadi"
149
287
  And time is frozen at Jun 24, 2015 11:05 AM
@@ -187,8 +325,7 @@ Feature: Browse comments
187
325
  When I run `usaidwat tally mipadi AskReddit`
188
326
  Then it should fail with:
189
327
  """
190
- ERROR: "usaidwat tally" was called with arguments ["mipadi", "AskReddit"]
191
- Usage: "usaidwat tally USERNAME"
328
+ You cannot specify a subreddit when tallying comments
192
329
  """
193
330
 
194
331
  Scenario: Sort comments with subreddit
@@ -196,16 +333,7 @@ Feature: Browse comments
196
333
  When I run `usaidwat tally -c mipadi AskReddit`
197
334
  Then it should fail with:
198
335
  """
199
- ERROR: "usaidwat tally" was called with arguments ["mipadi", "AskReddit"]
200
- Usage: "usaidwat tally USERNAME"
201
- """
202
-
203
- Scenario: Pass no arguments
204
- Given the Reddit service returns comments for the user "mipadi"
205
- When I run `usaidwat`
206
- Then it should pass with:
207
- """
208
- Commands:
336
+ You cannot specify a subreddit when tallying comments
209
337
  """
210
338
 
211
339
  Scenario: Pass no arguments when tallying
@@ -213,8 +341,7 @@ Feature: Browse comments
213
341
  When I run `usaidwat tally`
214
342
  Then it should fail with:
215
343
  """
216
- ERROR: "usaidwat tally" was called with no arguments
217
- Usage: "usaidwat tally USERNAME"
344
+ You must specify a username
218
345
  """
219
346
 
220
347
  Scenario: Pass no arguments when sorting
@@ -222,6 +349,13 @@ Feature: Browse comments
222
349
  When I run `usaidwat tally -c`
223
350
  Then it should fail with:
224
351
  """
225
- ERROR: "usaidwat tally" was called with no arguments
226
- Usage: "usaidwat tally USERNAME"
352
+ You must specify a username
353
+ """
354
+
355
+ Scenario: Pass no arguments when searching
356
+ Given the Reddit service returns comments for the user "mipadi"
357
+ When I run `usaidwat log --grep mipadi`
358
+ Then it should fail with:
359
+ """
360
+ You must specify a username
227
361
  """
@@ -4,17 +4,29 @@ Feature: Get help
4
4
  I want to be able to list help information for usaidwat
5
5
  In order to learn how to use it
6
6
 
7
+ Scenario: Pass no arguments
8
+ Given the Reddit service returns comments for the user "mipadi"
9
+ When I run `usaidwat`
10
+ Then it should pass with:
11
+ """
12
+ Usage:
13
+
14
+ usaidwat <command> [options] <args>
15
+ """
16
+
7
17
  Scenario: List usage details
8
18
  When I run `usaidwat --help`
9
19
  Then it should pass with:
10
20
  """
11
- Commands:
21
+ Usage:
22
+
23
+ usaidwat <command> [options] <args>
12
24
  """
13
25
 
14
26
  Scenario: Get version
15
27
  When I run `usaidwat --version`
16
28
  Then the exit status should be 0
17
- And the stdout should contain:
29
+ And the output should match:
18
30
  """
19
- usaidwat v
31
+ usaidwat [0-9]+\.[0-9]+\.[0-9]+
20
32
  """
@@ -1,84 +1,130 @@
1
- require 'sysexits'
2
- require 'thor'
1
+ require 'usaidwat/algo'
2
+ require 'usaidwat/client'
3
3
  require 'usaidwat/pager'
4
+ require 'sysexits'
4
5
 
5
6
  module USaidWat
6
- class Application < Thor
7
- include Pager
8
- include Sysexits
7
+ module Application
8
+ class Command
9
+ include Pager
10
+ include Sysexits
11
+
12
+ attr_reader :client
13
+
14
+ class << self
15
+ def subclasses
16
+ @subclasses ||= []
17
+ end
9
18
 
10
- class << self
11
- def client
12
- ENV['USAIDWAT_ENV'] == 'cucumber' ? USaidWat::Client::TestRedditor : USaidWat::Client::Redditor
19
+ def inherited(base)
20
+ subclasses << base
21
+ super
22
+ end
13
23
  end
14
24
 
15
- def exit_on_failure?
16
- true
25
+ def initialize(prog)
26
+ @client = cucumber? ? USaidWat::Client::TestRedditor : USaidWat::Client::Redditor
17
27
  end
18
- end
19
28
 
20
- map '--version' => :version
21
- map 't' => :tally
22
- map 'l' => :log
23
-
24
- desc 'tally USERNAME', 'Count comments by subreddit'
25
- option :count, :aliases => '-c', :type => :boolean, :desc => 'Sort output by number of comments'
26
- def tally(username)
27
- redditor = Application.client.new(username)
28
- algo_cls = options[:count] ? USaidWat::Algorithms::CountAlgorithm : USaidWat::Algorithms::LexicographicalAlgorithm
29
- quit "#{redditor.username} has no comments." if redditor.comments.empty?
30
- # Unfortunately Snooby cannot return comments for a specific
31
- # user in a specific subreddit, so for now we have to sort them
32
- # ourself.
33
- longest_subreddit = 0
34
- buckets = Hash.new { |hash, key| hash[key] = 0 }
35
- redditor.comments.each do |comment|
36
- subreddit = comment.subreddit
37
- longest_subreddit = subreddit.length if subreddit.length > longest_subreddit
38
- buckets[subreddit] += 1
29
+ protected
30
+
31
+ def cucumber?
32
+ ENV['USAIDWAT_ENV'] == 'cucumber'
39
33
  end
40
- algo = algo_cls.new(buckets)
41
- subreddits = buckets.keys.sort { |a,b| algo.sort(a, b) }
42
- subreddits.each do |subreddit|
43
- tally = buckets[subreddit]
44
- printf "%-*s %3d\n", longest_subreddit, subreddit, tally
34
+
35
+ def quit(message, code=:ok)
36
+ puts message
37
+ exit code
45
38
  end
46
- rescue USaidWat::Client::NoSuchUserError
47
- quit "No such user: #{username}", :no_such_user
48
39
  end
49
40
 
50
- desc 'log USERNAME [SUBREDDIT]', 'Show comments by a user'
51
- def log(username, subreddit = nil)
52
- redditor = Application.client.new(username)
53
- if subreddit
41
+ class Log < Command
42
+ def initialize(prog)
43
+ prog.command(:log) do |c|
44
+ c.alias :l
45
+ c.option 'grep', '--grep STRING', 'Show only comments matching STRING'
46
+ c.option 'oneline', '--oneline', 'Output log in a more comptact form'
47
+ c.option 'raw', '--raw', 'Print raw comment bodies'
48
+
49
+ c.action do |args, options|
50
+ process(options, args)
51
+ end
52
+ end
53
+ super
54
+ end
55
+
56
+ def process(options, args)
57
+ raise ArgumentError.new('You must specify a username') if args.empty?
58
+ username = args.shift
59
+ subreddit = args.shift
60
+
61
+ redditor = client.new(username)
54
62
  comments = redditor.comments
55
- comments = comments.group_by { |c| c.subreddit.downcase }
56
- comments = comments[subreddit.downcase]
57
- quit "No comments by #{redditor.username} for #{subreddit}." if comments.nil?
58
- list_comments(comments)
59
- else
60
- quit "#{redditor.username} has no comments." if redditor.comments.empty?
61
- list_comments(redditor.comments)
63
+ if subreddit
64
+ comments = comments.group_by { |c| c.subreddit.downcase }
65
+ comments = comments[subreddit.downcase]
66
+ quit "No comments by #{redditor.username} for #{subreddit}." if comments.nil?
67
+ end
68
+ comments = comments.select { |c| c.body =~ /#{options['grep']}/i } if options['grep']
69
+ if comments.empty?
70
+ msg = "#{redditor.username} has no comments"
71
+ msg = "#{msg} matching /#{options['grep']}/" if options['grep']
72
+ msg = "#{msg}."
73
+ quit msg
74
+ end
75
+ list_comments(comments, options['grep'], !options['oneline'].nil?, !options['raw'].nil?)
76
+ rescue USaidWat::Client::NoSuchUserError
77
+ quit "No such user: #{username}", :no_such_user
62
78
  end
63
- rescue USaidWat::Client::NoSuchUserError
64
- quit "No such user: #{username}", :no_such_user
65
- end
66
79
 
67
- desc 'version', 'Show version info and exit'
68
- def version
69
- puts "usaidwat v#{USaidWat::VERSION}"
70
- end
80
+ private
71
81
 
72
- no_commands do
73
- def list_comments(comments)
74
- formatter = USaidWat::CLI::CommentFormatter.new
82
+ def list_comments(comments, pattern = nil, oneline = false, raw = false)
83
+ formatter = (oneline ? USaidWat::CLI::CompactCommentFormatter : USaidWat::CLI::CommentFormatter).new(pattern, raw)
75
84
  page
76
85
  comments.each { |c| print formatter.format(c) }
77
86
  end
87
+ end
78
88
 
79
- def quit(message, code=:ok)
80
- puts message
81
- exit code
89
+ class Tally < Command
90
+ def initialize(prog)
91
+ prog.command(:tally) do |c|
92
+ c.alias :t
93
+ c.option 'count', '-c', '--count', 'Sort output by number of comments'
94
+
95
+ c.action do |args, options|
96
+ process(options, args)
97
+ end
98
+ end
99
+ super
100
+ end
101
+
102
+ def process(options, args)
103
+ raise ArgumentError.new('You must specify a username') if args.empty?
104
+ raise ArgumentError.new('You cannot specify a subreddit when tallying comments') if args.count > 1
105
+ username = args.first
106
+
107
+ redditor = client.new(username)
108
+ algo_cls = options['count'] ? USaidWat::Algorithms::CountAlgorithm : USaidWat::Algorithms::LexicographicalAlgorithm
109
+ quit "#{redditor.username} has no comments." if redditor.comments.empty?
110
+ # Unfortunately Snooby cannot return comments for a specific
111
+ # user in a specific subreddit, so for now we have to sort them
112
+ # ourself.
113
+ longest_subreddit = 0
114
+ buckets = Hash.new { |hash, key| hash[key] = 0 }
115
+ redditor.comments.each do |comment|
116
+ subreddit = comment.subreddit
117
+ longest_subreddit = subreddit.length if subreddit.length > longest_subreddit
118
+ buckets[subreddit] += 1
119
+ end
120
+ algo = algo_cls.new(buckets)
121
+ subreddits = buckets.keys.sort { |a,b| algo.sort(a, b) }
122
+ subreddits.each do |subreddit|
123
+ tally = buckets[subreddit]
124
+ printf "%-*s %3d\n", longest_subreddit, subreddit, tally
125
+ end
126
+ rescue USaidWat::Client::NoSuchUserError
127
+ quit "No such user: #{username}", :no_such_user
82
128
  end
83
129
  end
84
130
  end
@@ -1,12 +1,10 @@
1
+ require 'rainbow'
2
+
1
3
  class String
2
4
  def truncate(width)
3
5
  self[0, width]
4
6
  end
5
7
 
6
- def convert_entities
7
- self.gsub(/&gt;/, '>').gsub(/&lt;/, '<').gsub(/&amp;/, '&')
8
- end
9
-
10
8
  def pluralize(n, suffix = 's', singular_suffix = '')
11
9
  if n == 1
12
10
  self + singular_suffix
@@ -14,4 +12,8 @@ class String
14
12
  self + suffix
15
13
  end
16
14
  end
15
+
16
+ def highlight(pattern)
17
+ gsub(/#{pattern}/i) { |m| Rainbow(m).red }
18
+ end
17
19
  end
@@ -1,7 +1,9 @@
1
1
  require 'date'
2
+ require 'downterm'
2
3
  require 'highline'
3
- require 'stringio'
4
4
  require 'rainbow/ext/string'
5
+ require 'redcarpet'
6
+ require 'stringio'
5
7
  require 'usaidwat/ext/string'
6
8
  require 'usaidwat/ext/time'
7
9
 
@@ -9,27 +11,58 @@ Rainbow.enabled = true unless ENV['USAIDWAT_ENV'] == 'cucumber'
9
11
 
10
12
  module USaidWat
11
13
  module CLI
12
- class CommentFormatter
13
- def initialize
14
+ class BaseFormatter
15
+ attr_reader :pattern
16
+
17
+ def initialize(pattern = nil, raw = false)
18
+ @pattern = pattern
19
+ @raw = raw
14
20
  @count = 0
15
21
  end
16
-
22
+
23
+ def pattern?
24
+ !@pattern.nil?
25
+ end
26
+
27
+ def raw?
28
+ @raw
29
+ end
30
+ end
31
+
32
+ class CommentFormatter < BaseFormatter
33
+ def initialize(pattern = nil, raw = false)
34
+ @markdown = Redcarpet::Markdown.new(Downterm::Render::Terminal, :autolink => true,
35
+ :strikethrough => true,
36
+ :superscript => true)
37
+ super
38
+ end
39
+
17
40
  def format(comment)
18
41
  cols = HighLine::SystemExtensions.terminal_size[0]
19
42
  out = StringIO.new
20
43
  out.write("\n\n") unless @count == 0
21
44
  out.write("#{comment.subreddit}\n".color(:green))
22
45
  out.write("#{comment_link(comment)}\n".color(:yellow))
23
- out.write("#{comment.link_title.strip.truncate(cols)}\n".color(:red))
46
+ out.write("#{comment.link_title.strip.truncate(cols)}\n".color(:magenta))
24
47
  out.write("#{comment_date(comment)}\n".color(:blue))
25
48
  out.write("\n")
26
- out.write("#{comment.body.strip.convert_entities}\n")
49
+ out.write("#{comment_body(comment)}\n")
27
50
  @count += 1
28
51
  out.rewind
29
52
  out.read
30
53
  end
31
54
 
32
55
  private
56
+ def comment_body(comment)
57
+ body = comment.body
58
+ body = @markdown.render(body) unless raw?
59
+ if pattern?
60
+ body.highlight(pattern)
61
+ else
62
+ body
63
+ end
64
+ end
65
+
33
66
  def comment_link(comment)
34
67
  link = comment.link_id.split("_")[-1]
35
68
  "http://www.reddit.com/r/#{comment.subreddit}/comments/#{link}/z/#{comment.id}"
@@ -39,5 +72,18 @@ module USaidWat
39
72
  DateTime.strptime(comment.created_utc.to_s, "%s").to_time.localtime.ago
40
73
  end
41
74
  end
75
+
76
+ class CompactCommentFormatter < BaseFormatter
77
+ def format(comment)
78
+ cols = HighLine::SystemExtensions.terminal_size[0]
79
+ out = StringIO.new
80
+ subreddit = comment.subreddit
81
+ cols -= subreddit.length + 1
82
+ out.write("#{subreddit}".color(:green))
83
+ out.write(" #{comment.link_title.strip.truncate(cols)}\n")
84
+ out.rewind
85
+ out.read
86
+ end
87
+ end
42
88
  end
43
89
  end
@@ -1,3 +1,3 @@
1
1
  module USaidWat
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -72,5 +72,28 @@ EXPECTED
72
72
  end
73
73
  end
74
74
  end
75
+
76
+ describe CompactCommentFormatter do
77
+ let (:formatter) { CompactCommentFormatter.new }
78
+
79
+ before do
80
+ Timecop.freeze(Time.new(2015, 6, 16, 17, 8))
81
+ end
82
+
83
+ after do
84
+ Timecop.return
85
+ end
86
+
87
+ describe "#format" do
88
+ it "should return a string containing the formatted comment" do
89
+ comment = double("comment")
90
+ expect(comment).to receive(:subreddit).and_return("programming")
91
+ expect(comment).to receive(:link_title).and_return("Why Brit Ruby 2013 was cancelled and why this is not ok - Gist")
92
+ expected = "programming Why Brit Ruby 2013 was cancelled and why this is not ok - Gist\n"
93
+ actual = formatter.format(comment).delete_ansi_color_codes
94
+ expect(actual).to eq(expected)
95
+ end
96
+ end
97
+ end
75
98
  end
76
99
  end
@@ -1,38 +1,9 @@
1
+ require 'rainbow'
1
2
  require 'spec_helper'
2
3
 
3
4
  module USaidWat
4
5
  module Ext
5
6
  describe String do
6
- describe "#convert_entities" do
7
- it "converts &gt; to >" do
8
- s = "-&gt; look at this!"
9
- expected = "-> look at this!"
10
- actual = s.convert_entities
11
- expect(actual).to eq(expected)
12
- end
13
-
14
- it "converts &lt; to <" do
15
- s = "left &lt;&lt; shift!"
16
- expected = "left << shift!"
17
- actual = s.convert_entities
18
- expect(actual).to eq(expected)
19
- end
20
-
21
- it "converts both &gt; and &lt; to > and <" do
22
- s = "look -&gt; this string has both &lt;- awesome, huh?"
23
- expected = "look -> this string has both <- awesome, huh?"
24
- actual = s.convert_entities
25
- expect(actual).to eq(expected)
26
- end
27
-
28
- it "converts &amp; to &" do
29
- s = "i like cake &amp; ice cream"
30
- expected = "i like cake & ice cream"
31
- actual = s.convert_entities
32
- expect(actual).to eq(expected)
33
- end
34
- end
35
-
36
7
  describe "#truncate" do
37
8
  it "truncates strings longer than the given width to the width" do
38
9
  n = 80
@@ -74,6 +45,43 @@ module USaidWat
74
45
  expect(s.pluralize(1, "ies", "y")).to eq("poppy")
75
46
  end
76
47
  end
48
+
49
+ describe "#highlight" do
50
+ it "should highlight matching parts of strings" do
51
+ s = "apple pie is made from apples"
52
+ expected = "#{Rainbow("apple").red} pie is made from #{Rainbow("apple").red}s"
53
+ actual = s.highlight("apple")
54
+ expect(actual).to eq(expected)
55
+ end
56
+
57
+ it "should return an identical string if no matches are found" do
58
+ s = "apple pie is made from apples"
59
+ expected = s.dup
60
+ actual = s.highlight("cherry")
61
+ expect(actual).to eq(expected)
62
+ end
63
+
64
+ it "should match parts insensitive to case" do
65
+ s = "Apple pie is made from Apples"
66
+ expected = "#{Rainbow("Apple").red} pie is made from #{Rainbow("Apple").red}s"
67
+ actual = s.highlight("apple")
68
+ expect(actual).to eq(expected)
69
+ end
70
+
71
+ it "should highlight matching parts of strings using a regex-like string" do
72
+ s = "pears are tastier than bears"
73
+ expected = "#{Rainbow("pears").red} are tastier than #{Rainbow("bears").red}"
74
+ actual = s.highlight("[b|p]ears")
75
+ expect(actual).to eq(expected)
76
+ end
77
+
78
+ it "should highlight matching parts of strings using an actual regex" do
79
+ s = "pears are tastier than bears"
80
+ expected = "#{Rainbow("pears").red} are tastier than #{Rainbow("bears").red}"
81
+ actual = s.highlight(/[b|p]ears/)
82
+ expect(actual).to eq(expected)
83
+ end
84
+ end
77
85
  end
78
86
  end
79
87
  end
data/usaidwat.gemspec CHANGED
@@ -1,6 +1,8 @@
1
1
  # -*- encoding: utf-8 -*-
2
+
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
4
6
  require 'usaidwat/version'
5
7
 
6
8
  Gem::Specification.new do |gem|
@@ -13,20 +15,27 @@ Gem::Specification.new do |gem|
13
15
  gem.description = %q{View a user's last 100 Reddit comments, organized by subreddit.}
14
16
  gem.summary = %q{Answers the age-old question, "Where does a Redditor comment the most?"}
15
17
 
18
+ gem.metadata = {
19
+ 'build_date' => Time.now.strftime("%Y-%m-%d %H:%M:%S.%L %Z"),
20
+ }
21
+
16
22
  gem.files = `git ls-files`.split($/)
17
23
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
24
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
25
  gem.require_paths = ["lib"]
20
26
 
27
+ gem.required_ruby_version = '>= 1.9.3'
28
+
29
+ gem.add_runtime_dependency('downterm', '~> 0.1.0')
21
30
  gem.add_runtime_dependency('highline', '~> 1.7')
31
+ gem.add_runtime_dependency('mercenary', '~> 0.3.5')
22
32
  gem.add_runtime_dependency('rainbow', '~> 2.0')
23
33
  gem.add_runtime_dependency('snooby', '~> 0.1.5')
24
34
  gem.add_runtime_dependency('sysexits', '~> 1.2')
25
- gem.add_runtime_dependency('thor', '~> 0.19.1')
26
35
 
27
- gem.add_development_dependency('aruba', '~> 0.8.1')
36
+ gem.add_development_dependency('aruba', '~> 0.9.0')
28
37
  gem.add_development_dependency('cucumber', '~> 2.0')
29
38
  gem.add_development_dependency('rspec', '~> 3.2')
30
- gem.add_development_dependency('timecop', '~> 0.7.4')
39
+ gem.add_development_dependency('timecop', '~> 0.8.0')
31
40
  gem.add_development_dependency('webmock', '~> 1.21')
32
41
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usaidwat
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.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-08-20 00:00:00.000000000 Z
11
+ date: 2015-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: downterm
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: highline
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -25,75 +39,75 @@ dependencies:
25
39
  - !ruby/object:Gem::Version
26
40
  version: '1.7'
27
41
  - !ruby/object:Gem::Dependency
28
- name: rainbow
42
+ name: mercenary
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '2.0'
47
+ version: 0.3.5
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '2.0'
54
+ version: 0.3.5
41
55
  - !ruby/object:Gem::Dependency
42
- name: snooby
56
+ name: rainbow
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: 0.1.5
61
+ version: '2.0'
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: 0.1.5
68
+ version: '2.0'
55
69
  - !ruby/object:Gem::Dependency
56
- name: sysexits
70
+ name: snooby
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '1.2'
75
+ version: 0.1.5
62
76
  type: :runtime
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '1.2'
82
+ version: 0.1.5
69
83
  - !ruby/object:Gem::Dependency
70
- name: thor
84
+ name: sysexits
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: 0.19.1
89
+ version: '1.2'
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: 0.19.1
96
+ version: '1.2'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: aruba
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 0.8.1
103
+ version: 0.9.0
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 0.8.1
110
+ version: 0.9.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: cucumber
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +142,14 @@ dependencies:
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: 0.7.4
145
+ version: 0.8.0
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: 0.7.4
152
+ version: 0.8.0
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: webmock
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -194,7 +208,8 @@ files:
194
208
  homepage: https://github.com/mdippery/usaidwat
195
209
  licenses:
196
210
  - MIT
197
- metadata: {}
211
+ metadata:
212
+ build_date: 2015-08-27 18:54:51.726 PDT
198
213
  post_install_message:
199
214
  rdoc_options: []
200
215
  require_paths:
@@ -203,7 +218,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
203
218
  requirements:
204
219
  - - ">="
205
220
  - !ruby/object:Gem::Version
206
- version: '0'
221
+ version: 1.9.3
207
222
  required_rubygems_version: !ruby/object:Gem::Requirement
208
223
  requirements:
209
224
  - - ">="