mode-sdk 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe Mode::Sdk::Column do
6
+ describe '#validate!' do
7
+ it 'returns true if no exceptions are raised' do
8
+ column = Mode::Sdk::Column.new({})
9
+
10
+ expect(column).to receive(:validate_keys!)
11
+ expect(column).to receive(:validate_name!)
12
+ expect(column).to receive(:validate_type!)
13
+
14
+ expect(column.validate!).to eq(true)
15
+ end
16
+ end
17
+
18
+ describe '#validate_keys!' do
19
+ it 'raises error if column is missing name key' do
20
+ column = Mode::Sdk::Column.new(type: 'text')
21
+
22
+ expect {
23
+ column.send(:validate_keys!)
24
+ }.to raise_error(Mode::Sdk::Column::InvalidError) do |exception|
25
+ expect(exception.message).to match(/missing required key 'name'/i)
26
+ end
27
+ end
28
+
29
+ it 'raises error if column is missing type key' do
30
+ column = Mode::Sdk::Column.new(name: 'name')
31
+
32
+ expect {
33
+ column.send(:validate_keys!)
34
+ }.to raise_error(Mode::Sdk::Column::InvalidError) do |exception|
35
+ expect(exception.message).to match(/missing required key 'type'/i)
36
+ end
37
+ end
38
+
39
+ it 'raises error if column has extra keys' do
40
+ column = Mode::Sdk::Column.new(name: 'name', type: 'text', foo: 'bar')
41
+
42
+ expect {
43
+ column.send(:validate_keys!)
44
+ }.to raise_error(Mode::Sdk::Column::InvalidError) do |exception|
45
+ expect(exception.message).to match(/has unexpected keys/i)
46
+ end
47
+ end
48
+
49
+ it 'returns true for valid keys' do
50
+ column = Mode::Sdk::Column.new(name: nil, type: nil)
51
+
52
+ expect(column.send(:validate_keys!)).to eq(true)
53
+ end
54
+ end
55
+
56
+ describe '#validate_name!' do
57
+ it 'raises error if column name is too short' do
58
+ column = Mode::Sdk::Column.new(name: 'n')
59
+
60
+ expect {
61
+ column.send(:validate_name!)
62
+ }.to raise_error(Mode::Sdk::Column::InvalidError) do |exception|
63
+ expect(exception.message).to match(/name is invalid/i)
64
+ end
65
+ end
66
+
67
+ it 'raises error if column name is too long' do
68
+ column = Mode::Sdk::Column.new(name: 'no' * 50)
69
+
70
+ expect {
71
+ column.send(:validate_name!)
72
+ }.to raise_error(Mode::Sdk::Column::InvalidError) do |exception|
73
+ expect(exception.message).to match(/name is invalid/i)
74
+ end
75
+ end
76
+
77
+ it 'returns true for valid name' do
78
+ column = Mode::Sdk::Column.new(name: 'name')
79
+
80
+ expect(column.send(:validate_name!)).to eq(true)
81
+ end
82
+ end
83
+
84
+ describe '#validate_type!' do
85
+ it 'raises error if column type is not recognized' do
86
+ column = Mode::Sdk::Column.new(type: 'nope')
87
+
88
+ expect {
89
+ column.send(:validate_type!)
90
+ }.to raise_error(Mode::Sdk::Column::InvalidError) do |exception|
91
+ expect(exception.message).to match(/type is invalid/i)
92
+ end
93
+ end
94
+
95
+ it 'returns true for valid type' do
96
+ column = Mode::Sdk::Column.new(type: 'integer')
97
+
98
+ expect(column.send(:validate_type!)).to eq(true)
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe Mode::Sdk::HashUtil do
6
+ let :util do
7
+ Object.new.extend(Mode::Sdk::HashUtil)
8
+ end
9
+
10
+ describe '#stringify_keys' do
11
+ it 'stringifies keys' do
12
+ hash = { foo1: 'bar1', foo2: 'bar2' }
13
+
14
+ expect(util.stringify_keys(hash)).to eq(
15
+ 'foo1' => 'bar1', 'foo2' => 'bar2')
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe Mode::Sdk::TableImport do
6
+ describe '#poll' do
7
+ it 'polls state until completed' do
8
+ import = Mode::Sdk::TableImport.new('/some/path')
9
+
10
+ reprs = %w(new enqueued running running failed).map do |state|
11
+ { 'state' => state }
12
+ end
13
+
14
+ expect(import).to receive(:fetch_repr).and_return(*reprs)
15
+
16
+ expect { |b|
17
+ import.poll(0, &b)
18
+ }.to yield_successive_args(*reprs)
19
+ end
20
+ end
21
+
22
+ describe '#fetch_repr' do
23
+ it 'performs get request' do
24
+ import = Mode::Sdk::TableImport.new('/some/path')
25
+
26
+ response = double(:response, body: { 'state' => 'enqueued' })
27
+
28
+ expect(Mode::Sdk::Client).to receive(:get).and_return(response)
29
+
30
+ expect(import.send(:fetch_repr)).to eq('state' => 'enqueued')
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,191 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe Mode::Sdk::Table do
6
+ describe '#owner' do
7
+ it 'defaults to authenticated username' do
8
+ expect(Mode::Sdk).to receive(:username).and_return('sally')
9
+ table = Mode::Sdk::Table.new('name')
10
+ expect(table.send(:owner)).to eq('sally')
11
+ end
12
+
13
+ it 'uses owner option if present' do
14
+ expect(Mode::Sdk).to receive(:username).never
15
+ table = Mode::Sdk::Table.new('name', owner: 'earl')
16
+ expect(table.send(:owner)).to eq('earl')
17
+ end
18
+ end
19
+
20
+ describe '#resource_path' do
21
+ it 'forms path correctly' do
22
+ table = Mode::Sdk::Table.new('name', owner: 'sally')
23
+ expect(table.send(:resource_path)).to eq('/api/sally/tables/name')
24
+ end
25
+ end
26
+
27
+ describe '#exists?' do
28
+ it 'is true if table exists' do
29
+ response = Mode::Sdk::Client::Response.new(nil)
30
+ expect(response).to receive(:code).and_return(200)
31
+ expect(Mode::Sdk::Client).to receive(:head).and_return(response)
32
+
33
+ table = Mode::Sdk::Table.new('name', owner: 'sally')
34
+ expect(table.send(:exists?)).to eq(true)
35
+ end
36
+
37
+ it 'is false if table does not exist' do
38
+ response = Mode::Sdk::Client::Response.new(nil)
39
+ expect(response).to receive(:code).and_return(404)
40
+ expect(Mode::Sdk::Client).to receive(:head).and_return(response)
41
+
42
+ table = Mode::Sdk::Table.new('name', owner: 'sally')
43
+ expect(table.send(:exists?)).to eq(false)
44
+ end
45
+ end
46
+
47
+ describe '#create' do
48
+ it 'creates table' do
49
+ table = Mode::Sdk::Table.new('name')
50
+
51
+ expect(table).to receive(:upsert) do |*args|
52
+ expect(args.first).to eq(:create)
53
+ end
54
+
55
+ expect(table.create).to eq(true)
56
+ end
57
+ end
58
+
59
+ describe '#replace' do
60
+ it 'creates table' do
61
+ table = Mode::Sdk::Table.new('name')
62
+
63
+ expect(table).to receive(:upsert) do |*args|
64
+ expect(args.first).to eq(:replace)
65
+ end
66
+
67
+ expect(table.replace).to eq(true)
68
+ end
69
+ end
70
+
71
+ describe '#validate!' do
72
+ it 'raises exception if upload token is missing' do
73
+ table = Mode::Sdk::Table.new('no')
74
+
75
+ expect {
76
+ table.send(:validate!)
77
+ }.to raise_error(Mode::Sdk::Table::InvalidError) do |exception|
78
+ expect(exception.message).to match(/missing required attribute/i)
79
+ end
80
+ end
81
+
82
+ it 'raises exception if table name is invalid' do
83
+ table = Mode::Sdk::Table.new('no')
84
+ table.upload_token = 'token'
85
+
86
+ expect {
87
+ table.send(:validate!)
88
+ }.to raise_error(Mode::Sdk::Table::InvalidError) do |exception|
89
+ expect(exception.message).to match(/invalid name/i)
90
+ end
91
+ end
92
+
93
+ it 'returns true if no exceptions are raised' do
94
+ table = Mode::Sdk::Table.new('name')
95
+ table.upload_token = 'token'
96
+
97
+ expect_any_instance_of(Mode::Sdk::ColumnSet).to(
98
+ receive(:validate!).at_least(:once).and_return(true))
99
+
100
+ expect(table.send(:validate!)).to eq(true)
101
+ end
102
+ end
103
+
104
+ describe '#upsert' do
105
+ let :response do
106
+ Mode::Sdk::Client::Response.new(nil)
107
+ end
108
+
109
+ describe 'for create' do
110
+ it 'creates table' do
111
+ table = Mode::Sdk::Table.new('name', owner: 'owner')
112
+
113
+ expect(table).to receive(:validate!)
114
+ expect(response).to receive(:code).and_return(200)
115
+ expect(Mode::Sdk::Client).to receive(:post).and_return(response)
116
+
117
+ expect(table.send(:upsert, :create)).to be_an_instance_of(
118
+ Mode::Sdk::Client::Response)
119
+ end
120
+
121
+ it 'raises exception for bad request' do
122
+ table = Mode::Sdk::Table.new('name', owner: 'owner')
123
+
124
+ expect(table).to receive(:validate!)
125
+ expect(response).to receive(:code).and_return(400)
126
+ expect(response).to receive(:body)
127
+ expect(Mode::Sdk::Client).to receive(:post).and_return(response)
128
+
129
+ expect {
130
+ table.send(:upsert, :create)
131
+ }.to raise_error(Mode::Sdk::Table::InvalidError)
132
+ end
133
+ end
134
+
135
+ describe 'for replace' do
136
+ it 'replaces table' do
137
+ table = Mode::Sdk::Table.new('name', owner: 'owner')
138
+
139
+ expect(table).to receive(:validate!)
140
+ expect(response).to receive(:code).and_return(200)
141
+ expect(Mode::Sdk::Client).to receive(:put).and_return(response)
142
+
143
+ expect(table.send(:upsert, :replace)).to be_an_instance_of(
144
+ Mode::Sdk::Client::Response)
145
+ end
146
+ end
147
+ end
148
+
149
+ describe '#full_name' do
150
+ it 'forms full name with schema' do
151
+ table = Mode::Sdk::Table.new('name', owner: 'owner')
152
+
153
+ expect(table.full_name).to eq('owner.name')
154
+ end
155
+ end
156
+
157
+ describe '#upsert_data' do
158
+ it 'is formed correctly' do
159
+ table = Mode::Sdk::Table.new('name', owner: 'owner')
160
+ table.columns = [{ name: 'name', type: 'string' }]
161
+ table.upload_token = 'token'
162
+
163
+ result = table.send(:upsert_data)
164
+
165
+ expected = {
166
+ upload_token: 'token',
167
+ table: {
168
+ name: 'name',
169
+ description: nil,
170
+ columns: [{ 'name' => 'name', 'type' => 'string' }]
171
+ }
172
+ }
173
+
174
+ expect(result).to eq(expected)
175
+ end
176
+ end
177
+
178
+ describe '#columns=' do
179
+ it 'unmemoizes column set' do
180
+ table = Mode::Sdk::Table.new('name', owner: 'owner')
181
+ table.columns = [{ name: 'name', type: 'string' }]
182
+ table.send(:column_set)
183
+
184
+ expect(table.instance_variable_defined?(:@column_set)).to eq(true)
185
+
186
+ table.columns = [{ name: 'name', type: 'string' }]
187
+
188
+ expect(table.instance_variable_defined?(:@column_set)).to eq(false)
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe Mode::Sdk::Upload do
6
+ describe '#create' do
7
+ it 'performs http post' do
8
+ upload = Mode::Sdk::Upload.new('content')
9
+
10
+ expect(Mode::Sdk::Client).to receive(:post) do |*args|
11
+ expect(args[0]).to eq('/api/uploads')
12
+
13
+ expect(args[1]).to eq('content')
14
+
15
+ options = args[2]
16
+
17
+ expect(options[:content_type]).to eq('application/csv')
18
+ expect(options[:content_length]).to eq(7)
19
+ expect(options[:expect]).to eq([201])
20
+ end
21
+
22
+ upload.create
23
+ end
24
+ end
25
+
26
+ describe '#token' do
27
+ it 'retrieves the token' do
28
+ upload = Mode::Sdk::Upload.new('content')
29
+
30
+ response = Mode::Sdk::Client::Response.new(nil)
31
+ expect(response).to receive(:body).and_return('token' => 'sometoken')
32
+ expect(upload).to receive(:create).and_return(response)
33
+
34
+ expect(upload.token).to eq('sometoken')
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe Mode::Sdk::WarehouseUtil do
6
+ let :util do
7
+ Object.new.extend(Mode::Sdk::WarehouseUtil)
8
+ end
9
+
10
+ describe '#normalize_name' do
11
+ it 'preserves short name' do
12
+ expect(util.normalize_name('foo_bar')).to eq('foo_bar')
13
+ end
14
+
15
+ it 'truncates long name' do
16
+ expect(util.normalize_name('a' * 100).size).to eq(64)
17
+ end
18
+ end
19
+
20
+ describe '#normalize_string' do
21
+ it 'preserves simple strings' do
22
+ %w(foo foo_bar foo_bar_baz).each do |string|
23
+ expect(util.send(:normalize_string, string)).to eq(string)
24
+ end
25
+ end
26
+
27
+ it 'normalizes messy strings' do
28
+ expected = {
29
+ ' fOO_' => 'foo',
30
+ '_ foo___' => 'foo',
31
+ 'fo*(*o__BaR ! ?' => 'foo_bar',
32
+ 'fo__o- _!bar_b _ - az ' => 'fo_o_bar_b_az'
33
+ }
34
+
35
+ expected.each do |input, output|
36
+ expect(util.send(:normalize_string, input)).to eq(output)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe Mode::Sdk do
6
+ after :each do
7
+ Mode::Sdk.reset
8
+ end
9
+
10
+ describe '.configure' do
11
+ it 'sets configuration variables' do
12
+ expect_any_instance_of(
13
+ Mode::Sdk::Configuration).to receive(:setting=).once
14
+
15
+ Mode::Sdk.configure do |config|
16
+ config.setting = 'value'
17
+ end
18
+ end
19
+ end
20
+
21
+ describe '.config' do
22
+ it 'instantiates and memoizes configuration instance' do
23
+ expect(Mode::Sdk.instance_variable_get(:@config)).to be_nil
24
+
25
+ expect(Mode::Sdk.config).to be_an_instance_of(Mode::Sdk::Configuration)
26
+
27
+ config = Mode::Sdk.instance_variable_get(:@config)
28
+
29
+ expect(config).to be_an_instance_of(Mode::Sdk::Configuration)
30
+ end
31
+ end
32
+
33
+ describe '.account' do
34
+ it 'returns account from client' do
35
+ expect(Mode::Sdk::Client).to receive(:account).and_return(
36
+ 'username' => 'someone')
37
+
38
+ expect(Mode::Sdk.account).to eq('username' => 'someone')
39
+ end
40
+ end
41
+
42
+ describe '.username' do
43
+ it 'returns username from client' do
44
+ expect(Mode::Sdk::Client).to receive(:account).and_return(
45
+ 'username' => 'someone')
46
+
47
+ expect(Mode::Sdk.username).to eq('someone')
48
+ end
49
+ end
50
+ end