quandl_cassandra_models 0.3.6

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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +7 -0
  5. data/README.md +7 -0
  6. data/Rakefile +11 -0
  7. data/UPGRADE.md +34 -0
  8. data/config/cassandra.yml +41 -0
  9. data/lib/quandl/cassandra/models.rb +16 -0
  10. data/lib/quandl/cassandra/models/column.rb +42 -0
  11. data/lib/quandl/cassandra/models/column/read.rb +49 -0
  12. data/lib/quandl/cassandra/models/column/read/collapse.rb +41 -0
  13. data/lib/quandl/cassandra/models/column/read/column.rb +19 -0
  14. data/lib/quandl/cassandra/models/column/read/data.rb +59 -0
  15. data/lib/quandl/cassandra/models/column/read/offset.rb +104 -0
  16. data/lib/quandl/cassandra/models/column/read/row.rb +20 -0
  17. data/lib/quandl/cassandra/models/column/read/select_columns.rb +63 -0
  18. data/lib/quandl/cassandra/models/column/read/transform.rb +53 -0
  19. data/lib/quandl/cassandra/models/column/read/trim.rb +14 -0
  20. data/lib/quandl/cassandra/models/column/read/type.rb +25 -0
  21. data/lib/quandl/cassandra/models/column/write.rb +25 -0
  22. data/lib/quandl/cassandra/models/column/write/group_data_by_column.rb +36 -0
  23. data/lib/quandl/cassandra/models/column/write/group_data_by_frequency.rb +24 -0
  24. data/lib/quandl/cassandra/models/column/write/insert_column_attributes.rb +22 -0
  25. data/lib/quandl/cassandra/models/column/write/insert_columns.rb +9 -0
  26. data/lib/quandl/cassandra/models/column_attribute.rb +11 -0
  27. data/lib/quandl/cassandra/models/data.rb +18 -0
  28. data/lib/quandl/cassandra/models/data/search.rb +105 -0
  29. data/lib/quandl/cassandra/models/dataset.rb +87 -0
  30. data/lib/quandl/cassandra/models/dataset/columns.rb +63 -0
  31. data/lib/quandl/cassandra/models/dataset_attribute.rb +6 -0
  32. data/lib/quandl/cassandra/models/multiset.rb +55 -0
  33. data/lib/quandl/cassandra/models/version.rb +7 -0
  34. data/migrations/20131105204200_create_datasets.rb +18 -0
  35. data/migrations/20131105204201_create_columns.rb +18 -0
  36. data/migrations/20131105204202_create_dataset_attributes.rb +17 -0
  37. data/migrations/20131105204203_create_column_attributes.rb +17 -0
  38. data/quandl_cassandra_models.gemspec +28 -0
  39. data/spec/expectations/string.rb +5 -0
  40. data/spec/expectations/time.rb +5 -0
  41. data/spec/factories/dataset.rb +8 -0
  42. data/spec/lib/quandl/cassandra/models/column/read_spec.rb +27 -0
  43. data/spec/lib/quandl/cassandra/models/column/write/group_data_by_frequency_spec.rb +28 -0
  44. data/spec/lib/quandl/cassandra/models/column/write_spec.rb +23 -0
  45. data/spec/lib/quandl/cassandra/models/column_attribute_spec.rb +16 -0
  46. data/spec/lib/quandl/cassandra/models/column_spec.rb +17 -0
  47. data/spec/lib/quandl/cassandra/models/data_spec.rb +105 -0
  48. data/spec/lib/quandl/cassandra/models/dataset/collapse_spec.rb +44 -0
  49. data/spec/lib/quandl/cassandra/models/dataset/column_spec.rb +24 -0
  50. data/spec/lib/quandl/cassandra/models/dataset/persistence_spec.rb +25 -0
  51. data/spec/lib/quandl/cassandra/models/dataset/row_spec.rb +26 -0
  52. data/spec/lib/quandl/cassandra/models/dataset/transform_spec.rb +16 -0
  53. data/spec/lib/quandl/cassandra/models/dataset/trim_spec.rb +74 -0
  54. data/spec/lib/quandl/cassandra/models/dataset/update_spec.rb +37 -0
  55. data/spec/lib/quandl/cassandra/models/dataset_attribute_spec.rb +18 -0
  56. data/spec/lib/quandl/cassandra/models/dataset_spec.rb +117 -0
  57. data/spec/lib/quandl/cassandra/models/multiset/collapse_spec.rb +122 -0
  58. data/spec/lib/quandl/cassandra/models/multiset/columns_spec.rb +57 -0
  59. data/spec/lib/quandl/cassandra/models/multiset/data_spec.rb +25 -0
  60. data/spec/lib/quandl/cassandra/models/multiset/transform_spec.rb +69 -0
  61. data/spec/spec_helper.rb +40 -0
  62. data/tasks/migrations.rake +14 -0
  63. metadata +212 -0
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Quandl::Cassandra::Models::Column do
4
+
5
+ let(:id){ rand(10000*10000) + 10000*10000 }
6
+ let(:data){ Quandl::Fabricate::Data.rand( rows: 10, columns: 2, nils: false ) }
7
+ let(:dataset){ Quandl::Cassandra::Models::Dataset.create( id: id, data: data ) }
8
+
9
+ describe ".read" do
10
+ before(:each){ Quandl::Cassandra::Models::Column.write( id: id, data: data ); sleep(0.2) }
11
+
12
+ subject{ Quandl::Cassandra::Models::Column.read( id: id ) }
13
+ its(:count){ should eq 10 }
14
+ it{ should eq data }
15
+ end
16
+
17
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe Quandl::Cassandra::Models::Data do
4
+
5
+ let(:id){ rand(10000*10000) + 10000*10000 }
6
+ let(:data){ Quandl::Fabricate::Data.rand(rows: 10, columns: 2, nils: false) }
7
+ let(:dataset){ Quandl::Cassandra::Models::Dataset.create( id: id, data: data ) }
8
+ subject{ Quandl::Cassandra::Models::Data }
9
+
10
+ [:row, :id, :limit, :offset, :column, :accuracy, :frequency, :column_ids,
11
+ :collapse, :transform, :order, :trim_start, :trim_end ].each do |name|
12
+ it{ should respond_to name }
13
+ end
14
+
15
+ describe "#column" do
16
+ it "should handle column that is outside the range of available columns" do
17
+ dataset.data.scoped.column(4).to_table.should be_blank
18
+ end
19
+ end
20
+
21
+ describe "#collapse" do
22
+ it "should become annual" do
23
+ scope = subject.collapse(:annual)
24
+ scope.attributes[:collapse].should eq :annual
25
+ end
26
+ it "should become annual given string" do
27
+ scope = subject.collapse('annual')
28
+ scope.attributes[:collapse].should eq :annual
29
+ end
30
+ it "should become monthly" do
31
+ scope = subject.collapse(:monthly)
32
+ scope.attributes[:collapse].should eq :monthly
33
+ end
34
+ it "should become weekly" do
35
+ scope = subject.collapse('weekly')
36
+ scope.attributes[:collapse].should eq :weekly
37
+ end
38
+ end
39
+
40
+ describe "#trim_start & #trim_end" do
41
+ it "should handle trim_start > trim_end" do
42
+ dataset.data.scoped.trim_start(data[-1][0]).trim_end(data[0][0]).to_table.should be_a Quandl::Cassandra::Data
43
+ end
44
+ end
45
+
46
+ describe "#trim_start" do
47
+
48
+ subject{ dataset.data }
49
+
50
+ context "given invalid date" do
51
+
52
+ it "rejects string" do
53
+ subject.trim_start('invalid').attributes[:trim_start].should be_nil
54
+ end
55
+
56
+ end
57
+
58
+ context "given valid date" do
59
+
60
+ it "accepts string" do
61
+ subject.trim_start('1980-01-01').attributes[:trim_start].should eq Date.parse('1980-01-01').jd
62
+ end
63
+
64
+ it "accepts julian date" do
65
+ subject.trim_start( Date.today.jd ).attributes[:trim_start].should eq Date.today.jd
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+
72
+ describe "#trim_end" do
73
+
74
+ subject{ dataset.data }
75
+
76
+ context "given invalid date" do
77
+ it "rejects string" do
78
+ subject.trim_end('invalid').attributes[:trim_end].should be_nil
79
+ end
80
+ end
81
+ context "given valid date" do
82
+ it "accepts date" do
83
+ subject.trim_end(Date.today).attributes[:trim_end].should eq Date.today.jd
84
+ end
85
+ it "accepts string" do
86
+ subject.trim_end('1980-01-01').attributes[:trim_end].should eq Date.parse('1980-01-01').jd
87
+ end
88
+ it "accepts julian date" do
89
+ subject.trim_end( Date.today.jd ).attributes[:trim_end].should eq Date.today.jd
90
+ end
91
+ end
92
+ end
93
+
94
+ context "data with empty columns" do
95
+ let(:data){ Quandl::Data.new("2012-12-31,21.0,11.0,12.0,0.0,,,,0.0,,4.0,,4.0,18.0,19.0\n2012-12-24,21.0,11.0,12.0,0.0,,,,0.0,,4.0,,4.0,18.0,19.0\n2012-12-18,21.0,11.0,12.0,0.0,,,,0.0,,4.0,,4.0,18.0,19.0\n") }
96
+ let(:dataset){ Quandl::Cassandra::Models::Dataset.create( id: rand(100000), data: data ) }
97
+ subject{ Dataset.find(dataset.id) }
98
+
99
+ it "should eq data" do
100
+ subject.data.to_table.should eq data
101
+ end
102
+
103
+ end
104
+
105
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Quandl::Cassandra::Models::Dataset do
5
+
6
+ let(:dataset){ create(:dataset) }
7
+ subject { dataset }
8
+
9
+ it "should have columns" do
10
+ subject.columns.count.should eq 4
11
+ end
12
+
13
+ describe "#data" do
14
+
15
+ subject{ dataset.data }
16
+
17
+ its(:class){ should eq Quandl::Cassandra::Models::Data::ScopeScope }
18
+
19
+ its(:to_date){ should be_present }
20
+ its(:to_h){ should be_present }
21
+
22
+ it "should have data" do
23
+ subject.count.should eq 60
24
+ end
25
+
26
+ it "should collapse to daily" do
27
+ subject.collapse(:daily).count.should eq 60
28
+ end
29
+
30
+ it "should collapse to weekly" do
31
+ subject.collapse(:weekly).count.should be < 12
32
+ end
33
+
34
+ it "should collapse to monthly" do
35
+ subject.collapse(:monthly).count.should be < 4
36
+ end
37
+
38
+ it "should collapse to annual" do
39
+ subject.collapse(:annual).count.should eq 1
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Quandl::Cassandra::Models::Dataset do
5
+
6
+ context "column" do
7
+
8
+ subject { create(:dataset) }
9
+
10
+ it "should return first column" do
11
+ subject.data.column(1)[0][1].should eq subject.data.scoped.to_table[0][1]
12
+ end
13
+
14
+ it "should return second column" do
15
+ subject.data.column(2)[0][1].should eq subject.data.scoped.to_table[0][2]
16
+ end
17
+
18
+ it "should return third column" do
19
+ subject.data.column(2)[0][1].should eq subject.data.scoped.to_table[0][2]
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Quandl::Cassandra::Models::Dataset do
5
+
6
+ let(:data){ Quandl::Fabricate::Data.rand( rows: 4, columns: 4, nils: false ) }
7
+ let(:dataset){ create( :dataset, data: data ) }
8
+
9
+ subject{ dataset }
10
+
11
+ its(:dataset_attribute){ should be_a DatasetAttribute }
12
+ its(:trim_start){ should eq Date.jd(Dataset.find(dataset.id).data[-1][0]) }
13
+ its(:trim_end){ should eq Date.jd(Dataset.find(dataset.id).data[0][0]) }
14
+ its(:updated_at){ should_not be_nil }
15
+
16
+ context "after save" do
17
+ before(:each){
18
+ @previously_updated_at = subject.updated_at
19
+ subject.data = Quandl::Fabricate::Data.rand( rows: 4, columns: 4, nils: false )
20
+ subject.save
21
+ }
22
+ its(:updated_at){ should_not eq @previously_updated_at }
23
+ end
24
+
25
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Quandl::Cassandra::Models::Dataset do
5
+
6
+ let(:data){ Quandl::Fabricate::Data.rand( rows: 216, columns: 2, frequency: :weekly, nils: false ).to_csv }
7
+ let(:dataset){ create( :dataset, data: data ) }
8
+ subject { dataset }
9
+
10
+ it "should be monthly" do
11
+ subject.frequency.should eq 'weekly'
12
+ end
13
+
14
+ it "should pluck the second row" do
15
+ subject.data.scoped.collapse(:monthly).row(1).to_a.should eq [subject.data.scoped.collapse(:monthly)[1]]
16
+ end
17
+
18
+ it "should collapse and pluck the second year" do
19
+ subject.data.scoped.collapse(:annual).row(2).to_a.should eq [subject.data.scoped.collapse(:annual)[2]]
20
+ end
21
+
22
+ it "should collapse and pluck the second year with a transformation" do
23
+ subject.data.scoped.collapse(:annual).transform(:rdiff).row(2).to_a.should eq [subject.data.scoped.collapse(:annual).transform(:rdiff)[2]]
24
+ end
25
+
26
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Dataset do
5
+
6
+ let(:data){ Quandl::Data.new([ [1002, 10], [1001, 20], [1000, 30] ]) }
7
+ let(:dataset){ build(:dataset) }
8
+
9
+ it "should cumul data" do
10
+ dataset.data = data
11
+ dataset.save!
12
+ cumul_data = Dataset.find(dataset.id).data.transform(:cumul).to_table.data_array
13
+ cumul_data.should eq [ [1002, 60.0], [1001, 50.0], [1000, 30.0] ]
14
+ end
15
+
16
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Quandl::Cassandra::Models::Dataset do
5
+
6
+ describe ".trim_start,.trim_end" do
7
+ { weekly: 7, monthly: 30, quarterly: 92, annual: 365 }.each do | collapse_to, occurences |
8
+ context "when collapsed to #{collapse_to}" do
9
+
10
+ subject(:dataset){ create(:dataset, data: Quandl::Fabricate::Data.rand( rows: occurences * 3, columns: 1, nils: false ).to_csv ) }
11
+
12
+ it "should include trim_start" do
13
+ # raw data
14
+ source_data = subject.data.scoped.collapse(collapse_to).to_table
15
+ trim_start = source_data[-1][0]
16
+ # trim and check
17
+ trim_data = subject.data.trim_start( trim_start ).collapse(collapse_to).to_table
18
+ trim_data.last[0].should eq trim_start
19
+ end
20
+ it "should include trim_end" do
21
+ # raw data
22
+ source_data = subject.data.scoped.collapse(collapse_to).to_table
23
+ trim_end = source_data[1][0]
24
+ # trim and check
25
+ trim_data = subject.data.trim_end( trim_end ).collapse(collapse_to).to_table
26
+ trim_data.first[0].should eq trim_end
27
+ end
28
+ it "should include trim_start and trim_end" do
29
+ # raw data
30
+ source_data = subject.data.scoped.collapse(collapse_to).to_table
31
+ trim_end = source_data[1][0]
32
+ trim_start = source_data[-1][0]
33
+ # trim and check
34
+ trim_data = subject.data.trim_start( trim_start ).trim_end( trim_end ).collapse(collapse_to).to_table
35
+ trim_data.first[0].should eq trim_end
36
+ trim_data.last[0].should eq trim_start
37
+ end
38
+
39
+ [:diff, :rdiff, :cumul].each do |transformed_to|
40
+ context "when transformed to #{transformed_to}" do
41
+ it "should include trim_start" do
42
+ # raw data
43
+ source_data = subject.data.scoped.collapse(collapse_to).transform(transformed_to).to_table
44
+ trim_start = source_data[-1][0]
45
+ # trim and check
46
+ trim_data = subject.data.trim_start( trim_start ).transform(transformed_to).collapse(collapse_to).to_table
47
+ trim_data.last[0].should eq trim_start
48
+ end
49
+ it "should include trim_end" do
50
+ # raw data
51
+ source_data = subject.data.scoped.collapse(collapse_to).transform(transformed_to).to_table
52
+ trim_end = source_data[-1][0]
53
+ # trim and check
54
+ trim_data = subject.data.trim_end( trim_end ).transform(transformed_to).collapse(collapse_to).to_table
55
+ trim_data.first[0].should eq trim_end
56
+ end
57
+ it "should include trim_start and trim_end" do
58
+ source_data = subject.data.scoped.collapse(collapse_to).transform(transformed_to).to_table
59
+ trim_end = source_data[1][0]
60
+ trim_start = source_data[-1][0]
61
+ # trim and check
62
+ trim_data = subject.data.trim_start( trim_start ).trim_end( trim_end ).transform(transformed_to).collapse(collapse_to).to_table
63
+ trim_data.first[0].should eq trim_end
64
+ trim_data.last[0].should eq trim_start
65
+ end
66
+ end # each transform
67
+
68
+ end
69
+
70
+ end # each collapse
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Dataset do
5
+
6
+ context "update data with newer data" do
7
+
8
+ subject{ create(:dataset, data: Quandl::Fabricate::Data.rand( rows: 730, columns: 2, nils: false ).to_csv ) }
9
+
10
+ it "should update the collapse data" do
11
+ old_row = subject.data.scoped[0]
12
+ old_row_month = subject.data.scoped.collapse(:monthly)[0]
13
+ # update
14
+ dataset = Dataset.find(subject.id)
15
+ # advance data dates by 60 days
16
+ new_data = subject.data.collect{|r|
17
+ date = r[0] + 60
18
+ values = r[1..-1].collect{ rand(9102841).to_f / 1000 }
19
+ [date, values].flatten
20
+ }
21
+ # assign new data
22
+ dataset.data = new_data.to_a.collect{|r| r.to_csv }.join
23
+ dataset.save!
24
+
25
+ new_row = dataset.data.scoped[0]
26
+ new_row_month = dataset.data.scoped.collapse(:monthly)[0]
27
+
28
+ new_row[0].should_not eq new_row_month[0]
29
+ new_row[1].should eq new_row_month[1]
30
+
31
+ old_row[0].should_not eq new_row[0]
32
+ old_row_month[1].should_not eq new_row_month[1]
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe DatasetAttribute do
4
+ let(:id){ rand(10000*10000) + 10000*10000 }
5
+ let(:dataset_attribute){ DatasetAttribute.create( id: id ) }
6
+ subject{ dataset_attribute }
7
+
8
+ its(:updated_at){ should be_present }
9
+ its(:created_at){ should be_present }
10
+
11
+ describe ".find" do
12
+ subject{ DatasetAttribute.find( dataset_attribute.id ) }
13
+ it{ should be_a DatasetAttribute }
14
+ its(:updated_at){ should be_same_second_as dataset_attribute.updated_at }
15
+ its(:created_at){ should be_same_second_as dataset_attribute.created_at }
16
+ end
17
+
18
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe Quandl::Cassandra::Models::Dataset do
4
+
5
+ let(:id){ rand(10000*10000) + 10000*10000 }
6
+ let(:dataset){ Quandl::Cassandra::Models::Dataset.new( id: id ) }
7
+ subject{ dataset }
8
+
9
+ it{ should respond_to :id }
10
+ it{ should respond_to :data }
11
+ it{ should respond_to :column_ids }
12
+
13
+ its(:id){ should eq id }
14
+ its(:changes){ should eq( { "id" => [nil, id] }) }
15
+
16
+ describe ".new" do
17
+ let(:dataset){ Quandl::Cassandra::Models::Dataset.new( id: 0 ) }
18
+ subject{ dataset }
19
+ its(:data){ should eq [] }
20
+ its(:column_ids){ should eq [] }
21
+ its(:columns){ should eq [] }
22
+ describe "#data" do
23
+ subject{ dataset.data }
24
+ its(:count){ should eq 0 }
25
+ its(:to_a){ should eq Quandl::Cassandra::Models::Data.new }
26
+ context "given filters" do
27
+ subject{ dataset.data.row(0).column(1) }
28
+ its(:to_a){ should eq Quandl::Cassandra::Models::Data.new }
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "#data=" do
34
+ it "should accept data with dates" do
35
+ subject.data = Quandl::Fabricate::Data.rand(rows: 10, columns: 2, nils: false).to_date.to_a
36
+ subject.save.should be_true
37
+ end
38
+ end
39
+
40
+ describe "#save" do
41
+ subject{ Quandl::Cassandra::Models::Dataset.new }
42
+ before(:each){ subject.save }
43
+ end
44
+
45
+ describe "#class" do
46
+ subject{ dataset.class }
47
+ its(:table_name){ should eq 'datasets' }
48
+ end
49
+
50
+ context "given data" do
51
+ before(:each){ dataset.data = Quandl::Fabricate::Data.rand(rows: 10, columns: 2, nils: false) }
52
+
53
+ describe "#save" do
54
+ before(:each){ dataset.save }
55
+
56
+ subject{ dataset }
57
+
58
+ its(:changes){ should be_blank }
59
+ its(:frequency){ should eq 'daily' }
60
+
61
+ describe ".find" do
62
+ subject{ Quandl::Cassandra::Models::Dataset.find(id) }
63
+ its(:data){ should eq dataset.data.to_table }
64
+ its(:frequency){ should eq 'daily' }
65
+
66
+ describe "#columns" do
67
+ subject{ Quandl::Cassandra::Models::Dataset.find(id).columns }
68
+ its(:first){ should be_a Quandl::Cassandra::Models::ColumnAttribute }
69
+ end
70
+
71
+ it "data should count and return data" do
72
+ subject.data.count.should eq 10
73
+ subject.data.to_table.should be_a Quandl::Cassandra::Models::Data
74
+ end
75
+ it "columns should eq dataset.columns" do
76
+ subject.columns.collect{|c| c.id.to_s }.should eq dataset.columns.collect{|c| c.id.to_s }
77
+ end
78
+ it "column_ids should eq dataset.column_ids" do
79
+ subject.column_ids.collect(&:to_s).should eq dataset.column_ids.collect(&:to_s)
80
+ end
81
+ end
82
+
83
+ describe "#reload" do
84
+ before(:each){
85
+ dataset.data.limit(5).to_a
86
+ dataset.reload
87
+ }
88
+
89
+ describe "#attributes" do
90
+ subject{ dataset.attributes }
91
+ its([:data]){ should eq nil }
92
+ end
93
+
94
+ end
95
+
96
+ describe "#data" do
97
+ subject{ dataset.data }
98
+ its(:count){ should eq 10 }
99
+ end
100
+
101
+ describe "#column_ids" do
102
+ subject{ dataset.column_ids }
103
+ its(:count){ should eq 2 }
104
+ its(:first){ should be_a Cql::Uuid }
105
+ end
106
+
107
+ describe "#columns" do
108
+ subject{ dataset.columns }
109
+ its(:count){ should eq 2 }
110
+ its(:first){ should be_a Quandl::Cassandra::Models::ColumnAttribute }
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+
117
+ end