pwl 0.0.1 → 0.0.2
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/Gemfile +10 -12
- data/Gemfile.lock +19 -14
- data/README.md +1 -1
- data/VERSION +1 -1
- data/bin/pwl +51 -43
- data/lib/pwl.rb +6 -2
- data/lib/pwl/{store.rb → locker.rb} +19 -21
- data/lib/pwl/presenter/html.rb +19 -0
- data/lib/pwl/presenter/json.rb +22 -0
- data/lib/pwl/presenter/yaml.rb +23 -0
- data/pwl.gemspec +35 -23
- data/templates/export.html.erb +2 -2
- data/test/acceptance/test_add.rb +19 -0
- data/test/acceptance/test_delete.rb +1 -1
- data/test/acceptance/test_export.rb +4 -4
- data/test/acceptance/test_export_json.rb +59 -0
- data/test/acceptance/test_export_yaml.rb +59 -0
- data/test/acceptance/test_get.rb +1 -1
- data/test/acceptance/test_init.rb +6 -6
- data/test/acceptance/test_list.rb +3 -3
- data/test/acceptance/test_passwd.rb +2 -2
- data/test/fixtures/test_all.json +19 -0
- data/test/fixtures/test_all.yaml +11 -0
- data/test/fixtures/test_empty.json +7 -0
- data/test/fixtures/test_empty.yaml +5 -0
- data/test/helper.rb +8 -8
- data/test/unit/test_store_construction.rb +26 -26
- data/test/unit/test_store_crud.rb +35 -35
- data/test/unit/test_store_metadata.rb +16 -16
- data/test/unit/test_store_password_policy.rb +6 -6
- data/test/unit/test_store_security.rb +13 -13
- metadata +82 -27
- data/test/acceptance/test_put.rb +0 -19
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Pwl
|
4
|
+
module Presenter
|
5
|
+
class Html
|
6
|
+
attr_reader :locker # used by the ERB template
|
7
|
+
DEFAULT_EXPORT_TEMPLATE = File.join(File.dirname(__FILE__), *%w[.. .. .. templates export.html.erb])
|
8
|
+
|
9
|
+
def initialize(locker)
|
10
|
+
@locker = locker
|
11
|
+
@template = ERB.new(File.read(DEFAULT_EXPORT_TEMPLATE))
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
@template.result(binding)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'jbuilder'
|
2
|
+
|
3
|
+
module Pwl
|
4
|
+
module Presenter
|
5
|
+
class Json
|
6
|
+
def initialize(locker)
|
7
|
+
@locker = locker
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
Jbuilder.encode do |json|
|
12
|
+
json.(@locker, :created, :last_accessed, :last_modified)
|
13
|
+
|
14
|
+
json.entries @locker.all do |json, entry|
|
15
|
+
json.key entry.first
|
16
|
+
json.value entry.last
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Pwl
|
4
|
+
module Presenter
|
5
|
+
class Yaml
|
6
|
+
def initialize(locker)
|
7
|
+
@locker = locker
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
result = {}
|
12
|
+
result[:created] = @locker.created.to_s
|
13
|
+
result[:last_accessed] = @locker.last_accessed.to_s
|
14
|
+
result[:last_modified] = @locker.last_modified.to_s
|
15
|
+
result[:entries] = []
|
16
|
+
@locker.all.each{|entry|
|
17
|
+
result[:entries] << {:key => entry.first, :value => entry.last}
|
18
|
+
}
|
19
|
+
result.to_yaml
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/pwl.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "pwl"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Nicholas E. Rabenau"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-05-02"
|
13
13
|
s.description = "pwl is a secure password locker for the commandline"
|
14
14
|
s.email = "nerab@gmx.net"
|
15
15
|
s.executables = ["pwl", "pwl"]
|
@@ -33,22 +33,31 @@ Gem::Specification.new do |s|
|
|
33
33
|
"lib/pwl/dialog/cocoa.rb",
|
34
34
|
"lib/pwl/dialog/console.rb",
|
35
35
|
"lib/pwl/dialog/gnome.rb",
|
36
|
+
"lib/pwl/locker.rb",
|
36
37
|
"lib/pwl/message.rb",
|
37
38
|
"lib/pwl/password_policy.rb",
|
38
|
-
"lib/pwl/
|
39
|
+
"lib/pwl/presenter/html.rb",
|
40
|
+
"lib/pwl/presenter/json.rb",
|
41
|
+
"lib/pwl/presenter/yaml.rb",
|
39
42
|
"pwl.gemspec",
|
40
43
|
"templates/export.html.erb",
|
44
|
+
"test/acceptance/test_add.rb",
|
41
45
|
"test/acceptance/test_basics.rb",
|
42
46
|
"test/acceptance/test_delete.rb",
|
43
47
|
"test/acceptance/test_dialogs.rb",
|
44
48
|
"test/acceptance/test_export.rb",
|
49
|
+
"test/acceptance/test_export_json.rb",
|
50
|
+
"test/acceptance/test_export_yaml.rb",
|
45
51
|
"test/acceptance/test_get.rb",
|
46
52
|
"test/acceptance/test_init.rb",
|
47
53
|
"test/acceptance/test_list.rb",
|
48
54
|
"test/acceptance/test_passwd.rb",
|
49
|
-
"test/acceptance/test_put.rb",
|
50
55
|
"test/fixtures/test_all.html",
|
56
|
+
"test/fixtures/test_all.json",
|
57
|
+
"test/fixtures/test_all.yaml",
|
51
58
|
"test/fixtures/test_empty.html",
|
59
|
+
"test/fixtures/test_empty.json",
|
60
|
+
"test/fixtures/test_empty.yaml",
|
52
61
|
"test/helper.rb",
|
53
62
|
"test/unit/test_error.rb",
|
54
63
|
"test/unit/test_message.rb",
|
@@ -61,34 +70,37 @@ Gem::Specification.new do |s|
|
|
61
70
|
s.homepage = "http://github.com/nerab/pwl"
|
62
71
|
s.licenses = ["MIT"]
|
63
72
|
s.require_paths = ["lib"]
|
64
|
-
s.rubygems_version = "1.8.
|
73
|
+
s.rubygems_version = "1.8.24"
|
65
74
|
s.summary = "Command-line password locker"
|
66
75
|
|
67
76
|
if s.respond_to? :specification_version then
|
68
77
|
s.specification_version = 3
|
69
78
|
|
70
79
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
71
|
-
s.add_runtime_dependency(%q<encryptor>, ["
|
72
|
-
s.add_runtime_dependency(%q<commander>, ["
|
73
|
-
s.add_runtime_dependency(%q<activesupport>, ["
|
74
|
-
s.
|
75
|
-
s.add_development_dependency(%q<
|
76
|
-
s.add_development_dependency(%q<
|
80
|
+
s.add_runtime_dependency(%q<encryptor>, ["~> 1.1"])
|
81
|
+
s.add_runtime_dependency(%q<commander>, ["~> 4.1"])
|
82
|
+
s.add_runtime_dependency(%q<activesupport>, ["~> 3.2"])
|
83
|
+
s.add_runtime_dependency(%q<jbuilder>, ["~> 0.4"])
|
84
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.1"])
|
85
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.1"])
|
86
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8"])
|
77
87
|
else
|
78
|
-
s.add_dependency(%q<encryptor>, ["
|
79
|
-
s.add_dependency(%q<commander>, ["
|
80
|
-
s.add_dependency(%q<activesupport>, ["
|
81
|
-
s.add_dependency(%q<
|
82
|
-
s.add_dependency(%q<
|
83
|
-
s.add_dependency(%q<
|
88
|
+
s.add_dependency(%q<encryptor>, ["~> 1.1"])
|
89
|
+
s.add_dependency(%q<commander>, ["~> 4.1"])
|
90
|
+
s.add_dependency(%q<activesupport>, ["~> 3.2"])
|
91
|
+
s.add_dependency(%q<jbuilder>, ["~> 0.4"])
|
92
|
+
s.add_dependency(%q<rdoc>, ["~> 3.1"])
|
93
|
+
s.add_dependency(%q<bundler>, ["~> 1.1"])
|
94
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
84
95
|
end
|
85
96
|
else
|
86
|
-
s.add_dependency(%q<encryptor>, ["
|
87
|
-
s.add_dependency(%q<commander>, ["
|
88
|
-
s.add_dependency(%q<activesupport>, ["
|
89
|
-
s.add_dependency(%q<
|
90
|
-
s.add_dependency(%q<
|
91
|
-
s.add_dependency(%q<
|
97
|
+
s.add_dependency(%q<encryptor>, ["~> 1.1"])
|
98
|
+
s.add_dependency(%q<commander>, ["~> 4.1"])
|
99
|
+
s.add_dependency(%q<activesupport>, ["~> 3.2"])
|
100
|
+
s.add_dependency(%q<jbuilder>, ["~> 0.4"])
|
101
|
+
s.add_dependency(%q<rdoc>, ["~> 3.1"])
|
102
|
+
s.add_dependency(%q<bundler>, ["~> 1.1"])
|
103
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
92
104
|
end
|
93
105
|
end
|
94
106
|
|
data/templates/export.html.erb
CHANGED
@@ -44,12 +44,12 @@
|
|
44
44
|
<td colspan="2">
|
45
45
|
This <a href="http://rdoc.info/github/nerab/pwl/master/frames">pwl</a> export was created on <%= DateTime.now.strftime('%F %R') %>.
|
46
46
|
<br/>
|
47
|
-
The database at <%=
|
47
|
+
The database at <%= locker.path %> was <%= "last modified #{locker.last_modified.strftime('%F %R')}" rescue 'never modified' %>.
|
48
48
|
</td>
|
49
49
|
</tr>
|
50
50
|
</tfoot>
|
51
51
|
<tbody>
|
52
|
-
<%
|
52
|
+
<% locker.all.each{|key, value|%>
|
53
53
|
<tr>
|
54
54
|
<td><%= key %></td>
|
55
55
|
<td><%= value %></td>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# Tests `pwl add`
|
4
|
+
class TestAdd < Test::Pwl::AppTestCase
|
5
|
+
def test_add_blank_key
|
6
|
+
assert_error('may not be blank', 'add')
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_add_simple
|
10
|
+
assert_successful('', 'add foo bar')
|
11
|
+
assert_successful('^bar$', 'get foo')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_add_update
|
15
|
+
assert_successful('', 'add foo bar')
|
16
|
+
assert_successful('', 'add foo baz') # just do it twice
|
17
|
+
assert_successful('^baz$', 'get foo')
|
18
|
+
end
|
19
|
+
end
|
@@ -4,23 +4,23 @@ require 'nokogiri/diff'
|
|
4
4
|
# Tests `pwl export`
|
5
5
|
class TestExport < Test::Pwl::AppTestCase
|
6
6
|
def test_empty
|
7
|
-
fixture = fixture("test_empty.html").gsub('CREATED_STAMP', DateTime.now.strftime('%F %R')).gsub('MODIFIED_STAMP', 'never').gsub('DATABASE_FILE',
|
7
|
+
fixture = fixture("test_empty.html").gsub('CREATED_STAMP', DateTime.now.strftime('%F %R')).gsub('MODIFIED_STAMP', 'never').gsub('DATABASE_FILE', locker_file)
|
8
8
|
assert_successful_html(fixture, 'export')
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_all
|
12
12
|
test_vector = Hash['foo', 'one', 'bar', 'two', 'Chuck Norris', 'Roundhouse Kick']
|
13
13
|
test_vector.each{|k,v|
|
14
|
-
assert_successful('', "
|
14
|
+
assert_successful('', "add '#{k}' '#{v}'")
|
15
15
|
}
|
16
16
|
|
17
17
|
now = DateTime.now.strftime('%F %R')
|
18
|
-
fixture = fixture("test_all.html").gsub('CREATED_STAMP', now).gsub('MODIFIED_STAMP', now).gsub('DATABASE_FILE',
|
18
|
+
fixture = fixture("test_all.html").gsub('CREATED_STAMP', now).gsub('MODIFIED_STAMP', now).gsub('DATABASE_FILE', locker_file)
|
19
19
|
|
20
20
|
assert_successful_html(fixture, 'export')
|
21
21
|
end
|
22
22
|
|
23
|
-
def assert_successful_html(expected_out, cmd, password =
|
23
|
+
def assert_successful_html(expected_out, cmd, password = locker_password)
|
24
24
|
out, err, rc = execute(cmd, password)
|
25
25
|
assert_equal(0, rc.exitstatus, "Expected exit status 0, but it was #{rc.exitstatus}. STDERR was: #{err}")
|
26
26
|
assert(err.empty?, "Expected empty STDERR, but it yielded #{err}")
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# Tests `pwl export --format json`
|
5
|
+
class TestExportJSON < Test::Pwl::AppTestCase
|
6
|
+
def test_empty
|
7
|
+
fixture = fixture("test_empty.json")
|
8
|
+
assert_successful_json(fixture, 'export --format json')
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_all
|
12
|
+
test_vector = Hash['foo', 'one', 'bar', 'two', 'Chuck Norris', 'Roundhouse Kick']
|
13
|
+
test_vector.each{|k,v|
|
14
|
+
assert_successful('', "add '#{k}' '#{v}'")
|
15
|
+
}
|
16
|
+
|
17
|
+
now = DateTime.now.strftime('%F %R')
|
18
|
+
fixture = fixture("test_all.json")
|
19
|
+
|
20
|
+
assert_successful_json(fixture, 'export --format json')
|
21
|
+
end
|
22
|
+
|
23
|
+
def assert_successful_json(expected_out, cmd, password = locker_password)
|
24
|
+
out, err, rc = execute(cmd, password)
|
25
|
+
assert_equal(0, rc.exitstatus, "Expected exit status 0, but it was #{rc.exitstatus}. STDERR was: #{err}")
|
26
|
+
assert(err.empty?, "Expected empty STDERR, but it yielded #{err}")
|
27
|
+
|
28
|
+
actual = JSON.parse(out)
|
29
|
+
expected = JSON.parse(expected_out)
|
30
|
+
|
31
|
+
# fix up actuals to match expectations
|
32
|
+
actual["created"] = "2012-03-28T21:54:21+02:00"
|
33
|
+
actual["last_accessed"] = "2012-03-28T22:01:49+02:00"
|
34
|
+
actual["last_modified"] = "2012-03-29T22:46:29+02:00"
|
35
|
+
|
36
|
+
# This is essentially the same as
|
37
|
+
# assert_equal(expected, actual)
|
38
|
+
# but it provides better diagnostic output on error
|
39
|
+
json_diff(expected, actual)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def json_diff(expected, actual, context = nil)
|
44
|
+
assert_equal(expected.class, actual.class)
|
45
|
+
|
46
|
+
case expected
|
47
|
+
when Hash
|
48
|
+
actual.keys.each do |key|
|
49
|
+
json_diff(expected[key], actual[key], "#{context}/#{String == expected[key].class ? '@' : ''}#{key}")
|
50
|
+
end
|
51
|
+
when Array
|
52
|
+
actual.each_with_index do |e, i|
|
53
|
+
json_diff(expected[i], actual[i], "#{context}[#{i}]")
|
54
|
+
end
|
55
|
+
else
|
56
|
+
assert_equal(expected, actual, "#{context} is not the same:")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
# Tests `pwl export --format yaml`
|
5
|
+
class TestExportYAML < Test::Pwl::AppTestCase
|
6
|
+
def test_empty
|
7
|
+
fixture = fixture("test_empty.yaml")
|
8
|
+
assert_successful_yaml(fixture, 'export --format yaml')
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_all
|
12
|
+
test_vector = Hash['foo', 'one', 'bar', 'two', 'Chuck Norris', 'Roundhouse Kick']
|
13
|
+
test_vector.each{|k,v|
|
14
|
+
assert_successful('', "add '#{k}' '#{v}'")
|
15
|
+
}
|
16
|
+
|
17
|
+
now = DateTime.now.strftime('%F %R')
|
18
|
+
fixture = fixture("test_all.yaml")
|
19
|
+
|
20
|
+
assert_successful_yaml(fixture, 'export --format yaml')
|
21
|
+
end
|
22
|
+
|
23
|
+
def assert_successful_yaml(expected_out, cmd, password = locker_password)
|
24
|
+
out, err, rc = execute(cmd, password)
|
25
|
+
assert_equal(0, rc.exitstatus, "Expected exit status 0, but it was #{rc.exitstatus}. STDERR was: #{err}")
|
26
|
+
assert(err.empty?, "Expected empty STDERR, but it yielded #{err}")
|
27
|
+
|
28
|
+
actual = YAML.load(out)
|
29
|
+
expected = YAML.load(expected_out)
|
30
|
+
|
31
|
+
# fix up actuals to match expectations
|
32
|
+
actual[:created] = "2012-03-28T21:54:21+02:00"
|
33
|
+
actual[:last_accessed] = "2012-03-28T22:01:49+02:00"
|
34
|
+
actual[:last_modified] = "2012-03-29T22:46:29+02:00"
|
35
|
+
|
36
|
+
# This is essentially the same as
|
37
|
+
# assert_equal(expected, actual)
|
38
|
+
# but it provides better diagnostic output on error
|
39
|
+
yaml_diff(expected, actual)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def yaml_diff(expected, actual, context = nil)
|
44
|
+
#assert_equal(expected.class, actual.class)
|
45
|
+
|
46
|
+
case expected
|
47
|
+
when Hash
|
48
|
+
actual.keys.each do |key|
|
49
|
+
yaml_diff(expected[key], actual[key], "#{context}/#{String == expected[key].class ? '@' : ''}#{key}")
|
50
|
+
end
|
51
|
+
when Array
|
52
|
+
actual.each_with_index do |e, i|
|
53
|
+
yaml_diff(expected[i], actual[i], "#{context}[#{i}]")
|
54
|
+
end
|
55
|
+
else
|
56
|
+
assert_equal(expected, actual, "#{context} is not the same:")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/test/acceptance/test_get.rb
CHANGED
@@ -11,7 +11,7 @@ class TestGet < Test::Pwl::AppTestCase
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_get_known_key
|
14
|
-
assert_successful('', '
|
14
|
+
assert_successful('', 'add foo bar') # TODO Use a fixture instead of add
|
15
15
|
assert_successful('^bar$', 'get foo')
|
16
16
|
end
|
17
17
|
end
|
@@ -13,11 +13,11 @@ class TestInit < Test::Pwl::AppTestCase
|
|
13
13
|
# **************
|
14
14
|
# Enter master password again:
|
15
15
|
# **************
|
16
|
-
# Successfully initialized new
|
16
|
+
# Successfully initialized new locker at ...
|
17
17
|
# $
|
18
18
|
#
|
19
19
|
def test_matching_passwords
|
20
|
-
cmd = "bin/pwl init --force --verbose --file \"#{@
|
20
|
+
cmd = "bin/pwl init --force --verbose --file \"#{@locker_file}\""
|
21
21
|
|
22
22
|
PTY.spawn(cmd){|pwl_out, pwl_in, pid|
|
23
23
|
assert_response('Enter new master password:', pwl_out)
|
@@ -26,7 +26,7 @@ class TestInit < Test::Pwl::AppTestCase
|
|
26
26
|
assert_response('Enter master password again:', pwl_out)
|
27
27
|
pwl_in.puts("secr3tPassw0rd")
|
28
28
|
|
29
|
-
assert_response('Successfully initialized new
|
29
|
+
assert_response('Successfully initialized new locker', pwl_out)
|
30
30
|
}
|
31
31
|
end
|
32
32
|
|
@@ -44,7 +44,7 @@ class TestInit < Test::Pwl::AppTestCase
|
|
44
44
|
# $
|
45
45
|
#
|
46
46
|
def test_unmatching_passwords
|
47
|
-
cmd = "bin/pwl init --force --verbose --file \"#{
|
47
|
+
cmd = "bin/pwl init --force --verbose --file \"#{locker_file}\""
|
48
48
|
|
49
49
|
PTY.spawn(cmd){|pwl_out, pwl_in, pid|
|
50
50
|
assert_response('Enter new master password:', pwl_out)
|
@@ -58,14 +58,14 @@ class TestInit < Test::Pwl::AppTestCase
|
|
58
58
|
end
|
59
59
|
|
60
60
|
#
|
61
|
-
# Tests that initing an existing
|
61
|
+
# Tests that initing an existing locker without --force does not touch the existing locker
|
62
62
|
#
|
63
63
|
def test_exists
|
64
64
|
assert_error('already exists', "init")
|
65
65
|
end
|
66
66
|
|
67
67
|
#
|
68
|
-
# Tests that cancelling a forced re-init does not change the
|
68
|
+
# Tests that cancelling a forced re-init does not change the locker file
|
69
69
|
#
|
70
70
|
def test_cancel
|
71
71
|
# TODO
|
@@ -3,7 +3,7 @@ require 'helper'
|
|
3
3
|
# Tests `pwl list`
|
4
4
|
class TestList < Test::Pwl::AppTestCase
|
5
5
|
def test_list_empty
|
6
|
-
assert_empty(
|
6
|
+
assert_empty(locker.list)
|
7
7
|
assert_error('^$', 'list')
|
8
8
|
assert_error('^List is empty\.$', 'list --verbose')
|
9
9
|
end
|
@@ -11,7 +11,7 @@ class TestList < Test::Pwl::AppTestCase
|
|
11
11
|
def test_list_all
|
12
12
|
test_vector = Hash['foo', 'one', 'bar', 'two', 'Chuck Norris', 'Roundhouse Kick']
|
13
13
|
test_vector.each{|k,v|
|
14
|
-
assert_successful('', "
|
14
|
+
assert_successful('', "add '#{k}' '#{v}'")
|
15
15
|
}
|
16
16
|
|
17
17
|
assert_successful(test_vector.keys.join('-'), 'list -s "-"')
|
@@ -20,7 +20,7 @@ class TestList < Test::Pwl::AppTestCase
|
|
20
20
|
def test_list_filter
|
21
21
|
test_vector = Hash['foo', 'one', 'foot', 'two', 'Homer Simpson', 'Apu Nahasapeemapetilon']
|
22
22
|
test_vector.each{|k,v|
|
23
|
-
assert_successful('', "
|
23
|
+
assert_successful('', "add '#{k}' '#{v}'")
|
24
24
|
}
|
25
25
|
|
26
26
|
filter = 'foo'
|