mode-sdk 0.0.1

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,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