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.
@@ -0,0 +1,45 @@
1
+ require "test_helper"
2
+ require "shared_binary_data"
3
+
4
+ class TestBTreeBinaryData < Test::Unit::TestCase
5
+ def setup
6
+ @db = bdb
7
+ @key = "Binary\0Name"
8
+ @value = "James\0Edward\0Gray\0II"
9
+ @db[@key] = @value
10
+ @closed = false
11
+ end
12
+
13
+ def teardown
14
+ @db.close unless @closed
15
+ remove_db_files
16
+ end
17
+
18
+ include SharedBinaryData
19
+
20
+ def test_null_bytes_are_preserved_during_value_iteration
21
+ @db.each_value do |value|
22
+ assert_equal(@value, value)
23
+ end
24
+ end
25
+
26
+ def test_null_bytes_are_preserved_by_key_ranges
27
+ assert_equal([@key], @db.keys(:range => "A".."Z"))
28
+ end
29
+
30
+ def test_null_bytes_are_preserved_in_comparison_functions
31
+ @db.close
32
+ @closed = true
33
+ remove_db_files
34
+
35
+ callback = lambda { |a, b|
36
+ assert_equal(@key, a) unless a.empty?
37
+ assert_equal(@key, b) unless b.empty?
38
+ a <=> b
39
+ }
40
+ bdb(:cmpfunc => callback) do |db|
41
+ db[@key] = @value
42
+ assert_equal([@key], db.keys) # forces a comparison with ""
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,132 @@
1
+ require "test_helper"
2
+ require "shared_tuning"
3
+
4
+ class TestBTreeTuning < Test::Unit::TestCase
5
+ def teardown
6
+ remove_db_files
7
+ end
8
+
9
+ include SharedTuning
10
+
11
+ def test_leaf_members_can_be_set_with_other_tuning_defaults
12
+ members = rand(1_000) + 1
13
+ assert_option_calls([:tune, members, 0, 0, -1, -1, 0xFF], :lmemb => members)
14
+ end
15
+
16
+ def test_leaf_members_is_converted_to_an_int
17
+ assert_option_calls([:tune, 42, 0, 0, -1, -1, 0xFF], :lmemb => "42")
18
+ end
19
+
20
+ def test_non_leaf_members_can_be_set_with_other_tuning_defaults
21
+ members = rand(1_000) + 1
22
+ assert_option_calls([:tune, 0, members, 0, -1, -1, 0xFF], :nmemb => members)
23
+ end
24
+
25
+ def test_non_leaf_members_is_converted_to_an_int
26
+ assert_option_calls([:tune, 0, 42, 0, -1, -1, 0xFF], :nmemb => "42")
27
+ end
28
+
29
+ def test_a_bucket_array_size_can_be_set_with_other_tuning_defaults
30
+ size = rand(1_000) + 1
31
+ assert_option_calls([:tune, 0, 0, size, -1, -1, 0xFF], :bnum => size)
32
+ end
33
+
34
+ def test_bucket_array_size_is_converted_to_an_int
35
+ assert_option_calls([:tune, 0, 0, 42, -1, -1, 0xFF], :bnum => "42")
36
+ end
37
+
38
+ def test_a_record_alignment_power_can_be_set_with_other_tuning_defaults
39
+ pow = rand(10) + 1
40
+ assert_option_calls([:tune, 0, 0, 0, pow, -1, 0xFF], :apow => pow)
41
+ end
42
+
43
+ def test_record_alignment_power_is_converted_to_an_int
44
+ assert_option_calls([:tune, 0, 0, 0, 42, -1, 0xFF], :apow => "42")
45
+ end
46
+
47
+ def test_a_max_free_block_power_can_be_set_with_other_tuning_defaults
48
+ pow = rand(10) + 1
49
+ assert_option_calls([:tune, 0, 0, 0, -1, pow, 0xFF], :fpow => pow)
50
+ end
51
+
52
+ def test_max_free_block_power_is_converted_to_an_int
53
+ assert_option_calls([:tune, 0, 0, 0, -1, 42, 0xFF], :fpow => "42")
54
+ end
55
+
56
+ def test_options_can_be_set_with_other_tuning_defaults
57
+ assert_option_calls([:tune, 0, 0, 0, -1, -1, 1 | 2], :opts => "ld")
58
+ end
59
+
60
+ def test_options_is_a_string_of_characters_mapped_to_enums_and_ored_together
61
+ opts = {"l" => lib::OPTS[:BDBTLARGE], "b" => lib::OPTS[:BDBTBZIP]}
62
+ assert_option_calls( [ :tune, 0, 0, 0, -1, -1,
63
+ opts.values.inject(0) { |o, v| o | v } ],
64
+ :opts => opts.keys.join )
65
+ end
66
+
67
+ def test_the_options_string_is_not_case_sensative
68
+ assert_option_calls([:tune, 0, 0, 0, -1, -1, 1 | 2], :opts => "ld")
69
+ assert_option_calls([:tune, 0, 0, 0, -1, -1, 1 | 2], :opts => "LD")
70
+ end
71
+
72
+ def test_unknown_options_are_ignored_with_a_warning
73
+ warning = capture_stderr do
74
+ assert_option_calls([:tune, 0, 0, 0, -1, -1, 1 | 8], :opts => "ltu")
75
+ end
76
+ assert(!warning.empty?, "A warning was not issued for an unknown option")
77
+ end
78
+
79
+ def test_multiple_tuning_parameters_can_be_set_at_the_same_time
80
+ members = rand(1_000) + 1
81
+ size = rand(1_000) + 1
82
+ assert_option_calls( [:tune, members, 0, size, -1, -1, 1 | 2],
83
+ :lmemb => members, :bnum => size, :opts => "ld" )
84
+ end
85
+
86
+ def test_optimize_allows_the_adjustment_of_tune_options_for_an_open_database
87
+ db do |db|
88
+ args = capture_args(lib, :optimize) do
89
+ db.optimize(:apow => "42", :opts => "ld")
90
+ end
91
+ assert_instance_of(FFI::Pointer, args[0])
92
+ assert_equal([0, 0, 0, 42, -1, 1 | 2], args[1..-1])
93
+ end
94
+ end
95
+
96
+ def test_leaf_nodes_cached_can_be_set_with_other_cache_defaults
97
+ nodes = rand(1_000) + 1
98
+ assert_option_calls([:setcache, nodes, 0], :lcnum => nodes)
99
+ end
100
+
101
+ def test_leaf_nodes_cached_is_converted_to_an_int
102
+ assert_option_calls([:setcache, 42, 0], :lcnum => "42")
103
+ end
104
+
105
+ def test_non_leaf_nodes_cached_can_be_set_with_other_cache_defaults
106
+ nodes = rand(1_000) + 1
107
+ assert_option_calls([:setcache, 0, nodes], :ncnum => nodes)
108
+ end
109
+
110
+ def test_non_leaf_nodes_cached_is_converted_to_an_int
111
+ assert_option_calls([:setcache, 0, 42], :ncnum => "42")
112
+ end
113
+
114
+ def test_multiple_cache_parameters_can_be_set_at_the_same_time
115
+ l_nodes = rand(1_000) + 1
116
+ n_nodes = rand(1_000) + 1
117
+ assert_option_calls( [:setcache, l_nodes, n_nodes],
118
+ :lcnum => l_nodes, :ncnum => n_nodes )
119
+ end
120
+
121
+ #######
122
+ private
123
+ #######
124
+
125
+ def lib
126
+ OKMixer::BTreeDatabase::C
127
+ end
128
+
129
+ def db(*args, &block)
130
+ bdb(*args, &block)
131
+ end
132
+ end
@@ -1,4 +1,5 @@
1
1
  require "test_helper"
