lilutils 0.0.1

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.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ === 0.0.1 2011-02-08
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,22 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ lib/lilutils.rb
7
+ lib/lilutils/cli/cli.rb
8
+ lib/lilutils/cli_entry.rb
9
+ lib/lilutils/algo_test_utils/data_sets.rb
10
+ lib/lilutils/algo_test_utils_entry.rb
11
+ lib/lilutils/misc/misc.rb
12
+ lib/lilutils/misc/pascal.rb
13
+ lib/lilutils/misc_entry.rb
14
+ bin/cli-demo
15
+ script/console
16
+ script/destroy
17
+ script/generate
18
+ test/test_helper.rb
19
+ test/test_lilutils.rb
20
+ test/algo_test_utils/data_sets_test.rb
21
+ test/cli/cli_basic_test.rb
22
+ test/misc/misc_pascal_test.rb
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on lilutils, see http://lilutils.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.rdoc ADDED
@@ -0,0 +1,55 @@
1
+ = lilutils
2
+
3
+ * http://github.com:kedarmhaswade/lilutils.git
4
+
5
+ == DESCRIPTION:
6
+
7
+ Provides little utilities that are mainly intended for myself. Maybe someone else would find them useful?
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Provides a CLI module which provides a general purpose selection interface for command line interface.
12
+
13
+
14
+ == SYNOPSIS:
15
+
16
+ require 'lilutils/cli'
17
+
18
+ yn = YesNo.new
19
+
20
+ puts "You chose: #{yn.show}"
21
+
22
+ See bin/cli-demo after the gem is installed.
23
+
24
+ == REQUIREMENTS:
25
+
26
+ * Ruby 1.9.2
27
+
28
+ == INSTALL:
29
+
30
+ * [sudo] gem install lilutils
31
+
32
+ == LICENSE:
33
+
34
+ (The MIT License)
35
+
36
+ Copyright (c) 2011 Kedar Mhaswade
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining
39
+ a copy of this software and associated documentation files (the
40
+ 'Software'), to deal in the Software without restriction, including
41
+ without limitation the rights to use, copy, modify, merge, publish,
42
+ distribute, sublicense, and/or sell copies of the Software, and to
43
+ permit persons to whom the Software is furnished to do so, subject to
44
+ the following conditions:
45
+
46
+ The above copyright notice and this permission notice shall be
47
+ included in all copies or substantial portions of the Software.
48
+
49
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
50
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
53
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
54
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
55
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "lilutils"
16
+ gem.homepage = "http://github.com/kedarmhaswade/lilutils"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{Little utilities for everyone}
19
+ gem.description = %Q{Provides little utilties. It's a gem by a newbie, but I think it is quite useful. As of now, it provides a nicely abstracted out yes/no/cancel dialog box on a console.}
20
+ gem.email = "kedar.mhaswade@gmail.com"
21
+ gem.authors = ["Kedar Mhaswade"]
22
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
23
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ require 'rcov/rcovtask'
37
+ Rcov::RcovTask.new do |test|
38
+ test.libs << 'test'
39
+ test.pattern = 'test/**/test_*.rb'
40
+ test.verbose = true
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "lilutils #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/bin/cli-demo ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ require 'lilutils'
3
+ CLI = LilUtils::CLI
4
+ yn = CLI::NumberedOption.new(1, "Yes/No")
5
+ ync = CLI::NumberedOption.new(2, "Yes/No/Cancel")
6
+ list = CLI::NumberedOptions.new([yn, ync], 0, "Pick your pick for the demo: ", true)
7
+ puts "You chose: #{list.show}"
8
+ puts "Now opposite of the above"
9
+ list = CLI::NumberedOptions.new([yn, ync], 1, "Just press Enter to see what happens", true)
10
+ puts "You chose: #{list.show}"
11
+ puts "Now special case of the above"
12
+ yes_no = CLI::YesNo.new
13
+ puts "You chose: #{yes_no.show}"
14
+ puts "Liked it? Then use it!"
15
+ sc = CLI::Option.new("Show code")
16
+ ex = CLI::Option.new("Just exit")
17
+ yn = CLI::OptionList.new([sc, ex], 0, "What do you want me to do?", true)
18
+ choice = yn.show
19
+ if choice == sc # show me code
20
+ puts "-----------------------------------------------------------------------"
21
+ File.open(__FILE__, "r") do |f|
22
+ f.readlines.each do |line|
23
+ puts line
24
+ end
25
+ puts "-----------------------------------------------------------------------"
26
+ end
27
+ elsif choice == ex # just exit
28
+ puts "Bye!"
29
+ exit 0
30
+ else
31
+ puts "Impossible!"
32
+ end
33
+
@@ -0,0 +1,57 @@
1
+ # Provides for code useful to test algorithms, do benchmarks etc. For example, you might be testing a sorting algorithm
2
+ # and need 100_000 or 1_000_000 randomly generated (supposedly unsorted) strings. Of course, you are not going to test
3
+ # your algorithm with ten or hundred strings or numbers, right?
4
+ module LilUtils
5
+ module AlgoTestUtils
6
+ module DataSets
7
+ ALPHABET = ('a'..'z').to_a + ('0'..'9').to_a
8
+ SIZE = ALPHABET.length
9
+
10
+ # Returns random strings of <b> equal length </b>.
11
+ # The length of each string is determined by the parameter passed.
12
+ # The characters that can appear in returned strings are defined by
13
+ # the {#ALPHABET}.
14
+ # @param howmany [Integer] How many random strings do you need?
15
+ # @param rest [Integer] Optional arguments. First argument should be the length of
16
+ # each string in returned set. If unspecified, this is calculated from first
17
+ # argument, howmany, such that the length is enough to generate strings from the
18
+ # entire ALPHABET.
19
+ def self.ascii_strings(howmany, *rest)
20
+ p howmany, rest if $DEBUG
21
+ raise ArgumentError, "Size must be positive integer" if howmany < 1
22
+ srand(Time.now.to_i)
23
+ strings = []
24
+ of_length = rest[0] ? rest[0] : get_string_length_for(howmany)
25
+ 1.upto howmany do
26
+ strings << get_ascii_string(of_length)
27
+ end
28
+ strings
29
+ end
30
+
31
+ private
32
+
33
+ def self.get_ascii_string(length)
34
+ i = 0
35
+ str = ""
36
+ while i < length
37
+ str << ALPHABET[rand(SIZE)]
38
+ i += 1
39
+ end
40
+ str
41
+ end
42
+
43
+ def self.get_string_length_for(size)
44
+ length = 0
45
+ while size > 0
46
+ length += 1
47
+ size /= SIZE
48
+ end
49
+ length
50
+ end
51
+ end
52
+ end
53
+ end
54
+ # Example:
55
+ #DataSets = LilUtils::AlgoTestUtils::DataSets
56
+ #puts DataSets.ascii_strings(10).sort
57
+ #puts DataSets.ascii_strings(100, 10).sort
@@ -0,0 +1,4 @@
1
+ # used to include code from all of the algo_test_utils classes
2
+ # Add a line here when you add a new class that should be available to clients. Then, clients can just
3
+ # require this one file.
4
+ require 'lilutils/algo_test_utils/data_sets'
@@ -0,0 +1,226 @@
1
+ # Adds the simple_name method to Module.
2
+ # @note A simple_name is just the name of the class/module without encompassing modules
3
+ class Module
4
+ # suggested by Brian Candler
5
+ def simple_name
6
+ name.gsub(/^.*::/, '')
7
+ end
8
+ end
9
+
10
+ # The main module, wrapped inside LilUtils
11
+ # Provides functionality to interact with users on a <i> command line </i>
12
+ module LilUtils
13
+
14
+ module CLI
15
+
16
+ # Models an arbitrary option that user has choice to choose. Every Option has a name and a key.
17
+ # The name of an Option is its given name capitalized and its key is first character in its name in lower case. For example,
18
+ # for an option constructed with the string "separate", the actual name is "Separate" and key is 's'.
19
+ # Provides behavior for such an Option as far as its display, equality, validity etc. is
20
+ # concerned.
21
+ class Option
22
+ attr_reader :name
23
+ # constructs this option with a name. The first character of this is regarded its key, e.g. "Yes" and 'y'.
24
+ # Unless an option has a proper name (e.g. "Mozart"), do not use the default value of the parameter
25
+ def initialize(name=self.class.simple_name)
26
+ @name = name.capitalize
27
+ @name.freeze
28
+ end
29
+
30
+ def ==(other)
31
+ (other.is_a? Option) && (@name == other.name)
32
+ end
33
+
34
+ def valid_response(r)
35
+ key == r
36
+ end
37
+
38
+ def as_default
39
+ "*#{@name} (#{key})*"
40
+ end
41
+
42
+ def as_non_default
43
+ "#{@name} (#{key})"
44
+ end
45
+
46
+ def to_s
47
+ @name
48
+ end
49
+
50
+ def key
51
+ @name[0].downcase
52
+ end
53
+ end
54
+
55
+ # Models an Option that is completely specified by a single letter, e.g. "Y"
56
+ class SingleLetterOption < Option
57
+ def as_default
58
+ key.upcase
59
+ end
60
+
61
+ def as_non_default
62
+ key
63
+ end
64
+ end
65
+ # The class that identifies a user "Yes". This class is an example of an option where the name of
66
+ # the option is derived from the name of the class itself. Handy extension.
67
+ class Yes < SingleLetterOption
68
+ end
69
+
70
+ # The class that identifies a user "No".
71
+ # @see Yes
72
+ class No < SingleLetterOption
73
+ end
74
+
75
+ # The class that identifies a user "Cancel".
76
+ class Cancel < SingleLetterOption
77
+ end
78
+
79
+ # An Option with a name and a positive number used to identify its selection. This is useful when two
80
+ # Options start with the same character (e.g. "Chai" and "Coffee")
81
+ class NumberedOption < Option
82
+ attr_reader :number
83
+
84
+ def initialize(number, name)
85
+ super(name)
86
+ @number = number
87
+ end
88
+
89
+ # redefine
90
+ def ==(other)
91
+ @name == other.name && @number == other.number
92
+ end
93
+
94
+ # redefine
95
+ def valid_response(r)
96
+ @number.to_s == r
97
+ end
98
+
99
+ # redefine
100
+ def as_default
101
+ "*#{@name} (#{@number})*"
102
+ end
103
+
104
+ # redefine
105
+ def as_non_default
106
+ "#{@name} (#{@number})"
107
+ end
108
+
109
+ def to_s
110
+ "#{@name}, #{number}"
111
+ end
112
+ end
113
+
114
+ # Singletons
115
+ YES = Yes.new
116
+ NO = No.new
117
+ CANCEL = Cancel.new
118
+ YN = [YES, NO]
119
+ YNC = YN + [CANCEL]
120
+
121
+ # Models a generic list of options that determines if a particular key results in valid response.
122
+ # Takes care of generic behavior (display, validity of user response, defaults) when a list of
123
+ # options is presented to the user.
124
+ class OptionList
125
+ DEFAULT_PROMPT = "Do you want to proceed?"
126
+
127
+ def initialize(options, default_option_index, prompt, strict, istream=$stdin, ostream=$stdout)
128
+ # check, list must be non-nil and must have at least two elements
129
+ @options = options
130
+ @default_option = options[default_option_index]
131
+ @prompt = prompt
132
+ @strict = strict
133
+ @istream = istream
134
+ @ostream = ostream
135
+ end
136
+
137
+ def valid_response?(r)
138
+ @options.each do |option|
139
+ debug "#{option} == #{@default_option} ? : (#{option == @default_option})"
140
+ return option if (option == @default_option && r == "") || (option.valid_response(r))
141
+ end
142
+ nil
143
+ end
144
+
145
+ # subclasses may override, but don't have to
146
+ def display_string
147
+ long_str = ""
148
+ @options.each_with_index do |option, index|
149
+ if option == @default_option
150
+ long_str << option.as_default
151
+ else
152
+ long_str << option.as_non_default
153
+ end
154
+ long_str << "/" if index < (@options.size-1)
155
+ end
156
+ "#{@prompt} [#{long_str}] "
157
+ end
158
+
159
+ # the whole point is subclasses get this for free
160
+ def show
161
+ @ostream.print "#{display_string}"
162
+ response = @istream.gets.chomp!
163
+ chosen = valid_response? response
164
+ if @strict
165
+ until chosen
166
+ @ostream.print "\nSorry, I don't understand #{response}, #{display_string}"
167
+ response = @istream.gets.chomp!
168
+ chosen = valid_response? response
169
+ end
170
+ else
171
+ chosen = @default_option # when not strict, any key => default option
172
+ end
173
+ chosen
174
+ end
175
+
176
+ def debug(str)
177
+ puts "debug: #{str}" if $DEBUG
178
+ end
179
+ end
180
+ # A class that models the simple yes/no interaction with user on command line. Provides several ways to customize.
181
+ # @example:
182
+ # ...
183
+ # Do you want to proceed [Y/n]? y (Enter)
184
+ # A simple Enter or 'y' returns the YES object. Pressing n returns NO object. Pressing anything else returns a
185
+ # value that depends on the mode which can be <i>strict</i>. If the mode is strict, it keeps on asking the user till s/he
186
+ # presses the correct key. If the mode is not strict, any invalid key (other than y, n, or enter) results in whatever
187
+ # the default option is. Note that the default option is shown as upper case key.
188
+ # @see CLI#YES
189
+ # @see #NO
190
+ class YesNo < OptionList
191
+ # Creates a YesNo interaction.
192
+ # @param [Option] default_option the option that should be treated as default. Its default is #YES :-)
193
+ # @param [String] prompt prompt that should appear. Default is #DEFAULT_PROMPT
194
+ # @param [Boolean] strict decides if the interaction should demand exact response and loop till user behaves
195
+ # @param [IO] istream input stream to read user response from
196
+ # @param [IO] ostream output stream to display output to
197
+ def initialize(default_option=YES, prompt=DEFAULT_PROMPT, strict=true, istream=$stdin, ostream=$stdout)
198
+ super(YN, YN.index(default_option), prompt, strict, istream, ostream)
199
+ end
200
+
201
+ end
202
+
203
+ class YesNoCancel < OptionList
204
+ def initialize(default_option=YES, prompt=DEFAULT_PROMPT, strict=true, istream=$stdin, ostream=$stdout)
205
+ super(YNC, YNC.index(default_option), prompt, strict, istream, ostream)
206
+ end
207
+ end
208
+ # An OptionList where all the Options are NumberedOptions. You can't mix NumberedOptions with others.
209
+ class NumberedOptions < OptionList
210
+ # all the options must be NumberedOption instances
211
+ def initialize(options, default_option_index, prompt, strict, istream=$stdin, ostream=$stdout)
212
+ super
213
+ end
214
+ end
215
+ end
216
+ end
217
+
218
+ #CLI=LilUtils::CLI
219
+ #puts CLI::YesNo.new.show
220
+ #puts CLI::YesNo.new(LilUtils::CLI::NO).show
221
+ #puts CLI::YesNoCancel.new.show
222
+ #puts CLI::OptionList.new([CLI::Option.new("Mozart"), CLI::Option.new("Beethoven")], 1, "Pick your pick: ", true).show
223
+ #one = CLI::NumberedOption.new(1, "Standard")
224
+ #two = CLI::NumberedOption.new(2, "Expedite")
225
+ #three = CLI::NumberedOption.new(3, "Special")
226
+ #puts CLI::NumberedOptions.new([one, two, three], 0, "Select shipping method: ", true).show
@@ -0,0 +1,4 @@
1
+ # Used to include code from all of the cli classes.
2
+ # Add a line here when you add a new class that should be available to clients. Then, clients can just
3
+ # require this one file.
4
+ require 'lilutils/cli/cli'
@@ -0,0 +1,2 @@
1
+ module Misc
2
+ end
@@ -0,0 +1,21 @@
1
+ module LilUtils
2
+ module Misc
3
+ module Pascal
4
+ # Returns the nth row of the Pascal's triangle as an array of n+1 elements.
5
+ # This is an O(n) algorithm. Uses: nCr = nCr-1*(n-r+1)/r which calculates
6
+ # @param [Integer] n starts at 1
7
+ # @return [Array] of Integers representing numbers in given row.
8
+ def self.row(n)
9
+ raise ArgumentError, "#{n} is not valid" if !n.is_a?(Integer) || n < 1
10
+ len = n == 1 ? 1 : n + 1
11
+ a = Array.new(len); a[0] = a[-1] = 1
12
+ 1.upto n/2 do |r|
13
+ a[r] = a[-r-1] = a[r-1] * (n-r+1)/r
14
+ r += 1
15
+ end
16
+ a
17
+ end
18
+ end
19
+ end
20
+ end
21
+ #p LilUtils::Misc::Pascal.row(ARGV[0].to_i)
@@ -0,0 +1,5 @@
1
+ # used to include code from all of the misc classes
2
+ # Add a line here when you add a new class that should be available to clients. Then, clients can just
3
+ # require this one file.
4
+ require 'lilutils/misc/misc'
5
+ require 'lilutils/misc/pascal'
data/lib/lilutils.rb ADDED
@@ -0,0 +1,8 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+ require 'lilutils/cli_entry'
4
+ require 'lilutils/misc_entry'
5
+ require 'lilutils/algo_test_utils_entry'
6
+ module Lilutils
7
+ VERSION = '0.0.1'
8
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/lilutils.rb'}"
9
+ puts "Loading lilutils gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,12 @@
1
+ require "test/unit"
2
+ require "lilutils/algo_test_utils/data_sets"
3
+
4
+ class DataSetsTest < Test::Unit::TestCase
5
+
6
+ DS = LilUtils::AlgoTestUtils::DataSets
7
+
8
+ def test_ascii_strings
9
+ strs = DS.ascii_strings(100, 5)
10
+ assert_equal(100, strs.size)
11
+ end
12
+ end
@@ -0,0 +1,126 @@
1
+ require "test/unit"
2
+ require File.dirname(__FILE__) + '/../../lib/lilutils'
3
+ require 'stringio'
4
+
5
+ class BasicCLITest < Test::Unit::TestCase
6
+
7
+ CLI = LilUtils::CLI
8
+ # Called before every test method runs. Can be used
9
+ # to set up fixture information.
10
+ def setup
11
+ # Do nothing
12
+ end
13
+
14
+ # Called after every test method runs. Can be used to tear
15
+ # down fixture information.
16
+
17
+ def teardown
18
+ # Do nothing
19
+ end
20
+
21
+ def test_yes_no
22
+ is = StringIO.open("y\n", "r")
23
+ os = StringIO.open("", "w")
24
+ yes = CLI::YesNo.new(CLI::YES, CLI::YesNo::DEFAULT_PROMPT, true, is, os)
25
+ assert_equal(CLI::YES, yes.show)
26
+
27
+ is = StringIO.open("\n", "r") # just enter a newline character
28
+ no = CLI::YesNo.new(CLI::NO, CLI::YesNo::DEFAULT_PROMPT, true, is, os)
29
+ assert_equal(CLI::NO, no.show)
30
+
31
+ is = StringIO.open("c\n", "r") # invalid character
32
+ no = CLI::YesNo.new(CLI::NO, CLI::YesNo::DEFAULT_PROMPT, false, is, os) # we must not be strict here
33
+ assert_equal(CLI::NO, no.show) # default should prevail as 'c' is not recognized
34
+
35
+ is = StringIO.open("go away\nz\n\n", "r") # 2 invalid attempts and then a valid attempt to select the default
36
+ no = CLI::YesNo.new(CLI::NO, CLI::YesNo::DEFAULT_PROMPT, false, is, os) # we must not be strict here
37
+ assert_equal(CLI::NO, no.show) # default should prevail as we encounter a mere newline
38
+ is.close
39
+ os.close
40
+ end
41
+
42
+ def test_yes_no_cancel
43
+ is = StringIO.open("", "r")
44
+ os = StringIO.open("", "w")
45
+ CLI::YNC.each do |option|
46
+ is = StringIO.open("#{option.key}\n", "r")
47
+ ync = CLI::YesNoCancel.new(option, "test", true, is, os)
48
+ assert_equal(option, ync.show)
49
+ end
50
+ CLI::YNC.each do |option|
51
+ is = StringIO.open("\n", "r") # default option matches a mere Enter
52
+ ync = CLI::YesNoCancel.new(option, "test", true, is, os)
53
+ assert_equal(option, ync.show)
54
+ end
55
+ is.close
56
+ os.close
57
+ end
58
+
59
+ def test_display_string
60
+ prompt = "Pick one: "
61
+ options = []
62
+ options << CLI::SingleLetterOption.new("Coffee") << CLI::SingleLetterOption.new("Tea") << CLI::SingleLetterOption.new("Milk")
63
+ # make Tea the default
64
+ list = CLI::OptionList.new(options, 1, prompt, true)
65
+ expected = prompt + " [c/T/m] "
66
+ assert_equal(expected, list.display_string)
67
+ end
68
+
69
+ def test_generic_1
70
+ os = StringIO.open("", "w")
71
+ cat = CLI::Option.new("cat")
72
+ dog = CLI::Option.new("dog")
73
+ elephant = CLI::Option.new("elephant")
74
+ frog = CLI::Option.new("frog")
75
+
76
+ is = StringIO.open("z\ne\n", "r") # choose invalid option and then elephant
77
+ list = CLI::OptionList.new([cat, dog, elephant, frog], 3, "", true, is, os) # make frog the default
78
+ assert_equal(elephant, list.show)
79
+
80
+ is.close
81
+ os.close
82
+ end
83
+
84
+ def test_numbers_1
85
+ os = StringIO.open("", "w")
86
+ latte = CLI::NumberedOption.new(1, "Latte")
87
+ mocha = CLI::NumberedOption.new(2, "Mocha")
88
+ chai = CLI::NumberedOption.new(3, "Chai")
89
+ machiato = CLI::NumberedOption.new(4, "Caramel Machiato")
90
+ is = StringIO.open("3\n", "r") # choose Chai
91
+ list = CLI::NumberedOptions.new([latte, mocha, chai, machiato], 0, "Pick your favorite: ", true, is, os) # make latte the default
92
+ assert_equal(chai, list.show)
93
+
94
+ is.close
95
+ os.close
96
+ end
97
+
98
+ def test_long_names
99
+ os = StringIO.open("", "w")
100
+
101
+ l = CLI::Option.new("Left Turn")
102
+ r = CLI::Option.new("Right Turn")
103
+ u = CLI::Option.new("U Turn")
104
+
105
+ is = StringIO.open("u\n", "r") # take a U turn
106
+ message = "What should I do?"
107
+ list = CLI::OptionList.new([l, r, u], 1, message, true, is, os)
108
+ # puts list.display_string
109
+ assert_equal(u, list.show)
110
+
111
+ is = StringIO.open("\n", "r") # right turn as default
112
+ list = CLI::OptionList.new([l, r, u], 1, message, true, is, os)
113
+ assert_equal(r, list.show) # enter = right
114
+
115
+ is = StringIO.open("r\n", "r") # right turn explicit
116
+ list = CLI::OptionList.new([l, r, u], 1, message, true, is, os)
117
+ assert_equal(r, list.show) # right turn selected
118
+
119
+ is = StringIO.open("e\nl\n", "r") # invalid and then left
120
+ list = CLI::OptionList.new([l, r, u], 1, message, true, is, os)
121
+ assert_equal(l, list.show) # left
122
+
123
+ expected_display_string = "#{message} [Left turn (l)/*Right turn (r)*/U turn (u)] "
124
+ assert_equal(expected_display_string, list.display_string)
125
+ end
126
+ end
@@ -0,0 +1,28 @@
1
+ require "test/unit"
2
+ require File.dirname(__FILE__) + '/../../lib/lilutils'
3
+ require 'stringio'
4
+
5
+ class PascalTest < Test::Unit::TestCase
6
+
7
+ PASCAL = LilUtils::Misc::Pascal
8
+ # Called before every test method runs. Can be used
9
+ # to set up fixture information.
10
+ def setup
11
+ # Do nothing
12
+ end
13
+
14
+ # Called after every test method runs. Can be used to tear
15
+ # down fixture information.
16
+
17
+ def teardown
18
+ # Do nothing
19
+ end
20
+
21
+ def test_first_six
22
+ rows = {1 => [1], 2 => [1, 2, 1], 3 => [1, 3, 3, 1], 4 => [1, 4, 6, 4, 1],
23
+ 5 => [1, 5, 10, 10, 5, 1], 6 => [1, 6, 15, 20, 15, 6, 1]}
24
+ rows.each_pair do |row_no, row |
25
+ assert_equal(row, PASCAL.row(row_no))
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require 'lilutils'
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+ require 'cli/cli_basic_test'
3
+ require 'algo_test_utils/data_sets_test'
4
+ require 'misc/misc_pascal_test'
5
+
6
+ class TestLilutils < Test::Unit::TestCase
7
+
8
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lilutils
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Kedar Mhaswade
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-08 00:00:00 -08:00
18
+ default_executable: cli-demo
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: shoulda
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ prerelease: false
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 1
42
+ - 0
43
+ - 0
44
+ version: 1.0.0
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: jeweler
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 1
57
+ - 5
58
+ - 2
59
+ version: 1.5.2
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: rcov
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ type: :development
74
+ prerelease: false
75
+ version_requirements: *id004
76
+ description: Provides little utilties. It's a gem by a newbie, but I think it is quite useful. As of now, it provides a nicely abstracted out yes/no/cancel dialog box on a console.
77
+ email: kedar.mhaswade@gmail.com
78
+ executables:
79
+ - cli-demo
80
+ extensions: []
81
+
82
+ extra_rdoc_files:
83
+ - README.rdoc
84
+ files:
85
+ - History.txt
86
+ - Manifest.txt
87
+ - PostInstall.txt
88
+ - README.rdoc
89
+ - Rakefile
90
+ - bin/cli-demo
91
+ - lib/lilutils.rb
92
+ - lib/lilutils/algo_test_utils/data_sets.rb
93
+ - lib/lilutils/algo_test_utils_entry.rb
94
+ - lib/lilutils/cli/cli.rb
95
+ - lib/lilutils/cli_entry.rb
96
+ - lib/lilutils/misc/misc.rb
97
+ - lib/lilutils/misc/pascal.rb
98
+ - lib/lilutils/misc_entry.rb
99
+ - script/console
100
+ - script/destroy
101
+ - script/generate
102
+ - test/algo_test_utils/data_sets_test.rb
103
+ - test/cli/cli_basic_test.rb
104
+ - test/misc/misc_pascal_test.rb
105
+ - test/test_helper.rb
106
+ - test/test_lilutils.rb
107
+ has_rdoc: true
108
+ homepage: http://github.com/kedarmhaswade/lilutils
109
+ licenses:
110
+ - MIT
111
+ post_install_message:
112
+ rdoc_options: []
113
+
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ hash: -896547783063548006
122
+ segments:
123
+ - 0
124
+ version: "0"
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ segments:
131
+ - 0
132
+ version: "0"
133
+ requirements: []
134
+
135
+ rubyforge_project:
136
+ rubygems_version: 1.3.7
137
+ signing_key:
138
+ specification_version: 3
139
+ summary: Little utilities for everyone
140
+ test_files:
141
+ - test/algo_test_utils/data_sets_test.rb
142
+ - test/cli/cli_basic_test.rb
143
+ - test/misc/misc_pascal_test.rb
144
+ - test/test_helper.rb
145
+ - test/test_lilutils.rb