Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #5 from waslogic/master

patches applied, ready to roll
  • Loading branch information...
commit 52681e3b1971d3719569f6500c8e66b876ebcbc8 2 parents ffbe4bd + b834186
R. Bernstein authored
1  AUTHORS
View
@@ -1 +1,2 @@
R. Bernstein (rockyb@rubyforge.net)
+M. Davis (waslogic@gmail.com)
82 README.md
View
@@ -10,58 +10,82 @@ Setup
-----
$ irb
- >> a = (1..10).to_a
- => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> require 'columnize'
=> true
- >> include Columnize
- => Object
- >> g = %w(bibrons golden madascar leopard mourning suras tokay)
- => ["bibrons", "golden", "madascar", "leopard", "mourning", "suras", "tokay"]
With numeric data
-----------------
- columnize(a)
- => "1 2 3 4 5 6 7 8 9 10\n"
- >> puts Columnize::columnize(a, :arrange_array => true, :displaywidth => 10)
- [1, 2
- 3, 4
- 5, 6
- 7, 8
- 9, 10
- ]
+ >> a = (1..10).to_a
+ => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+
+ >> a.columnize
+ => "1 2 3 4 5 6 7 8 9 10"
+
+ >> puts a.columnize :arrange_array => true, :displaywidth => 10
+ [1, 2, 3,
+ 4, 5, 6,
+ 7, 8, 9,
+ 10]
+ => nil
+
+ >> puts a.columnize :arrange_array => true, :displaywidth => 20
+ [1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10]
=> nil
- >> puts Columnize::columnize(a, :arrange_array => true, :displaywidth => 20)
- [1, 2, 3, 4, 5, 6
- 7, 8, 9, 10
- ]
With String data
----------------
- >> puts columnize g, :displaywidth => 15
+ >> g = %w(bibrons golden madascar leopard mourning suras tokay)
+ => ["bibrons", "golden", "madascar", "leopard", "mourning", "suras", "tokay"]
+
+ >> puts g.columnize :displaywidth => 15
bibrons suras
golden tokay
madascar
- leopard
+ leopard
mourning
=> nil
- >> puts columnize g, {:displaywidth => 19, :colsep => ' | '}
+ >> puts g.columnize :displaywidth => 19, :colsep => ' | '
bibrons | suras
golden | tokay
madascar
- leopard
+ leopard
mourning
=> nil
- >> puts columnize g, {:displaywidth => 18, :colsep => ' | ', :ljust=>false}
+ >> puts g.columnize :displaywidth => 18, :colsep => ' | ', :ljust => false
+ bibrons | mourning
+ golden | suras
+ madascar | tokay
+ leopard
+ => nil
+
+Using Columnize.columnize
+-------------------------
+
+ >> Columnize.columnize(a)
+ => "1 2 3 4 5 6 7 8 9 10"
+ >> puts Columnize.columnize(a, :displaywidth => 10)
+ 1 5 9
+ 2 6 10
+ 3 7
+ 4 8
+ => nil
+
+ >> Columnize.columnize(g)
+ => "bibrons golden madascar leopard mourning suras tokay"
+
+ >> puts Columnize.columnize(g, :displaywidth => 19, :colsep => ' | ')
bibrons | mourning
- golden | suras
- madascar | tokay
- leopard
+ golden | suras
+ madascar | tokay
+ leopard
+ => nil
+
Credits
-------
@@ -71,9 +95,9 @@ This is adapted from a method of the same name from Python's cmd module.
Other stuff
-----------
-Author: Rocky Bernstein <rockyb@rubyforge.org>
+Authors: Rocky Bernstein <rockyb@rubyforge.org> and [Martin Davis](https://github.com/waslogic)
-License: Copyright (c) 2011 Rocky Bernstein
+License: Copyright (c) 2011 Rocky Bernstein
Warranty
--------
133 lib/columnize.rb
View
@@ -8,7 +8,7 @@
# See below for examples and options to the main method +columnize+.
#
#
-# == License
+# == License
#
# Columnize is copyright (C) 2007-2011, 2013 Rocky Bernstein
# <rockyb@rubyforge.net>
@@ -19,41 +19,31 @@
# Also available in Python (columnize), and Perl (Array::Columnize)
module Columnize
-
# Pull in the rest of my pieces
ROOT_DIR = File.dirname(__FILE__)
- %w(opts horizontal vertical version).each do |submod|
+ %w(opts columnize version).each do |submod|
require File.join %W(#{ROOT_DIR} columnize #{submod})
end
- module_function
-
- # Return the length of String +cell+. If Boolean +term_adjust+ is true,
- # ignore terminal sequences in +cell+.
- def cell_size(cell, term_adjust)
- if term_adjust
- cell.gsub(/\e\[.*?m/, '')
- else
- cell
- end.size
- end
+ # Add +columnize_opts+ instance variable to classes that mix in this module. The type should be a kind of hash in file +columnize/opts+.
+ attr_accessor :columnize_opts
- # columize([args]) => String
- #
+ # Columnize.columize([args]) => String
+ #
# Return a string from an array with embedded newlines formatted so
# that when printed the columns are aligned.
- #
+ #
# For example, for a line width of 4 characters (arranged vertically):
# a = (1..4).to_a
# Columnize.columnize(a) => '1 3\n2 4\n'
#
- # Alternatively:
+ # Alternatively:
# a.columnize => '1 3\n2 4\n'
- #
+ #
# Arranged horizontally:
- # a.columnize(:arrange_vertical => false) =>
+ # a.columnize(:arrange_vertical => false) =>
# ['1', '2,', '3', '4'] => '1 2\n3 4\n'
- #
+ #
# Formatted as an array using format specifier '%02d':
# puts (1..10).to_a.columnize(:arrange_array => true, :colfmt => '%02d',
# :displaywidth => 10) =>
@@ -63,7 +53,7 @@ def cell_size(cell, term_adjust)
# 07, 08,
# 09, 10,
# ]
- #
+ #
# Each column is only as wide as necessary. By default, columns are
# separated by two spaces. Options are available for setting
# * the line display width
@@ -73,91 +63,63 @@ def cell_size(cell, term_adjust)
# * A format specify for formatting each item each array item to a string
# * whether to ignore terminal codes in text size calculation
# * whether to left justify text instead of right justify
- # * whether to format as an array - with surrounding [] and
+ # * whether to format as an array - with surrounding [] and
# separating ', '
+ def self.columnize(*args)
+ list = args.shift
+ opts = parse_columnize_options(args)
+ Columnizer.new(list, opts).columnize
+ end
- def columnize(*args)
-
- list, opts = parse_columnize_options(args)
-
- # Some degenerate cases
- return '' if not list.is_a?(Array)
- return "<empty>\n" if list.empty?
-
- # Stringify array elements
- l =
- if opts[:colfmt]
- list.map{|li| opts[:colfmt] % li}
- else
- list.map{|li| li.to_s}
- end
-
- return "%s%s%s\n" % [opts[:array_prefix], l[0],
- opts[:array_suffix]] if 1 == l.size
-
- if opts[:displaywidth] - opts[:lineprefix].length < 4
- opts[:displaywidth] = opts[:lineprefix].length + 4
- else
- opts[:displaywidth] -= opts[:lineprefix].length
- end
- if opts[:arrange_vertical]
- return columnize_vertical(l, opts)
- else
- return columnize_horizontal(l, opts)
+ # Adds columnize_opts to the singleton level of included class
+ def self.included(base)
+ # screw class variables, we'll use an instance variable on the class singleton
+ class << base
+ attr_accessor :columnize_opts
end
+ base.columnize_opts = DEFAULT_OPTS.dup
end
-end
-# Mix in "Columnize" in the Array class and make the columnize method
-# public.
-# Array.send :include, Columnize
-# Array.send :public, :columnize
-
-class Array
- attr_accessor :columnize_opts
- def columnize(*args)
- if args.empty? and self.columnize_opts
- Columnize.columnize(self, self.columnize_opts)
- else
- Columnize.columnize(self, *args)
- end
+ def columnize(opts={})
+ @columnize_opts ||= self.class.columnize_opts.dup
+ @columnizer ||= Columnizer.new(self, @columnize_opts)
+ # make sure that any changes to list or opts get passed to columnizer
+ @columnizer.list = self unless @columnizer.list == self
+ @columnizer.opts = @columnize_opts.merge(opts) unless @columnizer.opts == @columnize_opts and opts.empty?
+ @columnizer.columnize
end
end
+# Mix Columnize into Array
+Array.send :include, Columnize
+
# Demo this sucker
if __FILE__ == $0
- include Columnize
-
+ # include Columnize
+
a = (1..80).to_a
- a.columnize_opts = {:arrange_array => true}
- puts a.columnize
+ puts a.columnize :arrange_array => true
puts '=' * 50
b = (1..10).to_a
puts b.columnize(:displaywidth => 10)
puts '-' * 50
- puts b.columnize(:arrange_array => true, :colfmt => '%02d',
- :displaywidth => 10)
-
- line = 'require "irb"';
- puts cell_size(line, true);
- puts cell_size(line, false);
+ puts b.columnize(:arrange_array => true, :colfmt => '%02d', :displaywidth => 10)
[[4, 4], [4, 7], [100, 80]].each do |width, num|
- data = (1..num).map{|i| i}
+ data = (1..num).map{|i| i }
[[false, 'horizontal'], [true, 'vertical']].each do |bool, dir|
puts "Width: #{width}, direction: #{dir}"
- print columnize(data, :displaywidth => width, :colsep => ' ',
- :arrange_vertical => bool, :ljust => :auto)
+ print Columnize.columnize(data, :displaywidth => width, :colsep => ' ', :arrange_vertical => bool, :ljust => :auto)
end
end
- puts Columnize::columnize(5)
- puts columnize([])
- puts columnize(["a", 2, "c"], :displaywidth =>10, :colsep => ', ')
- puts columnize(["oneitem"])
- puts columnize(["one", "two", "three"])
+ puts Columnize.columnize(5)
+ puts Columnize.columnize([])
+ puts Columnize.columnize(["a", 2, "c"], :displaywidth =>10, :colsep => ', ')
+ puts Columnize.columnize(["oneitem"])
+ puts Columnize.columnize(["one", "two", "three"])
data = ["one", "two", "three",
"for", "five", "six",
"seven", "eight", "nine",
@@ -167,8 +129,7 @@ def columnize(*args)
"nineteen", "twenty", "twentyone",
"twentytwo", "twentythree", "twentyfour",
"twentyfive","twentysix", "twentyseven"]
-
- puts columnize(data)
- puts columnize(data, 80, ' ', false)
+ puts Columnize.columnize(data)
+ puts Columnize.columnize(data, 80, ' ', false)
end
116 lib/columnize/columnize.rb
View
@@ -0,0 +1,116 @@
+# Copyright (C) 2007-2011, 2013 Rocky Bernstein
+# <rockyb@rubyforge.net>
+#
+# Part of Columnize to format in either direction
+module Columnize
+ class Columnizer
+ ARRANGE_ARRAY_OPTS = {:array_prefix => '[', :line_prefix => ' ', :line_suffix => ',', :array_suffix => ']', :colsep => ', ', :arrange_vertical => false}
+ OLD_AND_NEW_KEYS = {:lineprefix => :line_prefix, :linesuffix => :line_suffix}
+ # TODO: change colfmt to cell_format; change colsep to something else
+ ATTRS = [:arrange_vertical, :array_prefix, :array_suffix, :line_prefix, :line_suffix, :colfmt, :colsep, :displaywidth, :ljust]
+
+ attr_reader :list, :opts
+
+ def initialize(list=[], opts={})
+ self.list = list
+ self.opts = DEFAULT_OPTS.merge(opts)
+ end
+
+ def list=(list)
+ @list = list
+ if @list.is_a? Array
+ @short_circuit = @list.empty? ? "<empty>\n" : nil
+ else
+ @short_circuit = ''
+ @list = []
+ end
+ end
+
+ # TODO: freeze @opts
+ def opts=(opts)
+ @opts = opts
+ OLD_AND_NEW_KEYS.each {|old, new| @opts[new] = @opts.delete(old) if @opts.keys.include?(old) and !@opts.keys.include?(new) }
+ @opts.merge!(ARRANGE_ARRAY_OPTS) if @opts[:arrange_array]
+ set_attrs_from_opts
+ end
+
+ def update_opts(opts)
+ self.opts = @opts.merge(opts)
+ end
+
+ def columnize
+ return @short_circuit if @short_circuit
+
+ rows, colwidths = compute_rows_and_colwidths
+ ncols = colwidths.length
+ justify = lambda {|t, c| @ljust ? t.ljust(colwidths[c]) : t.rjust(colwidths[c]) }
+ textify = lambda do |row|
+ row.map!.with_index(&justify) unless ncols == 1 && @ljust
+ "#{@line_prefix}#{row.join(@colsep)}#{@line_suffix}"
+ end
+
+ text = rows.map(&textify)
+ text.first.sub!(/^#{@line_prefix}/, @array_prefix) unless @array_prefix.empty?
+ text.last.sub!(/#{@line_suffix}$/, @array_suffix) unless @array_suffix.empty?
+ text.join("\n") # + "\n" # if we want extra separation
+ end
+
+ # TODO: make this a method, rather than a function (?)
+ # compute the smallest number of rows and the max widths for each column
+ def compute_rows_and_colwidths
+ list = @list.map &@stringify
+ cell_widths = list.map(&@term_adjuster).map(&:size)
+ # default is 1 atom per row (just in case any atom > @displaywidth)
+ rcw = [min_rows_and_cols(list, 1)[0], [cell_widths.max]]
+ return rcw if rcw[1][0] > @displaywidth
+
+ # For horizontal arrangement, we want to *maximize* the number
+ # of columns. Thus the candidate number of rows (+sizes+) starts
+ # at the minumum number of rows, 1, and increases.
+
+ # For vertical arrangement, we want to *minimize* the number of
+ # rows. So here the candidate number of columns (+sizes+) starts
+ # at the maximum number of columns, list.length, and
+ # decreases. Also the roles of columns and rows are reversed
+ # from horizontal arrangement.
+
+ # The below sets up the order of the lengths to try, +sizes+. It
+ # also sets up the row and column permutation to use, [0,1] or
+ # [1,0], which are stored in +ri+, +ci+ in accessing the values
+ # passed back by min_rows_and_cols().
+ sizes, ri, ci =
+ if @arrange_vertical
+ [(1..list.length).to_a, 1, 0]
+ else
+ [(1..list.length).to_a.reverse, 0, 1]
+ end
+
+ # Loop from most compact arrangement to least compact, stopping
+ # at the first successful packing.
+ sizes.each do |size|
+ colwidths = min_rows_and_cols(cell_widths, size)[ci].map(&:max)
+ totwidth = colwidths.inject(&:+) + ((colwidths.length-1) * @colsep.length)
+ rcw = [min_rows_and_cols(list, size)[ri], colwidths] and break if totwidth <= @displaywidth
+ end
+ rcw
+ end
+
+ # Given list.size and ncols, calculate minimum number of rows needed. This is very cool.
+ def min_rows_and_cols(list, ncols)
+ nrows = (list.size + ncols - 1) / ncols
+ rows = (0...nrows).map {|r| list[r*ncols, ncols] }
+ cols = rows[0].zip(*rows[1..-1]).map(&:compact)
+ [rows, cols]
+ end
+
+ def set_attrs_from_opts
+ ATTRS.each {|attr| self.instance_variable_set "@#{attr}", @opts[attr] }
+
+ @ljust = !@list.all? {|datum| datum.kind_of?(Numeric)} if @ljust == :auto
+ @displaywidth -= @line_prefix.length
+ @displaywidth = @line_prefix.length + 4 if @displaywidth < 4
+ @stringify = @colfmt ? lambda {|li| @colfmt % li } : lambda {|li| li.to_s }
+ @term_adjuster = @opts[:term_adjust] ? lambda {|c| c.gsub(/\e\[.*?m/, '') } : lambda {|c| c }
+ end
+ end
+end
85 lib/columnize/horizontal.rb
View
@@ -1,85 +0,0 @@
-# Copyright (C) 2007-2011, 2013 Rocky Bernstein
-# <rockyb@rubyforge.net>
-#
-# Part of Columnize to format in the horizontal direction
-module Columnize
- module_function
- def columnize_horizontal(l, opts)
- nrows = ncols = 0 # Make nrows, ncols have more global scope
- colwidths = [] # Same for colwidths
- array_index = lambda {|ncols, row, col| ncols*(row-1) + col }
- # Assign to make enlarge scope of loop variables.
- totwidth = i = rounded_size = 0
- # Try every column count from size downwards.
- l.size.downto(1) do |_ncols|
- ncols = _ncols
- # Try every row count from 1 upwards
- min_rows = (l.size+ncols-1) / ncols
- min_rows.upto(l.size) do |_nrows|
- nrows = _nrows
- rounded_size = nrows * ncols
- colwidths = []
- totwidth = -opts[:colsep].length
- colwidth = row = 0
- 0.upto(ncols-1) do |col|
- # get max column width for this column
- 1.upto(nrows) do |_row|
- row = _row
- i = array_index.call(ncols, row, col)
- break if i >= l.size
- colwidth = [colwidth, cell_size(l[i], opts[:term_adjust])].max
- end
- colwidths.push(colwidth)
- totwidth += colwidth + opts[:colsep].length
- break if totwidth > opts[:displaywidth];
- end
- if totwidth <= opts[:displaywidth]
- # Found the right nrows and ncols
- nrows = row
- break
- elsif totwidth > opts[:displaywidth]
- # Need to reduce ncols
- break
- end
- end
- break if totwidth <= opts[:displaywidth] and i >= rounded_size-1
- end
- ncols = 1 if ncols < 1
- nrows = l.size if ncols == 1
- # The smallest number of rows computed and the max widths for
- # each column has been obtained. Now we just have to format
- # each of the rows.
- s = ''
- prefix = if opts[:array_prefix].empty?
- opts[:lineprefix]
- else
- opts[:array_prefix]
- end
- 1.upto(nrows) do |row|
- texts = []
- 0.upto(ncols-1) do |col|
- i = array_index.call(ncols, row, col)
- if i >= l.size
- break
- else
- x = l[i]
- end
- texts.push(x)
- end
- 0.upto(texts.size-1) do |col|
- unless ncols == 1 && opts[:ljust]
- if opts[:ljust]
- texts[col] = texts[col].ljust(colwidths[col]) if ncols != 1
- else
- texts[col] = texts[col].rjust(colwidths[col])
- end
- end
- end
- s += "%s%s%s" % [prefix, texts.join(opts[:colsep]),
- opts[:linesuffix]]
- prefix = opts[:lineprefix]
- end
- s += opts[:array_suffix]
- return s
- end
-end
72 lib/columnize/opts.rb
View
@@ -1,10 +1,8 @@
module Columnize
-
computed_displaywidth = (ENV['COLUMNS'] || '80').to_i
computed_displaywidth = 80 unless computed_displaywidth >= 10
- # When an option is not specified for the below keys, these
- # are the defaults.
+ # When an option is not specified for the below keys, these are the defaults.
DEFAULT_OPTS = {
:arrange_array => false,
:arrange_vertical => true,
@@ -13,73 +11,25 @@ module Columnize
:colfmt => nil,
:colsep => ' ',
:displaywidth => computed_displaywidth,
- :lineprefix => '',
- :linesuffix => "\n",
+ :line_prefix => '',
+ :line_suffix => '',
:ljust => :auto,
:term_adjust => false
}
- # Add +columnize_opts+ instance variable to classes that mix in this
- # module. The type should be a kind of hash as above.
- attr_accessor :columnize_opts
-
- # Adds class variable into any class mixes in this module.
- def self.included(base)
- base.class_variable_set :@@columnize_opts, DEFAULT_OPTS.dup if
- base.respond_to?(:class_variable_set)
- end
-
# Options parsing routine for Columnize::columnize. In the preferred
- # newer style, +args+ is either a hash where each key is one of the option
- # names:
+ # newer style, +args+ is a hash where each key is one of the option names.
#
- #
# In the older style positional arguments are used and the positions
# are in the order: +displaywidth+, +colsep+, +arrange_vertical+,
- # +ljust+, and +lineprefix+.
- #
- # Thanks to ideas from Martin Davis, failing any explicit setting on
- # the columnize method call, we also now allow options to be picked
- # up from a columnize_opts instance variable or columnize_opts class
- # variable.
- module_function
- def parse_columnize_options(args)
- list = args.shift
-
- if 1 == args.size && args[0].kind_of?(Hash)
- # Options were explicitly passed as a hash. Use that
- opts = DEFAULT_OPTS.merge(args[0])
- if opts[:arrange_array]
- opts[:array_prefix] = '['
- opts[:lineprefix] = ' '
- opts[:linesuffix] = ",\n"
- opts[:array_suffix] = "]\n"
- opts[:colsep] = ', '
- opts[:arrange_vertical] = false
- end
- opts[:ljust] = !(list.all?{|datum| datum.kind_of?(Numeric)}) if
- opts[:ljust] == :auto
- return list, opts
- elsif !args.empty?
- # Options were explicitly passes as ugly positional parameters.
- # Next priority
- opts = DEFAULT_OPTS.dup
- %w(displaywidth colsep arrange_vertical ljust lineprefix
- ).each do |field|
- break if args.empty?
- opts[field.to_sym] = args.shift
- end
- elsif defined?(@columnize_opts)
- # class has an option set as an instance variable.
- opts = @columnize_opts
- elsif defined?(@@columnize_opts)
- # class has an option set as a class variable.
- opts = @@columnize_opts.dup
+ # +ljust+, and +line_prefix+.
+ def self.parse_columnize_options(args)
+ if 1 == args.size && args[0].kind_of?(Hash) # explicitly passed as a hash
+ args[0]
+ elsif !args.empty? # passed as ugly positional parameters.
+ Hash[args.zip([:displaywidth, :colsep, :arrange_vertical, :ljust, :line_prefix]).map(&:reverse)]
else
- # When all else fails, just use the default options.
- opts = DEFAULT_OPTS.dup
+ {}
end
- return list, opts
end
-
end
2  lib/columnize/version.rb
View
@@ -3,5 +3,5 @@
# require'ing 'columnize'.
module Columnize
# The current version of this package
- VERSION = '0.3.6_01'
+ VERSION = '1.0.0'
end
71 lib/columnize/vertical.rb
View
@@ -1,71 +0,0 @@
-# Copyright (C) 2007-2011, 2013 Rocky Bernstein
-# <rockyb@rubyforge.net>
-#
-# Part of Columnize to format in the vertical direction
-module Columnize
- module_function
- def columnize_vertical(l, opts)
- nrows = ncols = 0 # Make nrows, ncols have more global scope
- colwidths = [] # Same for colwidths
- array_index = lambda {|num_rows, row, col| num_rows*col + row }
- # Try every row count from 1 upwards
- 1.upto(l.size-1) do |_nrows|
- nrows = _nrows
- ncols = (l.size + nrows-1) / nrows
- colwidths = []
- totwidth = -opts[:colsep].length
-
- 0.upto(ncols-1) do |col|
- # get max column width for this column
- colwidth = 0
- 0.upto(nrows-1) do |_row|
- row = _row
- i = array_index.call(nrows, row, col)
- break if i >= l.size
- colwidth = [colwidth, cell_size(l[i], opts[:term_adjust])].max
- end
- colwidths.push(colwidth)
- totwidth += colwidth + opts[:colsep].length
- if totwidth > opts[:displaywidth]
- ncols = col
- break
- end
- end
- break if totwidth <= opts[:displaywidth]
- end
- ncols = 1 if ncols < 1
- nrows = l.size if ncols == 1
- # The smallest number of rows computed and the max widths for
- # each column has been obtained. Now we just have to format
- # each of the rows.
- s = ''
- 0.upto(nrows-1) do |_row|
- row = _row
- texts = []
- 0.upto(ncols-1) do |col|
- i = array_index.call(nrows, row, col)
- if i >= l.size
- x = ''
- else
- x = l[i]
- end
- texts.push(x)
- end
- texts.pop while !texts.empty? and texts[-1] == ''
- if texts.size > 0
- 0.upto(texts.size-1) do |col|
- unless ncols == 1 && opts[:ljust]
- if opts[:ljust]
- texts[col] = texts[col].ljust(colwidths[col])
- else
- texts[col] = texts[col].rjust(colwidths[col])
- end
- end
- end
- s += "%s%s%s" % [opts[:lineprefix], texts.join(opts[:colsep]),
- opts[:linesuffix]]
- end
- end
- return s
- end
-end
60 test/test-columnize-array.rb
View
@@ -3,45 +3,37 @@
# Test of Columnize module
class TestColumnizeArray < Test::Unit::TestCase
-
# Ruby 1.8 form of require_relative
- TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)),
- '..', 'lib')
+ TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
+ ENV['COLUMNS'] = '80'
require File.join(TOP_SRC_DIR, 'columnize.rb')
# test columnize
- def test_basic
-
- a = (1..80).to_a
- a.columnize_opts = {:arrange_array => true}
- expect = <<EOF
-[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
-]
-EOF
- self.assert_equal(expect, a.columnize, "arrange_arrary => true (1..80)")
-
- expect = <<EOF
-1 5 9
-2 6 10
-3 7
-4 8
-EOF
- test_str = "(1..10).to_a.columnize(:displaywidth=>10)"
- self.assert_equal(expect, eval(test_str), test_str)
+ def test_arrange_array
+ data = (1..80).to_a
+ expect = "[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n" +
+ " 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n" +
+ " 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\n" +
+ " 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80]"
+ assert_equal(expect, data.columnize(:arrange_array => true), "columnize_opts -> arrange_array")
+ end
- expect = <<EOF
-[01, 02,
- 03, 04,
- 05, 06,
- 07, 08,
- 09, 10,
-]
-EOF
- test_str = "(1..10).to_a.columnize(:arrange_array=>true,:colfmt=>'%02d',:displaywidth=>10)"
- self.assert_equal(expect, eval(test_str), test_str)
+ def test_displaywidth
+ expect = "1 5 9\n" +
+ "2 6 10\n" +
+ "3 7\n" +
+ "4 8"
+ data = (1..10).to_a
+ assert_equal(expect, data.columnize(:displaywidth => 10), "displaywidth")
+ end
+ def test_colfmt
+ expect = "[01, 02,\n" +
+ " 03, 04,\n" +
+ " 05, 06,\n" +
+ " 07, 08,\n" +
+ " 09, 10]"
+ data = (1..10).to_a
+ assert_equal(expect, data.columnize(:arrange_array => true, :colfmt => '%02d', :displaywidth => 10), "arrange_array, colfmt, displaywidth")
end
end
60 test/test-columnize.rb
View
@@ -3,44 +3,29 @@
# Test of Columnize module
class TestColumnize < Test::Unit::TestCase
-
# Ruby 1.8 form of require_relative
- TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)),
- '..', 'lib')
+ TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
require File.join(TOP_SRC_DIR, 'columnize.rb')
- include Columnize
-
- def test_cell_size
- assert_equal(3, cell_size('abc', false))
- assert_equal(3, cell_size('abc', true))
- assert_equal(6, cell_size("\e[0;31mObject\e[0;4m", true))
- assert_equal(19, cell_size("\e[0;31mObject\e[0;4m", false))
- end
# test columnize
def test_basic
- # Try at least one test where we give the module name explicitely.
- assert_equal("1, 2, 3\n",
- Columnize::columnize([1, 2, 3], 10, ', '))
- assert_equal("", columnize(5))
- assert_equal("1 3\n2 4\n",
- columnize(['1', '2', '3', '4'], 4))
- assert_equal("1 2\n3 4\n",
- columnize(['1', '2', '3', '4'], 4, ' ', false))
- assert_equal("<empty>\n", columnize([]))
-
-
- assert_equal("oneitem\n", columnize(["oneitem"]))
-
+ assert_equal("1, 2, 3", Columnize::columnize([1, 2, 3], 10, ', '))
+ assert_equal("", Columnize::columnize(5))
+ assert_equal("1 3\n2 4", Columnize::columnize(['1', '2', '3', '4'], 4))
+ assert_equal("1 2\n3 4", Columnize::columnize(['1', '2', '3', '4'], 4, ' ', false))
+ assert_equal("<empty>\n", Columnize::columnize([]))
+
+ assert_equal("oneitem", Columnize::columnize(["oneitem"]))
+
data = (0..54).map{|i| i.to_s}
assert_equal(
- "0, 6, 12, 18, 24, 30, 36, 42, 48, 54\n" +
+ "0, 6, 12, 18, 24, 30, 36, 42, 48, 54\n" +
"1, 7, 13, 19, 25, 31, 37, 43, 49\n" +
"2, 8, 14, 20, 26, 32, 38, 44, 50\n" +
"3, 9, 15, 21, 27, 33, 39, 45, 51\n" +
"4, 10, 16, 22, 28, 34, 40, 46, 52\n" +
- "5, 11, 17, 23, 29, 35, 41, 47, 53\n",
- columnize(data, 39, ', ', true, false))
+ "5, 11, 17, 23, 29, 35, 41, 47, 53",
+ Columnize::columnize(data, 39, ', ', true, false))
assert_equal(
" 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n" +
@@ -48,8 +33,8 @@ def test_basic
"20, 21, 22, 23, 24, 25, 26, 27, 28, 29\n" +
"30, 31, 32, 33, 34, 35, 36, 37, 38, 39\n" +
"40, 41, 42, 43, 44, 45, 46, 47, 48, 49\n" +
- "50, 51, 52, 53, 54\n",
- columnize(data, 39, ', ', false, false))
+ "50, 51, 52, 53, 54",
+ Columnize::columnize(data, 39, ', ', false, false))
assert_equal(
@@ -59,8 +44,8 @@ def test_basic
" 27, 28, 29, 30, 31, 32, 33, 34, 35\n" +
" 36, 37, 38, 39, 40, 41, 42, 43, 44\n" +
" 45, 46, 47, 48, 49, 50, 51, 52, 53\n" +
- " 54\n",
- columnize(data, 39, ', ', false, false, ' '))
+ " 54",
+ Columnize::columnize(data, 39, ', ', false, false, ' '))
data = ["one", "two", "three",
@@ -74,17 +59,16 @@ def test_basic
"twentyfive","twentysix", "twentyseven"]
assert_equal(
-"one two three for five six \n" +
-"seven eight nine ten eleven twelve \n" +
-"thirteen fourteen fifteen sixteen seventeen eightteen \n" +
-"nineteen twenty twentyone twentytwo twentythree twentyfour \n" +
-"twentyfive twentysix twentyseven\n", columnize(data, 80, ' ', false))
+"one two three for five six \n" +
+"seven eight nine ten eleven twelve \n" +
+"thirteen fourteen fifteen sixteen seventeen eightteen \n" +
+"nineteen twenty twentyone twentytwo twentythree twentyfour\n" +
+"twentyfive twentysix twentyseven", Columnize::columnize(data, 80, ' ', false))
assert_equal(
"one five nine thirteen seventeen twentyone twentyfive \n" +
"two six ten fourteen eightteen twentytwo twentysix \n" +
"three seven eleven fifteen nineteen twentythree twentyseven\n" +
-"for eight twelve sixteen twenty twentyfour \n", columnize(data))
-
+"for eight twelve sixteen twenty twentyfour ", Columnize::columnize(data, 80))
end
end
104 test/test-columnizer.rb
View
@@ -0,0 +1,104 @@
+#!/usr/bin/env ruby
+require 'test/unit'
+
+# Test of Columnizer class
+class TestColumnizer < Test::Unit::TestCase
+ TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
+ require File.join(TOP_SRC_DIR, 'columnize.rb')
+
+ Columnize::Columnizer.class_eval 'attr_reader :stringify, :short_circuit, :term_adjuster'
+ Columnize::Columnizer.class_eval 'attr_reader *ATTRS'
+
+ # SETTING OPTS IN INITIALIZE
+ def test_passed_in_opts
+ # passed in opts should be merged with DEFAULT_OPTS
+ c = Columnize::Columnizer.new([], :displaywidth => 15)
+ assert_equal false, c.opts[:term_adjust], 'term_adjust comes from DEFAULT_OPTS'
+ assert_equal 15, c.opts[:displaywidth], 'displaywidth should override DEFAULT_OPTS'
+ end
+
+ def test_ljust_attr
+ c = Columnize::Columnizer.new([1,2,3], {:ljust => :auto})
+ assert_equal false, c.ljust, 'ljust: :auto should transform to false when all values are numeric'
+ c = Columnize::Columnizer.new(['1', 2, 3], {:ljust => :auto})
+ assert_equal true, c.ljust, 'ljust: :auto should transform to true when not all values are numeric'
+ c = Columnize::Columnizer.new([], {:ljust => false})
+ assert_equal false, c.ljust, 'ljust: false should stay false'
+ c = Columnize::Columnizer.new([], {:ljust => true})
+ assert_equal true, c.ljust, 'ljust: true should stay true'
+ end
+
+ def test_stringify_attr
+ c = Columnize::Columnizer.new
+ assert_equal '1.0', c.stringify[1.0], 'without colfmt, should be to_s'
+ c.update_opts :colfmt => '%02d'
+ assert_equal '01', c.stringify[1.0], 'without colfmt, should be to_s'
+ end
+
+ def test_short_circuit_attr
+ c = Columnize::Columnizer.new
+ assert_equal "<empty>\n", c.short_circuit, 'should explicitly state when empty'
+ c.list = 1
+ assert_equal '', c.short_circuit, 'should be an empty string when not an array'
+ c.list = [1]
+ assert_equal nil, c.short_circuit, 'should be nil when list is good'
+ end
+
+ def test_term_adjuster_attr
+ c = Columnize::Columnizer.new
+ assert_equal 'abc', c.term_adjuster['abc']
+ assert_equal "\e[0;31mObject\e[0;4m", c.term_adjuster["\e[0;31mObject\e[0;4m"]
+ c.update_opts :term_adjust => true
+ assert_equal 'abc', c.term_adjuster['abc']
+ assert_equal 'Object', c.term_adjuster["\e[0;31mObject\e[0;4m"]
+ end
+
+ def test_displaywidth_attr
+ c = Columnize::Columnizer.new [], :displaywidth => 10, :line_prefix => ' '
+ assert_equal 12, c.displaywidth, 'displaywidth within 4 of line_prefix.length'
+ c.update_opts :line_prefix => ' '
+ assert_equal 8, c.displaywidth, 'displaywidth not within 4 of line_prefix.length'
+ end
+
+ # COLUMNIZE
+ def test_columnize_with_short_circuit
+ msg = 'Johnny 5 is alive!'
+ c = Columnize::Columnizer.new
+ c.instance_variable_set(:@short_circuit, msg)
+ assert_equal msg, c.columnize, 'columnize should return short_circuit message if set'
+ end
+
+ def test_columnize_applies_ljust
+ c = Columnize::Columnizer.new [1,2,3,10,20,30], :displaywidth => 10, :ljust => false, :arrange_vertical => false
+ assert_equal " 1 2 3\n10 20 30", c.columnize, "ljust: #{c.ljust}"
+ c.update_opts :ljust => true
+ assert_equal "1 2 3 \n10 20 30", c.columnize, "ljust: #{c.ljust}"
+ end
+
+ def test_columnize_applies_colsep_and_prefix_and_suffix
+ c = Columnize::Columnizer.new [1,2,3]
+ assert_equal "1 2 3", c.columnize
+ c.update_opts :line_prefix => '>', :colsep => '-', :line_suffix => '<'
+ assert_equal ">1-2-3<", c.columnize
+ end
+
+ def test_columnize_applies_array_prefix_and_suffix
+ c = Columnize::Columnizer.new [1,2,3]
+ assert_equal "1 2 3", c.columnize
+ c.update_opts :array_prefix => '>', :array_suffix => '<'
+ assert_equal ">1 2 3<", c.columnize
+ end
+
+ # NOTE: compute_rows_and_colwidths tested in test-compute_rows_and_colwidths.rb
+
+ # ROWS_AND_COLS
+ def test_min_rows_and_cols
+ rows,cols = Columnize::Columnizer.new.min_rows_and_cols((1..9).to_a, 3)
+ assert_equal [[1,2,3],[4,5,6],[7,8,9]], rows, 'rows'
+ assert_equal [[1,4,7],[2,5,8],[3,6,9]], cols, 'cols'
+ end
+
+ def test_set_attrs_from_opts
+ assert(true, 'test set_attrs_from_opts')
+ end
+end
67 test/test-compute_rows_and_colwidths.rb
View
@@ -0,0 +1,67 @@
+#!/usr/bin/env ruby
+require 'test/unit'
+
+# Test of Columnize#compute_rows_and_colwidths
+class TestComputeRowsAndColwidths < Test::Unit::TestCase
+ # Ruby 1.8 form of require_relative
+ TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
+ require File.join(TOP_SRC_DIR, 'columnize.rb')
+
+ VOPTS = Columnize::DEFAULT_OPTS.merge(:displaywidth => 80)
+ HOPTS = VOPTS.merge(:arrange_vertical => false)
+
+ def compute_rows_and_colwidths(list, opts)
+ Columnize::Columnizer.new(list, opts).compute_rows_and_colwidths
+ end
+
+ def test_colwidths
+ data = ["one", "two", "three",
+ "four", "five", "six",
+ "seven", "eight", "nine",
+ "ten", "eleven", "twelve",
+ "thirteen", "fourteen", "fifteen",
+ "sixteen", "seventeen", "eightteen",
+ "nineteen", "twenty", "twentyone",
+ "twentytwo", "twentythree", "twentyfour",
+ "twentyfive","twentysix", "twentyseven"]
+
+ # horizontal
+ rows, colwidths = compute_rows_and_colwidths(data, HOPTS)
+ assert_equal([10, 9, 11, 9, 11, 10], colwidths, "colwidths")
+ assert_equal(5, rows.length, "number of rows")
+ assert_equal(6, rows.first.length, "number of cols")
+ # vertical
+ rows, colwidths = compute_rows_and_colwidths(data, VOPTS)
+ assert_equal([5, 5, 6, 8, 9, 11, 11], colwidths, "colwidths")
+ assert_equal(4, rows.length, "number of rows")
+ assert_equal(7, rows.first.length, "number of cols")
+ end
+
+ def test_horizontal_vs_vertical
+ data = (0..54).map{|i| i.to_s}
+ # horizontal
+ rows, colwidths = compute_rows_and_colwidths(data, HOPTS.merge(:displaywidth => 39))
+ assert_equal([2,2,2,2,2,2,2,2,2,2], colwidths, "colwidths")
+ assert_equal(6, rows.length, "number of rows")
+ assert_equal(10, rows.first.length, "number of cols")
+ # vertical
+ rows, colwidths = compute_rows_and_colwidths(data, VOPTS.merge(:displaywidth => 39))
+ assert_equal([1,2,2,2,2,2,2,2,2,2], colwidths, "colwidths")
+ assert_equal(6, rows.length, "number of rows")
+ assert_equal(10, rows.first.length, "number of cols")
+ end
+
+ def test_displaywidth_smaller_than_largest_atom
+ data = ['a' * 100, 'b', 'c', 'd', 'e']
+ # horizontal
+ rows, colwidths = compute_rows_and_colwidths(data, HOPTS)
+ assert_equal([100], colwidths, "colwidths")
+ assert_equal(5, rows.length, "number of rows")
+ assert_equal(1, rows.first.length, "number of cols")
+ # vertical
+ rows, colwidths = compute_rows_and_colwidths(data, VOPTS)
+ assert_equal([100], colwidths, "colwidths")
+ assert_equal(5, rows.length, "number of rows")
+ assert_equal(1, rows.first.length, "number of cols")
+ end
+end
81 test/test-hashparm.rb 100644 → 100755
View
@@ -3,78 +3,41 @@
# Test of Columnize module
class TestHashFormat < Test::Unit::TestCase
- TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)),
- '..', 'lib')
+ TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
require File.join(TOP_SRC_DIR, 'columnize.rb')
- include Columnize
+
def test_parse_columnize_options
- list, default_opts = parse_columnize_options([[], {}])
- assert list.kind_of?(Array)
- assert default_opts.kind_of?(Hash)
- list, opts = parse_columnize_options([[], 90])
- assert_equal 90, opts[:displaywidth]
- list, opts = parse_columnize_options([[], 70, '|'])
+ assert Columnize.parse_columnize_options([{}]).kind_of?(Hash)
+ assert_equal 90, Columnize.parse_columnize_options([90])[:displaywidth]
+ opts = Columnize.parse_columnize_options([70, '|'])
assert_equal 70, opts[:displaywidth]
assert_equal '|', opts[:colsep]
end
- def test_parse_columnize_ljust
- list, opts = parse_columnize_options([[1.5, 2, 3], {:ljust => :auto}])
- assert_equal false, opts[:ljust]
- list, opts = parse_columnize_options([[1.5, 2, 3], {:ljust => false}])
- assert_equal false, opts[:ljust]
- list, opts = parse_columnize_options([[1.5, 2, 3], {:ljust => true}])
- assert_equal true, opts[:ljust]
- list, opts = parse_columnize_options([[1, 2, 'b'], {:ljust => :auto}])
- assert_equal true, opts[:ljust]
- end
-
def test_new_hash
- list, opts = parse_columnize_options([[], {:displaywidth => 40,
- :colsep => ', ',
- :term_adjust => true,
- }])
- [[:displaywidth, 40], [:colsep, ', '], [:term_adjust, true]].each do
- |field, value|
- assert_equal(value , opts[field])
- end
- list, opts = parse_columnize_options([[], {:displaywidth => 40,
- :colsep => ', ',
- }])
- assert_equal(false , opts[:term_adjust])
- opts = {:colsep => ', '}
- assert_equal("1, 2, 3\n",
- Columnize::columnize([1, 2, 3], opts))
+ hash = {:displaywidth => 40, :colsep => ', ', :term_adjust => true,}
+ assert_equal(hash, Columnize.parse_columnize_options([hash]), "parse_columnize_options returns same hash it was passed")
end
-
+
def test_array
data = (0..54).to_a
- assert_equal(
- "[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n" +
- " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n" +
- " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n" +
- " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n" +
- " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n" +
- " 50, 51, 52, 53, 54,\n" +
- "]\n",
- columnize(data,
- :arrange_array => true, :ljust => false,
- :displaywidth => 39))
+ expected = "[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n" +
+ " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n" +
+ " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n" +
+ " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n" +
+ " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n" +
+ " 50, 51, 52, 53, 54]"
+ assert_equal(expected, Columnize.columnize(data, :arrange_array => true, :ljust => false, :displaywidth => 39))
end
def test_justify
data = (0..54).to_a
- assert_equal(
- "[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n" +
- " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n" +
- " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n" +
- " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n" +
- " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n" +
- " 50, 51, 52, 53, 54,\n" +
- "]\n",
- columnize(data,
- :arrange_array => true,
- :displaywidth => 39))
+ expected = "[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n" +
+ " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n" +
+ " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n" +
+ " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n" +
+ " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n" +
+ " 50, 51, 52, 53, 54]"
+ assert_equal(expected, Columnize.columnize(data, :arrange_array => true, :displaywidth => 39))
end
-
end
37 test/test-issue3.rb 100644 → 100755
View
@@ -3,35 +3,22 @@
# Test of Columnize module
class TestIssue3 < Test::Unit::TestCase
- @@TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)),
- '..', 'lib')
+ @@TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
require File.join(@@TOP_SRC_DIR, 'columnize.rb')
- include Columnize
+
# test columnize
def test_long_column
data = ["what's", "upppppppppppppppppp"]
- # Try at least one test where we give the module name explicitely.
- assert_equal("what's\nupppppppppppppppppp\n",
- Columnize::columnize(data, :arrange_vertical => false,
- :displaywidth => 7))
- assert_equal("what's\nupppppppppppppppppp\n",
- Columnize::columnize(data, :arrange_vertical => true,
- :displaywidth => 7))
+ data.columnize_opts = Columnize::DEFAULT_OPTS.merge :displaywidth => 7, :arrange_vertical => false
+ assert_equal("what's\nupppppppppppppppppp", data.columnize)
+ assert_equal("what's\nupppppppppppppppppp", data.columnize(:arrange_vertical => true))
+ end
+
+ def test_long_column_with_ljust
data = ["whaaaaaat's", "up"]
- assert_equal("whaaaaaat's\n up\n",
- Columnize::columnize(data,
- :arrange_vertical => false,
- :ljust => false,
- :displaywidth => 7))
- assert_equal("whaaaaaat's\nup\n",
- Columnize::columnize(data,
- :arrange_vertical => false,
- :ljust => true,
- :displaywidth => 7))
- assert_equal("whaaaaaat's\nup\n",
- Columnize::columnize(data,
- :arrange_vertical => true,
- :ljust => true,
- :displaywidth => 7))
+ data.columnize_opts = Columnize::DEFAULT_OPTS.merge :displaywidth => 7, :arrange_vertical => false, :ljust => true
+ assert_equal("whaaaaaat's\nup", data.columnize)
+ assert_equal("whaaaaaat's\n up", data.columnize(:ljust => false))
+ assert_equal("whaaaaaat's\nup", data.columnize(:arrange_vertical => true))
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.