Skip to content

Commit f455b72

Browse files
committed
Split out lookup; created separate test. Fixed test cases.
1 parent e41044f commit f455b72

File tree

5 files changed

+161
-50
lines changed

5 files changed

+161
-50
lines changed

Gemspec

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
Gem::Specification.new do |s|
22
s.name = 'cmd-utils'
3-
s.version = '1.0.4'
4-
s.date = '2013-08-01'
3+
s.version = '1.0.5'
4+
s.date = '2013-08-19'
55
s.summary = "Utilities for ruby command line scripts"
66
s.description = "Some handy utilities for writing command line scripts in ruby."
77
s.author = "Alan K. Stebbens"
88
s.email = '[email protected]'
9-
s.files = ["lib/cmd-utils.rb"]
10-
s.test_file = 'tests/test-cmd-utils.rb'
9+
s.files = ["lib/cmd-utils.rb", "lib/lookup.rb"]
10+
s.test_files = ['tests/test-cmd-utils.rb', 'tests/test-lookup.rb']
1111
s.homepage = 'http://github.com/aks/cmd-utils'
1212
s.license = 'GPL-2'
1313
end

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,38 @@ If `err_notfound` is nil, do not report an error, and return nil.
9191

9292
If `err_ambig` is nil, return the list of possible results.
9393

94+
lookup
95+
======
96+
97+
usage:
98+
99+
require 'lookup'
100+
101+
lookup: lookup a keyword in a list, in a case-insensitive, disambiguous way
102+
103+
result = lookup list, key, err_notfound="%s not found", err_ambig="% is ambiguous"
104+
result = list.lookup( key, err_notfound, err_ambig )
105+
result = list.lookup( key, err_notfound )
106+
result = list.lookup( key )
107+
108+
Lookup key in list, which can be an array or a hash. Return the one that
109+
matches exactly, or matches using case-insensitive, unambiguous matches, or
110+
raise a LookupError with a message.
111+
112+
`LookupError` is a subclass of StandardError.
113+
114+
`LookupNotFoundError`, a subclass of `LookupError`, is raised when a keyword is
115+
not found, and only if `err_notfound` is not nil.
116+
117+
`LookupAmbigError`, a subsclass of `LookupError`, is raised when a keyword search
118+
matches multiple entries from the list, and only if `err_ambig` is not nil.
119+
120+
If `err_notfound` is nil, do not raise a `LookupNotFoundError` error, and return
121+
nil.
122+
123+
If `err_ambigmsg` is nil, do not raise a `LookupAmbigError`, and return the list
124+
of possible results.
125+
94126
Author
95127
------
96128

lib/cmd-utils.rb

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#
66
# require 'cmd-utils'
77
#
8-
# Utilities for output, running commands, and looking up values.
8+
# Utilities for output, and running commands.
99
#
1010
# The output and run methods rely on some external variables:
1111
#
@@ -129,13 +129,15 @@ def error *args
129129
args = yield if args.size == 0 && block_given?
130130
code = args.size > 0 && args[0].class == Fixnum ? args.shift : 1
131131
$stderr.puts(*args)
132+
$stderr.flush
132133
exit code
133134
end
134135

135136
def errorf *args
136137
args = yield if args.size == 0 && block_given?
137138
code = args.size > 0 && args[0].class == Fixnum ? args.shift : 1
138139
$stderr.printf(*args)
140+
$stderr.flush
139141
exit code
140142
end
141143

@@ -181,50 +183,5 @@ def safe_run cmd=nil
181183
end
182184
end
183185

