oklahoma_mixer 0.1.0 → 0.2.0

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.
@@ -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
@@ -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