2
+ require "shared_binary_data"
2
3
 
3
4
  class TestBinaryData < Test::Unit::TestCase
4
5
  def setup
@@ -13,6 +14,8 @@ class TestBinaryData < Test::Unit::TestCase
13
14
  remove_db_files
14
15
  end
15
16
 
17
+ include SharedBinaryData
18
+
16
19
  def test_keys_and_values_can_be_read_with_null_bytes
17
20
  assert_equal(@value, @db[@key])
18
21
  end
@@ -22,19 +25,6 @@ class TestBinaryData < Test::Unit::TestCase
22
25
  assert_equal("new\0value", @db[@key])
23
26
  end
24
27
 
25
- def test_null_bytes_are_preserved_during_key_iteration
26
- @db.each_key do |key|
27
- assert_equal(@key, key)
28
- end
29
- end
30
-
31
- def test_null_bytes_are_preserved_during_iteration
32
- @db.each do |key, value|
33
- assert_equal(@key, key)
34
- assert_equal(@value, value)
35
- end
36
- end
37
-
38
28
  def test_null_bytes_are_preserved_by_key_listing
39
29
  assert_equal([@key], @db.keys)
40
30
  end
@@ -0,0 +1,151 @@
1
+ require "test_helper"
2
+ require "shared_iteration"
3
+
4
+ class TestCursorBasedIteration < Test::Unit::TestCase
5
+ def setup
6
+ @db = bdb
7
+ @keys = %w[a b c]
8
+ @values = @keys.map { |key| key * 2 }
9
+ @keys.zip(@values) do |key, value|
10
+ @db[key] = value
11
+ end
12
+ end
13
+
14
+ def teardown
15
+ @db.close
16
+ remove_db_files
17
+ end
18
+
19
+ include SharedIteration
20
+
21
+ def test_each_key_can_begin_iteration_at_a_passed_key
22
+ @db.each_key("b") do |key|
23
+ @keys.delete(key)
24
+ end
25
+ assert_equal(%w[a], @keys)
26
+ end
27
+
28
+ def test_each_key_can_begin_iteration_between_keys
29
+ @db.each_key("ab") do |key| # after "a", but before "b"
30
+ @keys.delete(key)
31
+ end
32
+ assert_equal(%w[a], @keys)
33
+ end
34
+
35
+ def test_iteration_can_be_broken_with_each_key
36
+ @db.each_key("b") do |key|
37
+ @keys.delete(key)
38
+ break
39
+ end
40
+ assert_equal(%w[a c], @keys)
41
+ end
42
+
43
+ def test_each_can_begin_iteration_at_a_passed_key
44
+ @db.each("b") do |key, value|
45
+ @keys.delete(key)
46
+ @values.delete(value)
47
+ end
48
+ assert_equal(%w[a], @keys)
49
+ assert_equal(%w[aa], @values)
50
+ end
51
+
52
+ def test_each_can_begin_iteration_between_keys
53
+ @db.each("ab") do |key, value| # after "a", but before "b"
54
+ @keys.delete(key)
55
+ @values.delete(value)
56
+ end
57
+ assert_equal(%w[a], @keys)
58
+ assert_equal(%w[aa], @values)
59
+ end
60
+
61
+ def test_iteration_can_be_broken_with_each
62
+ @db.each("b") do |key, value|
63
+ @keys.delete(key)
64
+ @values.delete(value)
65
+ break
66
+ end
67
+ assert_equal(%w[a c], @keys)
68
+ assert_equal(%w[aa cc], @values)
69
+ end
70
+
71
+ def test_reverse_each_can_begin_iteration_at_a_passed_key
72
+ @db.reverse_each("b") do |key, value|
73
+ @keys.delete(key)
74
+ @values.delete(value)
75
+ end
76
+ assert_equal(%w[c], @keys)
77
+ assert_equal(%w[cc], @values)
78
+ end
79
+
80
+ def test_reverse_each_can_begin_iteration_between_keys
81
+ @db.reverse_each("ab") do |key, value| # after "a", but before "b"
82
+ @keys.delete(key)
83
+ @values.delete(value)
84
+ end
85
+ assert_equal(%w[c], @keys)
86
+ assert_equal(%w[cc], @values)
87
+ end
88
+
89
+ def test_iteration_can_be_broken_with_reverse_each
90
+ @db.reverse_each("b") do |key, value|
91
+ @keys.delete(key)
92
+ @values.delete(value)
93
+ break
94
+ end
95
+ assert_equal(%w[a c], @keys)
96
+ assert_equal(%w[aa cc], @values)
97
+ end
98
+
99
+ def test_each_value_can_begin_iteration_at_a_passed_key
100
+ @db.each_value("b") do |value|
101
+ @values.delete(value)
102
+ end
103
+ assert_equal(%w[aa], @values)
104
+ end
105
+
106
+ def test_each_value_can_begin_iteration_between_keys
107
+ @db.each_value("ab") do |value| # after "a", but before "b"
108
+ @values.delete(value)
109
+ end
110
+ assert_equal(%w[aa], @values)
111
+ end
112
+
113
+ def test_iteration_can_be_broken_with_each_value
114
+ @db.each_value("b") do |value|
115
+ @values.delete(value)
116
+ break
117
+ end
118
+ assert_equal(%w[aa cc], @values)
119
+ end
120
+
121
+ def test_delete_if_can_begin_iteration_at_a_passed_key
122
+ @db.delete_if("b") do |key, value|
123
+ @keys.delete(key)
124
+ @values.delete(value)
125
+ true
126
+ end
127
+ assert_equal(%w[a], @keys)
128
+ assert_equal(%w[aa], @values)
129
+ end
130
+
131
+ def test_delete_if_can_begin_iteration_between_keys
132
+ @db.delete_if("ab") do |key, value| # after "a", but before "b"
133
+ @keys.delete(key)
134
+ @values.delete(value)
135
+ true
136
+ end
137
+ assert_equal(%w[a], @keys)
138
+ assert_equal(%w[aa], @values)
139
+ end
140
+
141
+ def test_iteration_can_be_broken_with_each_delete_if
142
+ @db.delete_if("b") do |key, value|
143
+ break if key == "c"
144
+ @keys.delete(key)
145
+ @values.delete(value)
146
+ true
147
+ end
148
+ assert_equal(%w[a c], @keys)
149
+ assert_equal(%w[aa cc], @values)
150
+ end
151
+ end
@@ -0,0 +1,107 @@
1
+ require "test_helper"
2
+
3
+ class TestDuplicateStorage < Test::Unit::TestCase
4
+ def setup
5
+ @db = bdb
6
+ end
7
+
8
+ def teardown
9
+ @db.close
10
+ remove_db_files
11
+ end
12
+
13
+ def test_duplicates_can_be_stored
14
+ assert(@db.store("Gray", "Dana", :dup), "Failed to store initial value")
15
+ assert(@db.store("Gray", "James", :dup), "Failed to store duplicate value")
16
+ assert_equal("Dana", @db["Gray"]) # always returns the first
17
+ end
18
+
19
+ def test_keys_are_a_unique_listing_not_showing_duplicates
20
+ @db.update("Gray" => "Dana", "Matsumoto" => "Yukihiro")
21
+ @db.store("Gray", "James", :dup)
22
+ assert_equal(%w[Gray Matsumoto], @db.keys)
23
+ assert_equal(%w[Gray], @db.keys(:range => "G"..."H"))
24
+ end
25
+
26
+ def test_values_can_be_scoped_to_a_key_to_retrieve_all_duplicates
27
+ @db[:other] = "one record"
28
+ assert_equal(["one record"], @db.values)
29
+ assert_equal([ ], @db.values("Gray"))
30
+ assert(@db.store("Gray", "Dana", :dup), "Failed to store initial value")
31
+ assert_equal(%w[Dana], @db.values("Gray"))
32
+ assert(@db.store("Gray", "James", :dup), "Failed to store duplicate value")
33
+ assert_equal(%w[Dana James], @db.values("Gray"))
34
+ end
35
+
36
+ def test_delete_removes_the_first_value_by_default
37
+ @db.update("Gray" => "Dana", "Matsumoto" => "Yukihiro")
38
+ @db.store("Gray", "James", :dup)
39
+ assert_equal(%w[Dana James], @db.values("Gray"))
40
+ assert_equal("Dana", @db.delete("Gray"))
41
+ assert_equal(%w[James], @db.values("Gray"))
42
+ assert_equal("James", @db.delete("Gray"))
43
+ assert_nil(@db.delete("Gray"))
44
+ end
45
+
46
+ def test_delete_with_dup_mode_deletes_all_values
47
+ @db.update("Gray" => "Dana", "Matsumoto" => "Yukihiro")
48
+ @db.store("Gray", "James", :dup)
49
+ assert_equal(%w[Dana James], @db.values("Gray"))
50
+ assert_equal(%w[Dana James], @db.delete("Gray", :dup))
51
+ assert_equal([ ], @db.delete("Gray", :dup))
52
+ end
53
+
54
+ def test_delete_with_dup_mode_supports_the_missing_handler
55
+ assert_nil(@db.delete(:missing, :dup) { nil })
56
+ end
57
+
58
+ def test_size_can_be_scoped_to_a_key_to_retrieve_all_duplicates
59
+ @db[:other] = "one record"
60
+ assert_equal(1, @db.size)
61
+ assert_equal(0, @db.size("Gray"))
62
+ assert(@db.store("Gray", "Dana", :dup), "Failed to store initial value")
63
+ assert_equal(1, @db.size("Gray"))
64
+ assert(@db.store("Gray", "James", :dup), "Failed to store duplicate value")
65
+ assert_equal(2, @db.size("Gray"))
66
+ end
67
+
68
+ def test_duplicates_show_up_in_cursor_based_iteration_of_keys
69
+ @db.update("Gray" => "Dana", "Matsumoto" => "Yukihiro")
70
+ @db.store("Gray", "James", :dup)
71
+ keys = [ ]
72
+ @db.each_key do |key|
73
+ keys << key
74
+ end
75
+ assert_equal(%w[Gray Gray Matsumoto], keys)
76
+ end
77
+
78
+ def test_duplicates_show_up_in_cursor_based_iteration
79
+ @db.update("Gray" => "Dana", "Matsumoto" => "Yukihiro")
80
+ @db.store("Gray", "James", :dup)
81
+ pairs = [ ]
82
+ @db.each do |pair|
83
+ pairs << pair
84
+ end
85
+ assert_equal([%w[Gray Dana], %w[Gray James], %w[Matsumoto Yukihiro]], pairs)
86
+ end
87
+
88
+ def test_duplicates_show_up_in_reverse_cursor_based_iteration
89
+ @db.update("Gray" => "Dana", "Matsumoto" => "Yukihiro")
90
+ @db.store("Gray", "James", :dup)
91
+ pairs = [ ]
92
+ @db.reverse_each do |pair|
93
+ pairs << pair
94
+ end
95
+ assert_equal([%w[Matsumoto Yukihiro], %w[Gray James], %w[Gray Dana]], pairs)
96
+ end
97
+
98
+ def test_duplicates_show_up_in_cursor_based_iteration_of_values
99
+ @db.update("Gray" => "Dana", "Matsumoto" => "Yukihiro")
100
+ @db.store("Gray", "James", :dup)
101
+ values = [ ]
102
+ @db.each_value do |value|
103
+ values << value
104
+ end
105
+ assert_equal(%w[Dana James Yukihiro], values)
106
+ end
107
+ end