oklahoma_mixer 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +10 -0
- data/TODO.rdoc +3 -3
- data/lib/oklahoma_mixer.rb +14 -5
- data/lib/oklahoma_mixer/b_tree_database.rb +185 -0
- data/lib/oklahoma_mixer/b_tree_database/c.rb +45 -0
- data/lib/oklahoma_mixer/cursor.rb +43 -0
- data/lib/oklahoma_mixer/cursor/c.rb +45 -0
- data/lib/oklahoma_mixer/fixed_length_database.rb +95 -0
- data/lib/oklahoma_mixer/fixed_length_database/c.rb +62 -0
- data/lib/oklahoma_mixer/hash_database.rb +84 -54
- data/lib/oklahoma_mixer/hash_database/c.rb +3 -96
- data/lib/oklahoma_mixer/utilities.rb +110 -5
- data/test/b_tree_binary_data_test.rb +45 -0
- data/test/b_tree_tuning_test.rb +132 -0
- data/test/binary_data_test.rb +3 -13
- data/test/cursor_based_iteration_test.rb +151 -0
- data/test/duplicate_storage_test.rb +107 -0
- data/test/fixed_length_tuning_test.rb +77 -0
- data/test/getting_and_setting_by_id_test.rb +288 -0
- data/test/getting_and_setting_keys_test.rb +37 -3
- data/test/iteration_test.rb +2 -76
- data/test/key_range_test.rb +161 -0
- data/test/order_test.rb +122 -0
- data/test/shared_binary_data.rb +14 -0
- data/test/shared_iteration.rb +99 -0
- data/test/shared_tuning.rb +91 -0
- data/test/test_helper.rb +10 -11
- data/test/top_level_interface_test.rb +12 -0
- data/test/tuning_test.rb +11 -87
- metadata +27 -2
@@ -0,0 +1,161 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestKeyRange < Test::Unit::TestCase
|
4
|
+
def teardown
|
5
|
+
remove_db_files
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_b_tree_supports_non_range_key_requests
|
9
|
+
abc_db do |db|
|
10
|
+
assert_equal(%w[a b], db.keys(:limit => 2))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_keys_can_return_a_range_of_keys_for_a_b_tree_database
|
15
|
+
abc_db do |db|
|
16
|
+
assert_equal(%w[b c], db.keys(:range => "b".."c"))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_range_overrides_prefix_and_triggers_a_warning
|
21
|
+
abc_db do |db|
|
22
|
+
warning = capture_stderr do
|
23
|
+
# returns range
|
24
|
+
assert_equal(%w[b c], db.keys(:range => "b".."c", :prefix => "ignored"))
|
25
|
+
end
|
26
|
+
assert(!warning.empty?, "A warning was not issued for a range and prefix")
|
27
|
+
end
|
28
|
+
|
29
|
+
num_db do |db|
|
30
|
+
warning = capture_stderr do
|
31
|
+
# returns range
|
32
|
+
assert_equal([2, 3], db.keys(:range => 2..3, :prefix => "ignored"))
|
33
|
+
end
|
34
|
+
assert(!warning.empty?, "A warning was not issued for a range and prefix")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_b_tree_key_ranges_must_be_passed_a_range_object
|
39
|
+
abc_db do |db|
|
40
|
+
assert_nothing_raised(ArgumentError) do
|
41
|
+
db.keys(:range => "b".."c")
|
42
|
+
end
|
43
|
+
assert_raise(ArgumentError) do
|
44
|
+
db.keys(:range => "not a Range")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_boundaries_are_converted_to_strings_for_a_b_tree_database
|
50
|
+
abc_db do |db|
|
51
|
+
assert_equal(%w[b c], db.keys(:range => %w[b]..%w[c]))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_key_ranges_can_exclude_the_last_member_in_a_b_tree_database
|
56
|
+
abc_db do |db|
|
57
|
+
assert_equal(%w[b], db.keys(:range => "b"..."c"))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_key_ranges_can_exclude_the_first_member_in_a_b_tree_database
|
62
|
+
abc_db do |db|
|
63
|
+
assert_equal(%w[c], db.keys(:range => "b".."c", :exclude_start => true))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_key_ranges_can_use_values_between_keys_in_a_b_tree_database
|
68
|
+
abc_db do |db|
|
69
|
+
assert_equal(%w[b c], db.keys(:range => "ab".."f"))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_a_limit_can_be_set_for_key_ranges_in_a_b_tree_database
|
74
|
+
abc_db do |db|
|
75
|
+
assert_equal(%w[b], db.keys(:range => "b".."c", :limit => 1))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_range_queries_work_with_custom_ordering
|
80
|
+
bdb(:cmpfunc => lambda { |a, b| a.to_i <=> b.to_i }) do |db|
|
81
|
+
db.update(1 => :a, 11 => :b, 2 => :c)
|
82
|
+
assert_equal(%w[2 11], db.keys(:range => 2..100))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_fixed_length_supports_non_range_key_requests
|
87
|
+
num_db do |db|
|
88
|
+
assert_equal([1, 2], db.keys(:limit => 2))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_keys_can_return_a_range_of_keys_for_a_fixed_length_database
|
93
|
+
num_db do |db|
|
94
|
+
assert_equal([2, 3], db.keys(:range => 2..3))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_fixed_length_key_ranges_must_be_passed_a_range_or_array
|
99
|
+
num_db do |db|
|
100
|
+
assert_nothing_raised(ArgumentError) do
|
101
|
+
db.keys(:range => "min".."max")
|
102
|
+
end
|
103
|
+
assert_nothing_raised(ArgumentError) do
|
104
|
+
db.keys(:range => [:min, 100])
|
105
|
+
end
|
106
|
+
assert_raise(ArgumentError) do
|
107
|
+
db.keys(:range => "not a Range")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_boundaries_are_converted_to_integers_for_a_fixed_length_database
|
113
|
+
num_db do |db|
|
114
|
+
assert_equal([2, 3], db.keys(:range => "2".."3"))
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_key_ranges_can_exclude_the_last_member_in_a_fixed_length_database
|
119
|
+
num_db do |db|
|
120
|
+
assert_equal([2], db.keys(:range => 2...3))
|
121
|
+
assert_equal([2], db.keys(:range => [2, 3], :exclude_end => true))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_key_ranges_can_exclude_the_first_member_in_a_fixed_length_database
|
126
|
+
num_db do |db|
|
127
|
+
assert_equal([3], db.keys(:range => 2..3, :exclude_start => true))
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_key_ranges_can_use_values_between_keys_in_a_fixed_length_database
|
132
|
+
num_db do |db|
|
133
|
+
db.update(5 => 500, 6 => 600)
|
134
|
+
assert_equal([5, 6], db.keys(:range => 4..7))
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_a_limit_can_be_set_for_key_ranges_in_a_fixed_length_database
|
139
|
+
num_db do |db|
|
140
|
+
assert_equal([2], db.keys(:range => 2..3, :limit => 1))
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
#######
|
145
|
+
private
|
146
|
+
#######
|
147
|
+
|
148
|
+
def abc_db
|
149
|
+
bdb do |db|
|
150
|
+
db.update(:a => 1, :b => 2, :c => 3)
|
151
|
+
yield db
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def num_db
|
156
|
+
fdb do |db|
|
157
|
+
db.update(1 => 100, 2 => 200, 3 => 300)
|
158
|
+
yield db
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
data/test/order_test.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestOrder < Test::Unit::TestCase
|
4
|
+
REVERSE_ORDER_CMPFUNC = lambda { |a, b| a == "" ? a <=> b : b <=> a }
|
5
|
+
|
6
|
+
def teardown
|
7
|
+
remove_db_files
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_b_tree_databases_default_to_lexical_ordering
|
11
|
+
bdb do |db|
|
12
|
+
db.update(:c => 3, :a => 1, :b => 2)
|
13
|
+
assert_equal(%w[a b c], db.keys)
|
14
|
+
assert_equal([%w[a 1], %w[b 2], %w[c 3]], db.to_a)
|
15
|
+
end
|
16
|
+
|
17
|
+
remove_db_files
|
18
|
+
bdb do |db|
|
19
|
+
db.update(1 => :a, 11 => :b, 2 => :c)
|
20
|
+
assert_equal(%w[1 11 2], db.keys)
|
21
|
+
assert_equal([%w[1 a], %w[11 b], %w[2 c]], db.to_a)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_b_tree_database_ordering_can_be_changed_with_a_comparison_function
|
26
|
+
bdb(:cmpfunc => REVERSE_ORDER_CMPFUNC) do |db|
|
27
|
+
db.update(:c => 3, :a => 1, :b => 2)
|
28
|
+
assert_equal(%w[c b a], db.keys)
|
29
|
+
assert_equal([%w[c 3], %w[b 2], %w[a 1]], db.to_a)
|
30
|
+
end
|
31
|
+
|
32
|
+
remove_db_files
|
33
|
+
cmpfunc = lambda { |a, b| a.to_i <=> b.to_i } # numerical order
|
34
|
+
bdb(:cmpfunc => cmpfunc) do |db|
|
35
|
+
db.update(1 => :a, 11 => :b, 2 => :c)
|
36
|
+
assert_equal(%w[1 2 11], db.keys)
|
37
|
+
assert_equal([%w[1 a], %w[2 c], %w[11 b]], db.to_a)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_each_key_iterates_through_keys_in_order_for_b_trees
|
42
|
+
assert_forward_iteration(%w[a b c], :each_key)
|
43
|
+
assert_reverse_iteration(%w[c b a], :each_key)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_each_iterates_through_key_value_pairs_in_order_for_b_trees
|
47
|
+
assert_forward_iteration([%w[a 1], %w[b 2], %w[c 3]], :each)
|
48
|
+
assert_reverse_iteration([%w[c 3], %w[b 2], %w[a 1]], :each)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_reverse_each_iterates_through_key_value_pairs_in_revserse_order
|
52
|
+
assert_forward_iteration([%w[c 3], %w[b 2], %w[a 1]], :reverse_each)
|
53
|
+
assert_reverse_iteration([%w[a 1], %w[b 2], %w[c 3]], :reverse_each)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_each_value_iterates_through_values_in_order_for_b_trees
|
57
|
+
assert_forward_iteration(%w[1 2 3], :each_value)
|
58
|
+
assert_reverse_iteration(%w[3 2 1], :each_value)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_delete_if_iterates_through_key_value_pairs_in_order_for_b_trees
|
62
|
+
assert_forward_iteration([%w[a 1], %w[b 2], %w[c 3]], :delete_if)
|
63
|
+
assert_reverse_iteration([%w[c 3], %w[b 2], %w[a 1]], :delete_if)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_fixed_length_databases_have_numerical_ordering_by_keys
|
67
|
+
fdb do |db|
|
68
|
+
db.update(3 => 300, 1 => 100, 2 => 200)
|
69
|
+
assert_equal([1, 2, 3], db.keys)
|
70
|
+
assert_equal([[1, "100"], [2, "200"], [3, "300"]], db.to_a)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_each_key_iterates_through_keys_in_order_for_fixed_lengths
|
75
|
+
assert_forward_iteration([1, 2, 3], :each_key, :fdb)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_each_iterates_through_key_value_pairs_in_order_for_fixed_lengths
|
79
|
+
assert_forward_iteration([[1, "100"], [2, "200"], [3, "300"]], :each, :fdb)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_each_value_iterates_through_values_in_order_for_fixed_lengths
|
83
|
+
assert_forward_iteration(%w[100 200 300], :each_value, :fdb)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_delete_if_iterates_through_key_value_pairs_in_order_for_fixed_lengths
|
87
|
+
assert_forward_iteration( [[1, "100"], [2, "200"], [3, "300"]],
|
88
|
+
:delete_if,
|
89
|
+
:fdb )
|
90
|
+
end
|
91
|
+
|
92
|
+
#######
|
93
|
+
private
|
94
|
+
#######
|
95
|
+
|
96
|
+
def assert_forward_iteration(expected_order, iterator, option = nil)
|
97
|
+
remove_db_files
|
98
|
+
if option == :fdb
|
99
|
+
fdb do |db|
|
100
|
+
db.update(3 => 300, 1 => 100, 2 => 200)
|
101
|
+
actual_order = [ ]
|
102
|
+
db.send(iterator) do |*args|
|
103
|
+
actual_order << (args.size == 1 ? args.first : args)
|
104
|
+
end
|
105
|
+
assert_equal(expected_order, actual_order)
|
106
|
+
end
|
107
|
+
else
|
108
|
+
bdb(:cmpfunc => option) do |db|
|
109
|
+
db.update(:c => 3, :a => 1, :b => 2)
|
110
|
+
actual_order = [ ]
|
111
|
+
db.send(iterator) do |*args|
|
112
|
+
actual_order << (args.size == 1 ? args.first : args)
|
113
|
+
end
|
114
|
+
assert_equal(expected_order, actual_order)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def assert_reverse_iteration(expected_order, iterator)
|
120
|
+
assert_forward_iteration(expected_order, iterator, REVERSE_ORDER_CMPFUNC)
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SharedBinaryData
|
2
|
+
def test_null_bytes_are_preserved_during_key_iteration
|
3
|
+
@db.each_key do |key|
|
4
|
+
assert_equal(@key, key)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_null_bytes_are_preserved_during_iteration
|
9
|
+
@db.each do |key, value|
|
10
|
+
assert_equal(@key, key)
|
11
|
+
assert_equal(@value, value)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module SharedIteration
|
2
|
+
def test_each_key_iterates_over_all_keys_in_the_database
|
3
|
+
@db.each_key do |key|
|
4
|
+
@keys.delete(key)
|
5
|
+
end
|
6
|
+
assert(@keys.empty?, "All keys were not iterated over")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_each_iterates_over_all_key_value_pairs_in_arrays
|
10
|
+
@db.each do |key_value_array|
|
11
|
+
assert_instance_of(Array, key_value_array)
|
12
|
+
assert_equal(2, key_value_array.size)
|
13
|
+
key, value = key_value_array
|
14
|
+
assert_equal(key * 2, value)
|
15
|
+
@keys.delete(key)
|
16
|
+
@values.delete(value)
|
17
|
+
end
|
18
|
+
assert( @keys.empty? && @values.empty?,
|
19
|
+
"All key/value pairs were not iterated over" )
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_the_arrays_passed_to_each_can_be_split
|
23
|
+
@db.each do |key, value|
|
24
|
+
@keys.delete(key)
|
25
|
+
@values.delete(value)
|
26
|
+
end
|
27
|
+
assert( @keys.empty? && @values.empty?,
|
28
|
+
"All key/value pairs were not iterated over" )
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_each_pair_is_an_alias_for_each
|
32
|
+
each_arrays = [ ]
|
33
|
+
@db.each do |array|
|
34
|
+
each_arrays << array
|
35
|
+
end
|
36
|
+
@db.each_pair do |array|
|
37
|
+
each_arrays.delete(array)
|
38
|
+
end
|
39
|
+
each_keys_and_values = [ ]
|
40
|
+
@db.each do |key, value|
|
41
|
+
each_keys_and_values << [key, value]
|
42
|
+
end
|
43
|
+
@db.each_pair do |key, value|
|
44
|
+
each_keys_and_values.delete([key, value])
|
45
|
+
end
|
46
|
+
assert( each_arrays.empty? && each_keys_and_values.empty?,
|
47
|
+
"The iterations did not match" )
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_each_value_iterates_over_all_values_in_the_database
|
51
|
+
@db.each_value do |value|
|
52
|
+
@values.delete(value)
|
53
|
+
end
|
54
|
+
assert(@values.empty?, "All values were not iterated over")
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_the_standard_iterators_are_supported
|
58
|
+
assert_kind_of(Enumerable, @db)
|
59
|
+
|
60
|
+
# examples
|
61
|
+
assert_equal(%w[b bb], @db.find { |_, value| value == "bb" })
|
62
|
+
assert_nil(@db.find { |_, value| value == "dd" })
|
63
|
+
assert_equal(%w[aaa bbb ccc], @db.map { |key, value| key + value }.sort)
|
64
|
+
assert( @db.any? { |_, value| value.include? "c" },
|
65
|
+
"A value was not found during iteration" )
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_delete_if_removes_all_keys_for_which_the_block_returns_true
|
69
|
+
@db.delete_if { |key, _| key != "a" }
|
70
|
+
assert_equal([%w[a aa]], @db.to_a)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_iterators_return_self_to_match_hash_interface
|
74
|
+
%w[each_key each each_pair each_value delete_if].each do |iterator|
|
75
|
+
assert_equal(@db, @db.send(iterator) { })
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_to_hash_converts_the_database_to_a_hash
|
80
|
+
assert_equal(Hash[*@keys.zip(@values).flatten], @db.to_hash)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_to_hash_keeps_a_default_object_by_default
|
84
|
+
@db.default = 0
|
85
|
+
assert_equal(0, @db.to_hash[:missing])
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_to_hash_keeps_a_default_proc_by_default
|
89
|
+
@db.default = lambda { |key| "is #{key}" }
|
90
|
+
assert_equal("is missing", @db.to_hash[:missing])
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_to_hash_can_be_told_to_ignore_a_default
|
94
|
+
@db.default = 0
|
95
|
+
assert_nil(@db.to_hash(false)[:missing])
|
96
|
+
@db.default = lambda { |key| "is #{key}" }
|
97
|
+
assert_nil(@db.to_hash(false)[:missing])
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module SharedTuning
|
2
|
+
def test_a_mutex_can_be_activated_as_the_database_is_created
|
3
|
+
assert_option_calls([:setmutex], :mutex => true)
|
4
|
+
end
|
5
|
+
|
6
|
+
def test_a_size_can_be_set_for_extra_mapped_memory
|
7
|
+
size = rand(1_000) + 1
|
8
|
+
assert_option_calls([:setxmsiz, size], :xmsiz => size)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_extra_mapped_memory_size_is_converted_to_an_int
|
12
|
+
assert_option_calls([:setxmsiz, 42], :xmsiz => "42")
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_a_step_unit_can_be_set_for_auto_defragmentation
|
16
|
+
unit = rand(1_000) + 1
|
17
|
+
assert_option_calls([:setdfunit, unit], :dfunit => unit)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_auto_defragmentation_step_unit_is_converted_to_an_int
|
21
|
+
assert_option_calls([:setdfunit, 42], :dfunit => "42")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_nested_transactions_can_be_ignored
|
25
|
+
db(:nested_transactions => :ignore) do |db|
|
26
|
+
result = db.transaction {
|
27
|
+
db.transaction { # ignored
|
28
|
+
41
|
29
|
+
} + 1 # ignored
|
30
|
+
}
|
31
|
+
assert_equal(42, result)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_nested_transactions_can_be_set_to_fail_with_an_error
|
36
|
+
[:fail, :raise].each do |setting|
|
37
|
+
db(:nested_transactions => setting) do |db|
|
38
|
+
db.transaction do
|
39
|
+
assert_raise(OKMixer::Error::TransactionError) do
|
40
|
+
db.transaction { } # nested fails with error
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_a_mode_string_can_be_passed
|
48
|
+
assert_raise(OKMixer::Error::CabinetError) do # file not found
|
49
|
+
db("r")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_the_mode_can_be_passed_as_as_option
|
54
|
+
assert_raise(OKMixer::Error::CabinetError) do # file not found
|
55
|
+
db(:mode => "r")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_an_option_mode_overrides_the_mode_argument_and_triggers_a_warning
|
60
|
+
warning = capture_stderr do
|
61
|
+
db("r", :mode => "wc") do
|
62
|
+
# just open and close
|
63
|
+
end
|
64
|
+
end
|
65
|
+
assert( !warning.empty?,
|
66
|
+
"A warning was not issued for an option mode with a mode argument" )
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_an_unknown_mode_triggers_a_warning
|
70
|
+
warning = capture_stderr do
|
71
|
+
db("wcu") do
|
72
|
+
# just open and close
|
73
|
+
end
|
74
|
+
end
|
75
|
+
assert(!warning.empty?, "A warning was not issued for an unknown mode")
|
76
|
+
end
|
77
|
+
|
78
|
+
#######
|
79
|
+
private
|
80
|
+
#######
|
81
|
+
|
82
|
+
def assert_option_calls(c_call, options)
|
83
|
+
args = capture_args(lib, c_call[0]) do
|
84
|
+
db(options) do
|
85
|
+
# just open and close
|
86
|
+
end
|
87
|
+
end
|
88
|
+
assert_instance_of(FFI::Pointer, args[0])
|
89
|
+
assert_equal(c_call[1..-1], args[1..-1])
|
90
|
+
end
|
91
|
+
end
|