cassandra-cql 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +203 -0
  4. data/README.rdoc +78 -0
  5. data/Rakefile +150 -0
  6. data/cassandra-cql.gemspec +29 -0
  7. data/lib/cassandra-cql.rb +39 -0
  8. data/lib/cassandra-cql/database.rb +107 -0
  9. data/lib/cassandra-cql/result.rb +133 -0
  10. data/lib/cassandra-cql/row.rb +59 -0
  11. data/lib/cassandra-cql/schema.rb +108 -0
  12. data/lib/cassandra-cql/statement.rb +111 -0
  13. data/lib/cassandra-cql/types/abstract_type.rb +47 -0
  14. data/lib/cassandra-cql/types/ascii_type.rb +25 -0
  15. data/lib/cassandra-cql/types/boolean_type.rb +25 -0
  16. data/lib/cassandra-cql/types/bytes_type.rb +21 -0
  17. data/lib/cassandra-cql/types/decimal_type.rb +25 -0
  18. data/lib/cassandra-cql/types/double_type.rb +25 -0
  19. data/lib/cassandra-cql/types/float_type.rb +25 -0
  20. data/lib/cassandra-cql/types/integer_type.rb +27 -0
  21. data/lib/cassandra-cql/types/long_type.rb +27 -0
  22. data/lib/cassandra-cql/types/utf8_type.rb +25 -0
  23. data/lib/cassandra-cql/types/uuid_type.rb +27 -0
  24. data/lib/cassandra-cql/utility.rb +37 -0
  25. data/lib/cassandra-cql/uuid.rb +21 -0
  26. data/lib/cassandra-cql/version.rb +19 -0
  27. data/spec/column_family_spec.rb +105 -0
  28. data/spec/comparator_spec.rb +225 -0
  29. data/spec/conf/0.8/cassandra.in.sh +41 -0
  30. data/spec/conf/0.8/cassandra.yaml +61 -0
  31. data/spec/conf/0.8/log4j-server.properties +40 -0
  32. data/spec/conf/0.8/schema.txt +10 -0
  33. data/spec/conf/1.0/cassandra.in.sh +41 -0
  34. data/spec/conf/1.0/cassandra.yaml +416 -0
  35. data/spec/conf/1.0/log4j-server.properties +40 -0
  36. data/spec/conf/1.0/schema.txt +10 -0
  37. data/spec/result_spec.rb +173 -0
  38. data/spec/row_spec.rb +55 -0
  39. data/spec/rowkey_spec.rb +223 -0
  40. data/spec/schema_spec.rb +51 -0
  41. data/spec/spec_helper.rb +23 -0
  42. data/spec/statement_spec.rb +224 -0
  43. data/spec/utility_spec.rb +26 -0
  44. data/spec/uuid_spec.rb +26 -0
  45. data/spec/validation_spec.rb +250 -0
  46. data/vendor/gen-rb/cassandra.rb +2212 -0
  47. data/vendor/gen-rb/cassandra_constants.rb +10 -0
  48. data/vendor/gen-rb/cassandra_types.rb +854 -0
  49. metadata +171 -0
