console_table 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ad359bbbe8957d51f799ac7761138ce6298c242
4
- data.tar.gz: 33e4d6d67e2405a9915d7368b32d572e27f4575a
3
+ metadata.gz: 626c1c75fc83f5be630b35551e96d9bd318f41e5
4
+ data.tar.gz: c7b122ba03999438a6408ea10ac15c3c1dc7adc1
5
5
  SHA512:
6
- metadata.gz: ca996310196d283a334171530e68b93922bff9bf2e4ac5bf2a00870a469f597ebcd8cd3cb9273e21c32add989513808df3e913270a28e3f4398eb00e1ca77414
7
- data.tar.gz: 69d0c16af724898caa200b825b3ea4c0c2fd92fe1809b969649120002f59a662bac0c16c1857c777ebe84a34ca379902da00eda03335eda328976c41dcfae7ae
6
+ metadata.gz: a5711b3beebcd41a3e353d2a3e3b842316e2201320f52a92e69fab8ac95badda818eda8d475c0cbfd6c03e285b9d18d2f6c05cd71db12300fdb73bfc164c13b1
7
+ data.tar.gz: 1f4f0a647a7db4da4b4cbd9b691b6ef9d7d4a03cd58bec59e366fe5cf83f10a44dea6d183176da40438d818b07ff18b517550e2fd2fb995c3600b2a0f58ea64a
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ deploy:
5
+ provider: rubygems
6
+ api_key:
7
+ secure: M1I+7IFuje77sZjtQbmvamzihT+NEJpCzb6Eco8AKbJu/swim+2DvojdJHJw3qpjBt+S2u6zPWWc8KqP6ME7YZzydhJKN/rftUow4lyPbJ6ut9wNg4J9EaZgawG/BOm7LESqtj6J5KWrEd2qRn86mLMHO6ZgLsvsKBWR+oMnb+U=
8
+ gem: console_table
9
+ on:
10
+ tags: true
11
+ repo: rodhilton/console_table
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # ConsoleTable
2
2
 