184-
##
185-
# :call-seq:
186-
# result = lookup list, key, err_notfound="%s not found", err_ambig="% is ambiguous"
187-
# result = list.lookup( key, err_notfound, err_ambig )
188-
# result = list.lookup( key, err_notfound )
189-
# result = list.lookup( key )
190-
#
191-
# Lookup key in list, which is an array (or hash). Return the one that matches
192-
# unambiguously, or report an error.
193-
#
194-
# If err_notfound is nil, do not report an error, and return nil.
195-
#
196-
# If err_ambigmsg is nil, return the list of possible results.
197-
198-
def key_lookup list, key, err_notfound="%s not found\n", err_ambig="%s is ambiguous\n"
199-
keylist = list.keys if list.class == Hash
200-
if exact = keylist.grep(/^#{key}$/i) # exact matche?
201-
return exact
202-
end
203-
keys = keylist.grep(/^#{key}/i)
204-
case keys.size
205-
when 0
206-
unless err_notfound.nil?
207-
errorf err_notfound, key
208-
end
209-
return nil
210-
when 1
211-
return keys[0]
212-
else
213-
unless err_ambig.nil?
214-
errorf err_ambig, key
215-
end
216-
return keys
217-
end
218-
end
219-
220-
alias lookup key_lookup
221-
222-
class Array
223-
def lookup key, err_notfound="%s not found\n", err_ambig="%s is ambiguous\n"
224-
key_lookup self, key, err_notfound, err_ambig
225-
end
226-
end
227-
228-
229186
# end of cmd-utils.sh
230187
# vim: set ai sw=2

lib/lookup.rb

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# lookup.rb -- simple keyword lookup routine
2+
#
3+
# Alan K. Stebbens <[email protected]>
4+
#
5+
# require 'lookup'
6+
#
7+
# lookup - lookup a keyword in a list, in a case-insensitive, disambiguous way
8+
#
9+
# :call-seq:
10+
# result = lookup list, key, err_notfound="%s not found", err_ambig="% is ambiguous"
11+
# result = list.lookup( key, err_notfound, err_ambig )
12+
# result = list.lookup( key, err_notfound )
13+
# result = list.lookup( key )
14+
#
15+
# Lookup key in list, which can be an array or a hash. Return the one that
16+
# matches exactly, or matches using case-insensitive, unambiguous matches, or
17+
# raise a LookupError with a message.
18+
#
19+
# LookupError is a subclass of StandardError.
20+
#
21+
# LookupNotFoundError, a subclass of LookupError, is raised when a keyword is
22+
# not found, and only if `err_notfound` is not nil.
23+
#
24+
# LookupAmbigError, a subsclass of LookupError, is raised when a keyword search
25+
# matches multiple entries from the list, and only if `err_ambig` is not nil.
26+
#
27+
# If err_notfound is nil, do not raise a LookupNotFoundError error, and return
28+
# nil.
29+
#
30+
# If err_ambigmsg is nil, do not raise a LookupAmbigError, and return the list
31+
# of possible results.
32+
33+
class LookupError < StandardError ; end
34+
class LookupNotFoundError < LookupError ; end
35+
class LookupAmbigError < LookupError ; end
36+
37+
def key_lookup list, key, err_notfound="%s not found\n", err_ambig="%s is ambiguous\n"
38+
keylist = list.is_a?(Hash) ? list.keys : list
39+
if exact = keylist.grep(/^#{key}$/i) # exact match?
40+
return exact.shift if exact && exact.size == 1
41+
end
42+
keys = keylist.grep(/^#{key}/i)
43+
case keys.size
44+
when 0
45+
unless err_notfound.nil?
46+
raise LookupNotFoundError, sprintf(err_notfound, key)
47+
end
48+
return nil
49+
when 1
50+
return keys[0]
51+
else
52+
unless err_ambig.nil?
53+
raise LookupAmbigError, sprintf(err_ambig, key)
54+
end
55+
return keys
56+
end
57+
end
58+
59+
alias lookup key_lookup
60+
61+
class Array
62+
def lookup key, err_notfound="%s not found\n", err_ambig="%s is ambiguous\n"
63+
key_lookup self, key, err_notfound, err_ambig
64+
end
65+
end
66+
67+
class Hash
68+
def lookup key, err_notfound="%s not found\n", err_ambig="%s is ambiguous\n"
69+
self.keys.lookup(key, err_notfound, err_ambig)
70+
end
71+
end

tests/test-lookup.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env ruby
2+
# test-cmd-utils.rb -- simple tester for cmd-utils
3+
#
4+
require 'rubygems'
5+
gem 'minitest'
6+
require 'minitest/autorun'
7+
require 'lookup'
8+
9+
class NilClass ; def to_s ; '' ; end ; end
10+
11+
class TestLookup < MiniTest::Test
12+
13+
def do_lookup input, output, errok=nil
14+
found = nil
15+
err = ''
16+
begin
17+
found = lookup(@keywords, input)
18+
found = found.first if found && found.size == 1
19+
rescue LookupError => err
20+
end
21+
if errok
22+
refute_empty err.to_s, "Input = #{input}\nErr = #{err.to_s}\n"
23+
else
24+
assert_empty err.to_s, "Input = #{input}\nErr = #{err}\n"
25+
assert_equal found, output, "Input = #{input}\nOutput = #{output}\n"
26+
end
27+
end
28+
29+
def test_lookup_many
30+
@keywords = %w( set get show edit reset delete count )
31+
do_lookup 'se', 'set'
32+
do_lookup 'set', 'set'
33+
do_lookup 'SET', 'set'
34+
do_lookup 'show', 'show'
35+
do_lookup 'sh', 'show'
36+
do_lookup 'e', 'edit'
37+
do_lookup 'ed', 'edit'
38+
do_lookup 's', [%w( set show )], true
39+
end
40+
41+
def test_lookup_exact
42+
@keywords = %w( email emails reason reasons )
43+
do_lookup 'email', 'email'
44+
do_lookup 'emails', 'emails'
45+
do_lookup 'emai', 'email', true
46+
do_lookup 'rea', 'reason', true
47+
do_lookup 'reason', 'reason'
48+
do_lookup 'reasons', 'reasons'
49+
end
50+
51+
end

0 commit comments

Comments
 (0)