@@ -0,0 +1,51 @@
1
+ require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
2
+ include CassandraCQL
3
+
4
+ describe "Schema class" do
5
+ before(:each) do
6
+ @connection = setup_cassandra_connection
7
+ @connection.execute("USE system")
8
+ end
9
+
10
+ context "initialize" do
11
+ it "should set a thrift schema object" do
12
+ @connection.schema.schema.should be_kind_of(CassandraCQL::Thrift::KsDef)
13
+ end
14
+
15
+ it "should set column family hash" do
16
+ @connection.schema.column_families.should be_kind_of(Hash)
17
+ end
18
+
19
+ it "should set column family hash" do
20
+ @connection.schema.column_families.should be_kind_of(Hash)
21
+ end
22
+ end
23
+
24
+ it "should method_missing" do
25
+ expect {
26
+ @connection.schema.this_method_does_not_exist
27
+ }.to raise_error NoMethodError
28
+ end
29
+
30
+ context "name" do
31
+ it "should return keyspace name" do
32
+ @connection.schema.name.should eq('system')
33
+ end
34
+ end
35
+
36
+ context "to_s" do
37
+ it "should return keyspace name" do
38
+ @connection.schema.to_s.should eq(@connection.schema.name)
39
+ end
40
+ end
41
+
42
+ context "column_family_names" do
43
+ it "should return cf_def names" do
44
+ @connection.schema.column_family_names.sort.should eq(@connection.schema.schema.cf_defs.map(&:name).sort)
45
+ end
46
+
47
+ it "should be the same as tables" do
48
+ @connection.schema.column_family_names.should eq(@connection.schema.tables)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,23 @@
1
+ require 'yaml'
2
+ require 'rspec'
3
+ $LOAD_PATH << "#{File.expand_path(File.dirname(__FILE__))}/../lib"
4
+ require 'cassandra-cql'
5
+
6
+ def yaml_fixture(file)
7
+ if file.kind_of?(Symbol)
8
+ file = "#{file}.yaml"
9
+ elsif file !~ /\.yaml$/
10
+ file = "#{file}.yaml"
11
+ end
12
+ YAML::load_file(File.dirname(__FILE__) + "/fixtures/#{file}")
13
+ end
14
+
15
+ def setup_cassandra_connection
16
+ connection = CassandraCQL::Database.new(["127.0.0.1:9160"], {}, :retries => 2, :timeout => 1) rescue false
17
+ if !connection.keyspaces.map(&:name).include?("CassandraCQLTestKeyspace")
18
+ connection.execute("CREATE KEYSPACE CassandraCQLTestKeyspace WITH strategy_class='org.apache.cassandra.locator.SimpleStrategy' AND strategy_options:replication_factor=1")
19
+ end
20
+ connection.execute("USE CassandraCQLTestKeyspace")
21
+
22
+ connection
23
+ end
@@ -0,0 +1,224 @@
1
+ require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
2
+ include CassandraCQL
3
+
4
+ describe "initialize" do
5
+ it "should set a handle and prepare statement" do
6
+ statement = "use keyspace1"
7
+ handle = double("Database")
8
+ sth = Statement.new(handle, statement)
9
+ sth.statement.should eq(statement)
10
+ sth.instance_variable_get("@handle").should eq(handle)
11
+ end
12
+ end
13
+
14
+ describe "execute" do
15
+ context "when performing keyspace operations" do
16
+ before(:each) do
17
+ @connection = setup_cassandra_connection
18
+ end
19
+
20
+ it "should set keyspace without compression" do
21
+ @connection.keyspace.should_not eq('system')
22
+ stmt = @connection.prepare("use system")
23
+ stmt.execute([], :compression => false).should be_nil
24
+ @connection.keyspace.should eq('system')
25
+ end
26
+
27
+ it "should set keyspace with compression" do
28
+ @connection.keyspace.should_not eq('system')
29
+ stmt = @connection.prepare("use system")
30
+ stmt.execute([], :compression => true).should be_nil
31
+ @connection.keyspace.should eq('system')
32
+ end
33
+
34
+ it "should set keyspace to nil when deleting keyspace" do
35
+ @connection.execute("DROP KEYSPACE #{@connection.keyspace}").should be_nil
36
+ @connection.keyspace.should be_nil
37
+ end
38
+ end
39
+
40
+ context "when performing void-returning column_family operations" do
41
+ before(:each) do
42
+ @connection = setup_cassandra_connection
43
+ if !@connection.schema.column_family_names.include?('colfam_ops')
44
+ @connection.execute("CREATE COLUMNFAMILY colfam_ops (id varchar PRIMARY KEY)")
45
+ else
46
+ @connection.execute("TRUNCATE colfam_ops")
47
+ end
48
+ end
49
+
50
+ it "should return nil when inserting" do
51
+ @connection.execute("INSERT INTO colfam_ops (id, column) VALUES (?, ?)", "key", "value").should be_nil
52
+ end
53
+
54
+ it "should return nil when updating" do
55
+ @connection.execute("UPDATE colfam_ops SET column=? WHERE id=?", "value", "key").should be_nil
56
+ end
57
+
58
+ it "should return nil when deleting" do
59
+ @connection.execute("DELETE FROM colfam_ops WHERE id=?", "key").should be_nil
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "escape" do
65
+ it "should escape quotes" do
66
+ Statement.escape(%q{'}).should eq(%q{''})
67
+ Statement.escape(%q{\'}).should eq(%q{\''})
68
+ Statement.escape(%q{''}).should eq(%q{''''})
69
+ end
70
+ end
71
+
72
+ describe "quote" do
73
+ context "with a string" do
74
+ it "should add quotes" do
75
+ Statement.quote("test").should eq("'test'")
76
+ end
77
+ end
78
+
79
+ context "with an integer" do
80
+ it "should not add quotes" do
81
+ Statement.quote(15).should eq(15)
82
+ end
83
+ end
84
+
85
+ context "with an array" do
86
+ it "should return a comma-separated list" do
87
+ Statement.quote([1, 2, 3]).should eq("1,2,3")
88
+ Statement.quote(["a", "b''", "c"]).should eq("'a','b''','c'")
89
+ end
90
+ end
91
+
92
+ context "with an unsupported object" do
93
+ it "should raise an exception" do
94
+ expect {
95
+ Statement.quote(Time.new)
96
+ }.to raise_error(CassandraCQL::Error::UnescapableObject)
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "cast_to_cql" do
102
+ context "with a Time object" do
103
+ it "should return a guid of a UUID" do
104
+ ts = Time.new - 86400 # set it to yesterday just to be sure no defaulting to today misses an error
105
+ guid = Statement.cast_to_cql(ts)
106
+ guid.should be_kind_of(String)
107
+ expect {
108
+ ret = UUID.new(guid)
109
+ uuid_ts = Time.at(ret.seconds)
110
+ [:year, :month, :day, :hour, :min, :sec].each do |sym|
111
+ uuid_ts.send(sym).should eq(ts.send(sym))
112
+ end
113
+ }.to_not raise_error
114
+ end
115
+ end
116
+
117
+ context "with a Fixnum object" do
118
+ it "should return the same object" do
119
+ Statement.cast_to_cql(15).should eq(15)
120
+ end
121
+ end
122
+
123
+ context "with a UUID object" do
124
+ it "should return the a guid" do
125
+ uuid = UUID.new
126
+ guid = Statement.cast_to_cql(uuid)
127
+ guid.should eq(uuid.to_guid)
128
+ end
129
+ end
130
+
131
+ context "with a String without quotes" do
132
+ it "should return a copy of itself" do
133
+ str = "This is a string"
134
+ new_str = Statement.cast_to_cql(str)
135
+ str.should eq(str)
136
+ new_str.object_id.should_not eq(str.object_id)
137
+ end
138
+ end
139
+
140
+ context "with a String with quotes" do
141
+ it "should return a quoted version" do
142
+ str = "This is a ' string"
143
+ new_str = Statement.cast_to_cql(str)
144
+ new_str.should_not eq(str)
145
+ new_str.should eq(Statement.escape(str))
146
+ end
147
+ end
148
+
149
+ context "with binary data" do
150
+ it "should return an unpacked version" do
151
+ bytes = "binary\x00"
152
+ bytes = bytes.force_encoding('ASCII-8BIT') if RUBY_VERSION >= "1.9"
153
+ new_data = Statement.cast_to_cql(bytes)
154
+ new_data.should_not eq(bytes)
155
+ [new_data].pack('H*').should eq(bytes)
156
+ end
157
+ end
158
+
159
+ context "with an array of Fixnums" do
160
+ it "should equal itself" do
161
+ arr = [1, 2, 3]
162
+ Statement.cast_to_cql(arr).should eq(arr)
163
+ end
164
+ end
165
+
166
+ context "with an array of Strings" do
167
+ it "should return quoted versions of itself" do
168
+ arr = ["test", "'"]
169
+ res = Statement.cast_to_cql(arr)
170
+ arr.map { |o| Statement.cast_to_cql(o) }.should eq(res)
171
+ end
172
+ end
173
+ end
174
+
175
+ describe "sanitize" do
176
+ context "with no bind vars" do
177
+ it "should return itself" do
178
+ Statement.sanitize("use keyspace").should eq("use keyspace")
179
+ end
180
+ end
181
+
182
+ context "when expecting bind vars" do
183
+ it "should raise an exception with bind variable mismatch" do
184
+ expect {
185
+ Statement.sanitize("use keyspace ?")
186
+ }.to raise_error(Error::InvalidBindVariable)
187
+
188
+ expect {
189
+ Statement.sanitize("use keyspace ?", ['too', 'many'])
190
+ }.to raise_error(Error::InvalidBindVariable)
191
+ end
192
+
193
+ it "should not raise an exception with matching bind vars" do
194
+ expect {
195
+ Statement.sanitize("use keyspace ?", ["test"]).should eq("use keyspace 'test'")
196
+ }.to_not raise_error(Error::InvalidBindVariable)
197
+ end
198
+
199
+ it "should have bind vars in the right order" do
200
+ expect {
201
+ Statement.sanitize("use keyspace ? with randomness (?)", ["test", "stuff"]).should eq("use keyspace 'test' with randomness ('stuff')")
202
+ }.to_not raise_error(Error::InvalidBindVariable)
203
+ end
204
+
205
+ it "should not double-escape the single quotes in your string" do
206
+ Statement.sanitize(
207
+ "insert into keyspace (key, ?) values (?)", ["vanilla", %Q{I\'m a string with \'cool\' quotes}]
208
+ ).should eq("insert into keyspace (key, 'vanilla') values ('I''m a string with ''cool'' quotes')")
209
+ end
210
+
211
+ it "should handle numbers and stuff appropriately" do
212
+ Statement.sanitize(
213
+ "insert into keyspace (key, ?) values (?)", [488, 60.368]
214
+ ).should eq("insert into keyspace (key, 488) values (60.368)")
215
+ end
216
+
217
+ end
218
+ end
219
+
220
+ describe "finish" do
221
+ it "should just return true .. nothing to clean up yet" do
222
+ Statement.new(nil, 'whatever').finish.should be_true
223
+ end
224
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
3
+ include CassandraCQL
4
+
5
+ describe "compress" do
6
+ it "should return some valid gzipped stuff" do
7
+ stuff = "This is some stuff"
8
+ bytes = Utility.compress(stuff)
9
+ Utility.binary_data?(bytes).should be_true
10
+ Utility.decompress(bytes).should eq(stuff)
11
+ end
12
+
13
+ it "should be binary data" do
14
+ if RUBY_VERSION >= "1.9"
15
+ Utility.binary_data?("binary\x00".force_encoding('ASCII-8BIT')).should be_true
16
+ else
17
+ Utility.binary_data?("binary\x00").should be_true
18
+ end
19
+ end
20
+
21
+ it "should not be binary data" do
22
+ Utility.binary_data?("test").should_not be_true
23
+ Utility.binary_data?("snårk").should_not be_true
24
+ end
25
+ end
26
+
@@ -0,0 +1,26 @@
1
+ require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
2
+ include CassandraCQL
3
+
4
+ describe "UUID" do
5
+ it "should respond_to to_guid" do
6
+ UUID.new.respond_to?(:to_guid)
7
+ end
8
+
9
+ it "should respond_to to_time" do
10
+ UUID.new.respond_to?(:to_time)
11
+ end
12
+
13
+ it "should instantiate from raw bytes" do
14
+ UUID.new("\252}\303\374\3137\021\340\237\214\251}\315\351 ]")
15
+ end
16
+
17
+ it "should instantiate from a Time object" do
18
+ ts = Time.new
19
+ UUID.new(ts).to_time.should eq(ts)
20
+ end
21
+
22
+ it "should turn have a to_time class method that takes bytes" do
23
+ UUID.to_time("\252}\303\374\3137\021\340\237\214\251}\315\351 ]").should be_kind_of(Time)
24
+ end
25
+ end
26
+
@@ -0,0 +1,250 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
3
+ include CassandraCQL
4
+
5
+ describe "Validation Roundtrip tests" do
6
+ before(:each) do
7
+ @connection = setup_cassandra_connection
8
+ end
9
+
10
+ def create_and_fetch_column(column_family, value)
11
+ @connection.execute("insert into #{column_family} (id, test_column) values (?, ?)", 'test', value)
12
+ return @connection.execute("select test_column from #{column_family} where id = ?", 'test').fetch[0]
13
+ end
14
+
15
+ def create_column_family(name, test_column_type, opts="")
16
+ if !@connection.schema.column_family_names.include?(name)
17
+ @connection.execute("CREATE COLUMNFAMILY #{name} (id text PRIMARY KEY, test_column #{test_column_type}) #{opts}")
18
+ end
19
+ end
20
+
21
+ context "with ascii validation" do
22
+ let(:cf_name) { "validation_cf_ascii" }
23
+ before(:each) { create_column_family(cf_name, 'ascii') }
24
+
25
+ it "should return an ascii string" do
26
+ create_and_fetch_column(cf_name, "test string").should eq("test string")
27
+ end
28
+ end
29
+
30
+ context "with bigint validation" do
31
+ let(:cf_name) { "validation_cf_bigint" }
32
+ before(:each) { create_column_family(cf_name, 'bigint') }
33
+
34
+ def test_for_value(value)
35
+ create_and_fetch_column(cf_name, value).should eq(value)
36
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
37
+ end
38
+
39
+ it "should properly convert integer values that fit into 1 byte" do
40
+ test_for_value(1)
41
+ end
42
+ it "should properly convert integer values that fit into 2 bytes" do
43
+ test_for_value(2**8 + 80)
44
+ end
45
+ it "should properly convert integer values that fit into 3 bytes" do
46
+ test_for_value(2**16 + 622)
47
+ end
48
+ it "should properly convert integer values that fit into 4 bytes" do
49
+ test_for_value(2**24 + 45820)
50
+ end
51
+ it "should properly convert integer values that fit into 5 bytes" do
52
+ test_for_value(2**32 + 618387)
53
+ end
54
+ end
55
+
56
+ context "with blob validation" do
57
+ let(:cf_name) { "validation_cf_blob" }
58
+ before(:each) { create_column_family(cf_name, 'blob') }
59
+
60
+ it "should return a blob" do
61
+ bytes = "binary\x00"
62
+ bytes = bytes.force_encoding('ASCII-8BIT') if RUBY_VERSION >= "1.9"
63
+ create_and_fetch_column(cf_name, bytes).should eq(bytes)
64
+ end
65
+ end
66
+
67
+ context "with boolean validation" do
68
+ let(:cf_name) { "validation_cf_boolean" }
69
+ before(:each) { create_column_family(cf_name, 'boolean') }
70
+
71
+ it "should return true" do
72
+ create_and_fetch_column(cf_name, true).should be_true
73
+ end
74
+
75
+ it "should return false" do
76
+ create_and_fetch_column(cf_name, false).should be_false
77
+ end
78
+ end
79
+
80
+ context "with counter validation" do
81
+ let(:cf_name) { "validation_cf_counter" }
82
+ before(:each) {
83
+ if !@connection.schema.column_family_names.include?(cf_name)
84
+ @connection.execute("CREATE COLUMNFAMILY #{cf_name} (id text PRIMARY KEY) WITH default_validation=CounterColumnType")
85
+ end
86
+ @connection.execute("TRUNCATE #{cf_name}")
87
+ }
88
+
89
+ it "should increment a few times" do
90
+ 10.times do |i|
91
+ @connection.execute("UPDATE #{cf_name} SET test=test + 1 WHERE id=?", 'test_key')
92
+ @connection.execute("SELECT test FROM #{cf_name} WHERE id=?", 'test_key').fetch[0].should eq(i+1)
93
+ end
94
+ end
95
+
96
+ it "should decrement a few times" do
97
+ 10.times do |i|
98
+ @connection.execute("UPDATE #{cf_name} SET test=test - 1 WHERE id=?", 'test_key')
99
+ @connection.execute("SELECT test FROM #{cf_name} WHERE id=?", 'test_key').fetch[0].should eq((i+1)*-1)
100
+ end
101
+ end
102
+ end
103
+
104
+ context "with decimal validation" do
105
+ let(:cf_name) { "validation_cf_decimal" }
106
+ before(:each) { create_column_family(cf_name, 'decimal') }
107
+
108
+ def test_for_value(value)
109
+ create_and_fetch_column(cf_name, value).should eq(value)
110
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
111
+ end
112
+
113
+ it "should return a small decimal" do
114
+ test_for_value(15.333)
115
+ end
116
+ it "should return a huge decimal" do
117
+ test_for_value(BigDecimal.new('129182739481237481341234123411.1029348102934810293481039'))
118
+ end
119
+ end
120
+
121
+ context "with double validation" do
122
+ let(:cf_name) { "validation_cf_double" }
123
+ before(:each) { create_column_family(cf_name, 'double') }
124
+
125
+ def test_for_value(value)
126
+ create_and_fetch_column(cf_name, value).should be_within(0.1).of(value)
127
+ create_and_fetch_column(cf_name, value*-1).should be_within(0.1).of(-1*value)
128
+ end
129
+
130
+ it "should properly convert some float values" do
131
+ test_for_value(1.125)
132
+ test_for_value(384.125)
133
+ test_for_value(65540.125)
134
+ test_for_value(16777217.125)
135
+ test_for_value(1099511627776.125)
136
+ end
137
+ end
138
+
139
+ context "with float validation" do
140
+ let(:cf_name) { "validation_cf_float" }
141
+ before(:each) { create_column_family(cf_name, 'float') }
142
+
143
+ def test_for_value(value)
144
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
145
+ create_and_fetch_column(cf_name, value).should eq(value)
146
+ end
147
+
148
+ it "should properly convert some float values" do
149
+ test_for_value(1.125)
150
+ test_for_value(384.125)
151
+ test_for_value(65540.125)
152
+ end
153
+ end
154
+
155
+ context "with int validation" do
156
+ let(:cf_name) { "validation_cf_int" }
157
+ before(:each) { create_column_family(cf_name, 'int') }
158
+
159
+ def test_for_value(value)
160
+ create_and_fetch_column(cf_name, value).should eq(value)
161
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
162
+ end
163
+
164
+ it "should properly convert integer values that fit into 1 byte" do
165
+ test_for_value(1)
166
+ end
167
+ it "should properly convert integer values that fit into 2 bytes" do
168
+ test_for_value(2**8 + 80)
169
+ end
170
+ it "should properly convert integer values that fit into 3 bytes" do
171
+ test_for_value(2**16 + 622)
172
+ end
173
+ it "should properly convert integer values that fit into 4 bytes" do
174
+ test_for_value(2**24 + 45820)
175
+ end
176
+ end
177
+
178
+ context "with text validation" do
179
+ let(:cf_name) { "validation_cf_text" }
180
+ before(:each) { create_column_family(cf_name, 'varchar') }
181
+
182
+ it "should return a non-multibyte string" do
183
+ create_and_fetch_column(cf_name, "snark").should eq("snark")
184
+ end
185
+
186
+ it "should return a multibyte string" do
187
+ if RUBY_VERSION >= "1.9"
188
+ create_and_fetch_column(cf_name, "sn\xC3\xA5rk".force_encoding('UTF-8')).should eq("sn\xC3\xA5rk".force_encoding('UTF-8'))
189
+ else
190
+ create_and_fetch_column(cf_name, "snårk").should eq("snårk")
191
+ end
192
+ end
193
+ end
194
+
195
+ context "with timestamp validation" do
196
+ let(:cf_name) { "validation_cf_timestamp" }
197
+ before(:each) { create_column_family(cf_name, 'timestamp') }
198
+
199
+ it "should return a timestamp" do
200
+ uuid = UUID.new
201
+ #create_and_fetch_column(cf_name, uuid).should eq(uuid)
202
+ end
203
+ end
204
+
205
+ context "with uuid validation" do
206
+ let(:cf_name) { "validation_cf_uuid" }
207
+ before(:each) { create_column_family(cf_name, 'uuid') }
208
+
209
+ it "should return a uuid" do
210
+ uuid = UUID.new
211
+ create_and_fetch_column(cf_name, uuid).should eq(uuid)
212
+ end
213
+ end
214
+
215
+ context "with varchar validation" do
216
+ let(:cf_name) { "validation_cf_varchar" }
217
+ before(:each) { create_column_family(cf_name, 'varchar') }
218
+
219
+ it "should return a non-multibyte string" do
220
+ create_and_fetch_column(cf_name, "snark").should eq("snark")
221
+ end
222
+
223
+ it "should return a multibyte string" do
224
+ create_and_fetch_column(cf_name, "snårk").should eq("snårk")
225
+ end
226
+ end
227
+
228
+ context "with varint validation" do
229
+ let(:cf_name) { "validation_cf_varint" }
230
+ before(:each) { create_column_family(cf_name, 'varint') }
231
+
232
+ def test_for_value(value)
233
+ create_and_fetch_column(cf_name, value).should eq(value)
234
+ create_and_fetch_column(cf_name, value*-1).should eq(value*-1)
235
+ end
236
+
237
+ it "should properly convert integer values that fit into 1 byte" do
238
+ test_for_value(1)
239
+ end
240
+ it "should properly convert integer values that fit into 2 bytes" do
241
+ test_for_value(2**8 + 80)
242
+ end
243
+ it "should properly convert integer values that fit into 3 bytes" do
244
+ test_for_value(2**16 + 622)
245
+ end
246
+ it "should properly convert integer values that fit into more than 8 bytes" do
247
+ test_for_value(2**256)
248
+ end
249
+ end
250
+ end