3
+ [![Build Status](https://travis-ci.org/rodhilton/console_table.svg?branch=master)](https://travis-ci.org/rodhilton/console_table)
4
+
3
5
  ConsoleTable is a helper class that allows you to print data to a console in a clean, table-like fashion. It's intended for use
4
6
  in commandline applications with information-dense output. It checks your terminal window size (or COLUMNS environment variable) to ensure
5
7
  your data will fit, allows you to define table column sizes, and then just supply the ConsoleTable instance with data which will be
@@ -243,10 +245,137 @@ end
243
245
 
244
246
  Note the alternative method of calling `<<` where you can supply an Array instead of a hash, and ConsoleTable will infer from the array order which value goes in what column
245
247
 
248
+ Here's a somewhat more practical example:
249
+
250
+ ```ruby
251
+ require 'console_table'
252
+
253
+ require 'json'
254
+ require 'net/http'
255
+ require 'open-uri'
256
+ require 'colorize'
257
+
258
+ symbols = ["YHOO", "AAPL", "GOOG", "MSFT", "C", "MMM", "KO", "WMT", "GM", "IBM", "MCD", "VZ", "HD", "DIS", "INTC"]
259
+
260
+ params = symbols.collect{|s| "\"#{s}\"" }.join(",")
261
+ url = "http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.quotes where symbol in (#{params})&env=http://datatables.org/alltables.env&format=json"
262
+ uri = URI.parse(URI::encode(url))
263
+ response = Net::HTTP.get_response(uri)
264
+ json = JSON.parse(response.body)
265
+
266
+ table_config = [
267
+ {:key=>:symbol, :title=>"Symbol", :size=>6},
268
+ {:key=>:name, :title=>"Name", :size=>17},
269
+ {:key=>:price, :title=>"Price", :size=>5, :justify=>:right},
270
+ {:key=>:change, :title=>"Change", :size=>7, :justify=>:right},
271
+ {:key=>:recommendation, :title=>"Recommendation", :size=>15, :justify=>:right}
272
+ ]
273
+
274
+ ConsoleTable.define(table_config, :title=>"Stock Prices") do |table|
275
+
276
+ json["query"]["results"]["quote"].each do |j|
277
+ change = j["ChangeRealtime"]
278
+ if change.start_with?("+")
279
+ change = change.green
280
+ else
281
+ change = change.red
282
+ end
283
+
284
+ recommendation = (rand() <= 0.5) ? "BUY!".white.on_green.bold.underline : "Sell".yellow
285
+
286
+ table << [
287
+ j["Symbol"].magenta,
288
+ j["Name"],
289
+ j["LastTradePriceOnly"],
290
+ change,
291
+ recommendation
292
+ ]
293
+
294
+ end
295
+
296
+ table.footer << "Recommendations randomly generated"
297
+
298
+ end
299
+ ```
300
+
301
+ And the output:
302
+
303
+ ```
304
+ ======================================================
305
+ Stock Prices
306
+ Symbol Name Price Change Recommendation
307
+ ------------------------------------------------------
308
+ YHOO Yahoo! Inc. 44.42 +0.495 Sell
309
+ AAPL Apple Inc. 127.0 +0.62 BUY!
310
+ GOOG Google Inc. 549.0 +6.08 BUY!
311
+ MSFT Microsoft Corpora 43.87 +0.78 Sell
312
+ C Citigroup, Inc. C 51.20 +0.31 BUY!
313
+ MMM 3M Company Common 165.9 +0.03 Sell
314
+ KO Coca-Cola Company 41.99 -0.18 BUY!
315
+ WMT Wal-Mart Stores, 85.81 -0.08 Sell
316
+ GM General Motors Co 37.62 -0.40 BUY!
317
+ IBM International Bus 160.4 +1.88 BUY!
318
+ MCD MCDONALD'S CORPOR 95.65 +0.56 BUY!
319
+ VZ Verizon Communica 49.31 -0.21 BUY!
320
+ HD Home Depot, Inc. 111.8 -0.27 BUY!
321
+ DIS Walt Disney Compa 104.1 +0.59 BUY!
322
+ INTC Intel Corporation 34.36 +0.235 Sell
323
+ ------------------------------------------------------
324
+ Recommendations randomly generated
325
+ ======================================================
326
+ ```
327
+
328
+ And yes, you can make the table super-ugly and lame if you want by adding `:borders=>true` to the define call, like so:
329
+
330
+ `ConsoleTable.define(table_config, :title=>"Stock Prices", :borders=>true) do |table|`
331
+
332
+ Which will yield this, if you're into that sort of thing:
333
+
334
+ ```
335
+ *======================================================*
336
+ | Stock Prices |
337
+ +------+-----------------+-----+-------+---------------+
338
+ |Symbol|Name |Price| Change| Recommendation|
339
+ +------+-----------------+-----+-------+---------------+
340
+ |YHOO |Yahoo! Inc. |44.42| +0.495| BUY!|
341
+ +------+-----------------+-----+-------+---------------+
342
+ |AAPL |Apple Inc. |127.0| +0.62| BUY!|
343
+ +------+-----------------+-----+-------+---------------+
344
+ |GOOG |Google Inc. |549.0| +6.08| Sell|
345
+ +------+-----------------+-----+-------+---------------+
346
+ |MSFT |Microsoft Corpora|43.87| +0.78| Sell|
347
+ +------+-----------------+-----+-------+---------------+
348
+ |C |Citigroup, Inc. C|51.20| +0.31| Sell|
349
+ +------+-----------------+-----+-------+---------------+
350
+ |MMM |3M Company Common|165.9| +0.03| BUY!|
351
+ +------+-----------------+-----+-------+---------------+
352
+ |KO |Coca-Cola Company|41.99| -0.18| Sell|
353
+ +------+-----------------+-----+-------+---------------+
354
+ |WMT |Wal-Mart Stores, |85.81| -0.08| BUY!|
355
+ +------+-----------------+-----+-------+---------------+
356
+ |GM |General Motors Co|37.62| -0.40| BUY!|
357
+ +------+-----------------+-----+-------+---------------+
358
+ |IBM |International Bus|160.4| +1.88| BUY!|
359
+ +------+-----------------+-----+-------+---------------+
360
+ |MCD |MCDONALD'S CORPOR|95.65| +0.56| Sell|
361
+ +------+-----------------+-----+-------+---------------+
362
+ |VZ |Verizon Communica|49.31| -0.21| BUY!|
363
+ +------+-----------------+-----+-------+---------------+
364
+ |HD |Home Depot, Inc. |111.8| -0.27| BUY!|
365
+ +------+-----------------+-----+-------+---------------+
366
+ |DIS |Walt Disney Compa|104.1| +0.59| BUY!|
367
+ +------+-----------------+-----+-------+---------------+
368
+ |INTC |Intel Corporation|34.36| +0.235| Sell|
369
+ +------+-----------------+-----+-------+---------------+
370
+ | Recommendations randomly generated|
371
+ *======================================================*
372
+ ```
373
+
374
+
246
375
  ## Contributing
247
376
 
248
377
  1. Fork it ( http://github.com/rodhilton/console_table/fork )
249
378
  2. Create your feature branch (`git checkout -b my-new-feature`)
250
379
  3. Commit your changes (`git commit -am 'Add some feature'`)
251
380
  4. Push to the branch (`git push origin my-new-feature`)
252
- 5. Create new Pull Request
381
+ 5. Create new Pull Request
@@ -19,7 +19,6 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_development_dependency "bundler", "~> 1.5"
21
21
  spec.add_development_dependency 'rake', '~> 0'
22
- spec.add_development_dependency 'simplecov', '~> 0.9'
23
22
  spec.add_development_dependency 'minitest', '~> 5.5'
24
23
  spec.add_development_dependency 'colorize', '~> 0.7'
25
24
 
data/lib/console_table.rb CHANGED
@@ -1,7 +1,5 @@
1
- require 'terminfo'
2
-
3
1
  module ConsoleTable
4
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
5
3
 
6
4
  def self.define(layout, options={}, &block)
7
5
  table = ConsoleTableClass.new(layout, options)
@@ -11,7 +9,6 @@ module ConsoleTable
11
9
  end
12
10
 
13
11
  class ConsoleTableClass
14
-
15
12
  attr_reader :footer
16
13
 
17
14
  def <<(options)
@@ -21,13 +18,29 @@ module ConsoleTable
21
18
  protected
22
19
 
23
20
  def initialize(column_layout, options={})
24
- @original_column_layout = column_layout
25
- @left_margin = options[:left_margin] || 0
26
- @right_margin = options[:right_margin] || 0
21
+ @original_column_layout = []
22
+ column_layout.each_with_index do |layout, i|
23
+ if layout.is_a? String
24
+ @original_column_layout << {:key => "col#{i+1}".to_sym, :title=>layout, :size=>"*"}
25
+ elsif layout[:key].nil? and layout[:title].nil?
26
+ @original_column_layout << layout.merge({:key => "col#{i+1}".to_sym, :title=>"Column #{i+1}"})
27
+ elsif layout[:title].nil?
28
+ @original_column_layout << layout.merge({:title => layout[:key].to_s.capitalize})
29
+ elsif layout[:key].nil?
30
+ @original_column_layout << layout.merge({:key => "col#{i+1}".to_sym})
31
+ else
32
+ @original_column_layout << layout
33
+ end
34
+ end
35
+
36
+ #Mostly used for mocking/testing
27
37
  @out = options[:output] || $stdout
28
- @title = options[:title]
29
38
  @set_width = options[:width]
39
+
40
+ @title = options[:title]
30
41
  @borders = options[:borders] || false #Lines between every cell, implies outline
42
+ @left_margin = options[:left_margin] || 0
43
+ @right_margin = options[:right_margin] || 0
31
44
 
32
45
  #Set outline, just the upper and lower lines
33
46
  if @borders
@@ -39,7 +52,6 @@ module ConsoleTable
39
52
  end
40
53
 
41
54
  @footer = []
42
-
43
55
  @headings_printed = false
44
56
  @count = 0
45
57
 
@@ -48,6 +60,8 @@ module ConsoleTable
48
60
  end
49
61
 
50
62
  def print_header()
63
+ #Kind of weird but basically if there's a title, there will be a space between the top border and the actual data, meaning we don't
64
+ #want special characters printed for the "joining" of the lines. If there's no title, however, we do.
51
65
  if @title.nil?
52
66
  print_line("=", "*", false)
53
67
  else
@@ -66,6 +80,7 @@ module ConsoleTable
66
80
 
67
81
  def print_headings()
68
82
  @headings_printed = true
83
+
69
84
  @out.print " "*@left_margin
70
85
  if @borders
71
86
  @out.print "|"
@@ -73,8 +88,9 @@ module ConsoleTable
73
88
 
74
89
  @column_widths.each_with_index do |column, i|
75
90
  justify = column[:justify] || :left
76
- title = (column[:title] || column[:key].to_s.capitalize).strip
77
- @out.print format(column[:size], title, false, justify)
91
+ ellipsize = column[:ellipsize] || false
92
+ title = column[:title].strip
93
+ @out.print format(column[:size], title, ellipsize, justify)
78
94
 
79
95
  if @borders
80
96
  @out.print "|"
@@ -84,7 +100,7 @@ module ConsoleTable
84
100
  end
85
101
  @out.print "\n"
86
102
 
87
- print_line unless @borders #this line will be printed when the NEXT LINE prints out if borders are on
103
+ print_line unless @borders #this line will be printed when the NEXT LINE of actual data prints out if borders are on, because that call PRE-prints the separator line
88
104
  end
89
105
 
90
106
  def print_line(char="-", join_char="+", edge_join_only=false)
@@ -107,6 +123,8 @@ module ConsoleTable
107
123
  end
108
124
  end
109
125
 
126
+ #TODO: it's a little weird how, if a footer is too long, it simply doesn't print at all. This seems like not what someone would want to have happen.
127
+ #Could we take footer lines and split them every X characters where X is the working width, then use those? Long lines effectively wrap, but not on word boundaries
110
128
  def print_footer()
111
129
  if should_print_footer
112
130
  print_line
@@ -220,9 +238,7 @@ module ConsoleTable
220
238
  if string.nil?
221
239
  nil
222
240
  else
223
- require 'pp'
224
241
  normalized = string.to_s
225
-
226
242
  normalized = normalized.sub(/^(\e\[\d[^m]*?m)(\s+)/, '\2\1') #Any leading spaces preceeded by a color code should be swapped with the color code itself, so the spaces themselves aren't colored
227
243
  normalized = normalized.sub(/(\s+)(\e\[\d[^m]*?m)$/, '\2\1')
228
244
  normalized = normalized.gsub(/\s+/, " ").strip #Primarily to remove any tabs or newlines
@@ -235,12 +251,15 @@ module ConsoleTable
235
251
 
236
252
  total_width = @set_width
237
253
  begin
254
+ require 'terminfo'
238
255
  total_width = TermInfo.screen_columns
239
256
  rescue => ex
240
257
  total_width = ENV["COLUMNS"].to_i || 79
241
258
  end if total_width.nil?
242
259
 
243
- keys = @original_column_layout.reject { |d| d[:key].nil? }.collect { |d| d[:key] }.uniq
260
+ working_column_layout = []
261
+
262
+ keys = @original_column_layout.collect { |d| d[:key] }.uniq
244
263
  if keys.length < @original_column_layout.length
245
264
  raise("ConsoleTable configuration invalid, same key defined more than once")
246
265
  end
@@ -300,7 +319,7 @@ module ConsoleTable
300
319
 
301
320
  parts = text.scan(/(\e\[\d.*?m)|(.)/) #The idea here is to break the string up into control codes and single characters
302
321
  #We're going to now count up until we hit goal length, but we're not going to ever count control codes against the count
303
- #We're also going to keep track of if the last thing was a color code, so we know to reset if a color is "active"
322
+ #We're also going to keep track of if a non-resetting control code is 'active', so we know to reset at the end if need-be
304
323
 
305
324
  #I can't think of a better way to do this, it's probably dumb
306
325
  current_length = 0
@@ -331,15 +350,15 @@ module ConsoleTable
331
350
 
332
351
  final_string_parts.join("")
333
352
  else
353
+ space = length-uncolorized.length
334
354
  if justify == :right
335
- (" "*(length-uncolorized.length)) + text
355
+ (" "*space) + text
336
356
  elsif justify == :center
337
- space = length-uncolorized.length
338
357
  left_side = space/2
339
358
  right_side = space - left_side
340
359
  (" " * left_side) + text + (" "*right_side)
341
360
  else #assume left
342
- text + (" "*(length-uncolorized.length))
361
+ text + (" "*space)
343
362
  end
344
363
  end
345
364
  end
@@ -1,13 +1,12 @@
1
+ # encoding: utf-8
1
2
  require 'minitest/autorun'
2
- require 'console_table'
3
- require 'colorize'
4
-
5
- #TODO: What happens if you have a linebreak in what you print?
6
- # - what if it occurs inside of an active color code?
7
3
  #TODO: trimming from different sides depending on justification?
8
4
 
9
5
  class ConsoleTableTest < Minitest::Test
10
6
 
7
+ require 'console_table'
8
+ require 'colorize'
9
+
11
10
  def setup
12
11
  @mock_out = StringIO.new
13
12
  end
@@ -960,6 +959,74 @@ Much mu... Normal,... Much mu...
960
959
  assert_output_equal expected, @mock_out.string
961
960
  end
962
961
 
962
+ def test_will_generate_default_column_keys_and_titles_and_sizes_if_not_provided
963
+ table_config = [
964
+ {:size=>20, :title=>"Column 1"},
965
+ {:key=>:col2, :size=>20, :title=>"Column 2"},
966
+ {:size=>20, :title=>"Column 3"},
967
+ {:key=>:col4, :size=>20},
968
+ {:size=>20},
969
+ {}
970
+ ]
971
+
972
+ ConsoleTable.define(table_config, :width=> 125, :output=>@mock_out) do |table|
973
+ table << ["A", "B", "C", "D", "E", "F"]
974
+
975
+ end
976
+
977
+ expected=<<-END
978
+ =============================================================================================================================
979
+ Column 1 Column 2 Column 3 Col4 Column 5 Column 6
980
+ -----------------------------------------------------------------------------------------------------------------------------
981
+ A B C D E F
982
+ =============================================================================================================================
983
+ END
984
+
985
+ assert_output_equal expected, @mock_out.string
986
+ end
987
+
988
+ def test_can_use_a_string_instead_of_hash_to_default_everything
989
+ table_config = [
990
+ {:size=>20, :title=>"Column 1"},
991
+ "Simple Column",
992
+ {:size=>20, :title=>"Column 3"},
993
+ ]
994
+
995
+ ConsoleTable.define(table_config, :width=> 70, :output=>@mock_out) do |table|
996
+ table << ["A", "B", "C"]
997
+ end
998
+
999
+ expected=<<-END
1000
+ ======================================================================
1001
+ Column 1 Simple Column Column 3
1002
+ ----------------------------------------------------------------------
1003
+ A B C
1004
+ ======================================================================
1005
+ END
1006
+
1007
+ assert_output_equal expected, @mock_out.string
1008
+ end
1009
+
1010
+ def test_can_use_a_config_of_nothing_but_titles_if_you_really_want
1011
+ table_config = [
1012
+ "A Column", "B Column", "C Column"
1013
+ ]
1014
+
1015
+ ConsoleTable.define(table_config, :width=> 30, :output=>@mock_out) do |table|
1016
+ table << ["A", "B", "C"]
1017
+ end
1018
+
1019
+ expected=<<-END
1020
+ =============================
1021
+ A Column B Column C Column
1022
+ -----------------------------
1023
+ A B C
1024
+ =============================
1025
+ END
1026
+
1027
+ assert_output_equal expected, @mock_out.string
1028
+ end
1029
+
963
1030
  private
964
1031
  def assert_output_equal(expected, actual)
965
1032
  expected_lines = expected.split("\n")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: console_table
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rod Hilton
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: simplecov
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.9'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.9'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: minitest
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -104,6 +90,7 @@ extensions: []
104
90
  extra_rdoc_files: []
105
91
  files:
106
92
  - ".gitignore"
93
+ - ".travis.yml"
107
94
  - Gemfile
108
95
  - LICENSE
109
96
  - README.md