filemaker 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +17 -0
  5. data/.travis.yml +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +116 -0
  9. data/Rakefile +6 -0
  10. data/diagram.png +0 -0
  11. data/filemaker.gemspec +30 -0
  12. data/lib/filemaker.rb +13 -0
  13. data/lib/filemaker/api.rb +13 -0
  14. data/lib/filemaker/api/query_commands/delete.rb +16 -0
  15. data/lib/filemaker/api/query_commands/dup.rb +22 -0
  16. data/lib/filemaker/api/query_commands/edit.rb +26 -0
  17. data/lib/filemaker/api/query_commands/find.rb +46 -0
  18. data/lib/filemaker/api/query_commands/findall.rb +34 -0
  19. data/lib/filemaker/api/query_commands/findany.rb +26 -0
  20. data/lib/filemaker/api/query_commands/findquery.rb +84 -0
  21. data/lib/filemaker/api/query_commands/new.rb +21 -0
  22. data/lib/filemaker/api/query_commands/view.rb +11 -0
  23. data/lib/filemaker/configuration.rb +28 -0
  24. data/lib/filemaker/core_ext/hash.rb +32 -0
  25. data/lib/filemaker/database.rb +29 -0
  26. data/lib/filemaker/error.rb +391 -0
  27. data/lib/filemaker/layout.rb +38 -0
  28. data/lib/filemaker/metadata/field.rb +71 -0
  29. data/lib/filemaker/record.rb +64 -0
  30. data/lib/filemaker/resultset.rb +124 -0
  31. data/lib/filemaker/script.rb +9 -0
  32. data/lib/filemaker/server.rb +197 -0
  33. data/lib/filemaker/store/database_store.rb +21 -0
  34. data/lib/filemaker/store/layout_store.rb +23 -0
  35. data/lib/filemaker/store/script_store.rb +23 -0
  36. data/lib/filemaker/version.rb +3 -0
  37. data/spec/filemaker/api/query_commands/compound_find_spec.rb +69 -0
  38. data/spec/filemaker/error_spec.rb +257 -0
  39. data/spec/filemaker/layout_spec.rb +229 -0
  40. data/spec/filemaker/metadata/field_spec.rb +62 -0
  41. data/spec/filemaker/record_spec.rb +47 -0
  42. data/spec/filemaker/resultset_spec.rb +65 -0
  43. data/spec/filemaker/server_spec.rb +106 -0
  44. data/spec/filemaker/store/database_store_spec.rb +34 -0
  45. data/spec/filemaker/store/layout_store_spec.rb +31 -0
  46. data/spec/filemaker/store/script_store_spec.rb +31 -0
  47. data/spec/spec_helper.rb +84 -0
  48. data/spec/support/responses/dbnames.xml +34 -0
  49. data/spec/support/responses/employment.xml +55 -0
  50. data/spec/support/responses/jobs.xml +199 -0
  51. data/spec/support/responses/layoutnames.xml +39 -0
  52. data/spec/support/responses/portal.xml +108 -0
  53. data/spec/support/responses/scriptnames.xml +29 -0
  54. data/spec/support/xml_loader.rb +29 -0
  55. metadata +227 -0
@@ -0,0 +1,21 @@
1
+ module Filemaker
2
+ module Store
3
+ class DatabaseStore < Hash
4
+ def initialize(server)
5
+ @server = server
6
+ end
7
+
8
+ def [](name)
9
+ super || self[name] = Filemaker::Database.new(name, @server)
10
+ end
11
+
12
+ def all
13
+ response, _params = @server.perform_request(:post, '-dbnames', nil)
14
+ resultset = Filemaker::Resultset.new(@server, response.body)
15
+ resultset.map do |record|
16
+ record['DATABASE_NAME']
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module Filemaker
2
+ module Store
3
+ class LayoutStore < Hash
4
+ def initialize(server, database)
5
+ @server = server
6
+ @database = database
7
+ end
8
+
9
+ def [](name)
10
+ super || self[name] = Filemaker::Layout.new(name, @server, @database)
11
+ end
12
+
13
+ def all
14
+ args = { '-db' => @database.name }
15
+ response, _params = @server.perform_request(:post, '-layoutnames', args)
16
+ resultset = Filemaker::Resultset.new(@server, response.body)
17
+ resultset.map do |record|
18
+ record['LAYOUT_NAME']
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module Filemaker
2
+ module Store
3
+ class ScriptStore < Hash
4
+ def initialize(server, database)
5
+ @server = server
6
+ @database = database
7
+ end
8
+
9
+ def [](name)
10
+ super || self[name] = Filemaker::Script.new(name, @server, @database)
11
+ end
12
+
13
+ def all
14
+ args = { '-db' => @database.name }
15
+ response, _params = @server.perform_request(:post, '-scriptnames', args)
16
+ resultset = Filemaker::Resultset.new(@server, response.body)
17
+ resultset.map do |record|
18
+ record['SCRIPT_NAME']
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module Filemaker
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,69 @@
1
+ describe Filemaker::Api::QueryCommands::CompoundFind do
2
+
3
+ context 'with hash' do
4
+ it '{a: [1, 2]} to (q0);(q1)' do
5
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
6
+ a: [1, 2]
7
+ ).key_maps_string).to eq '(q0);(q1)'
8
+ end
9
+
10
+ it '{a: [1, 2, 3]} to (q0);(q1);(q2)' do
11
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
12
+ a: [1, 2, 3]
13
+ ).key_maps_string).to eq '(q0);(q1);(q2)'
14
+ end
15
+
16
+ it '{a: 1, b: 2} to (q0,q1)' do
17
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
18
+ a: 1, b: 2
19
+ ).key_maps_string).to eq '(q0,q1)'
20
+ end
21
+
22
+ it '{a: 1, b: 2} to (q0,q1)' do
23
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
24
+ a: 1, b: 2
25
+ ).key_maps_string).to eq '(q0,q1)'
26
+ end
27
+
28
+ it '{a: [1, 2], b: 2} to (q0,q2);(q1,q2)' do
29
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
30
+ a: [1, 2], b: 1
31
+ ).key_maps_string).to eq '(q0,q2);(q1,q2)'
32
+ end
33
+
34
+ it '{a: [1, 2], b: 2, c: 3} to (q0,q2,q3);(q1,q2,q3)' do
35
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
36
+ a: [1, 2], b: 2, c: 3
37
+ ).key_maps_string).to eq '(q0,q2,q3);(q1,q2,q3)'
38
+ end
39
+
40
+ it '{a: [1, 2], "-omit": true} to !(q0);!(q1)' do
41
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
42
+ a: [1, 2], '-omit' => true
43
+ ).key_maps_string).to eq '!(q0);!(q1)'
44
+ end
45
+ end
46
+
47
+ context 'with array' do
48
+ it '[{a: 1}, {b: 2}] to (q0);(q1)' do
49
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
50
+ [{ a: 1 }, { b: 2 }]
51
+ ).key_maps_string).to eq '(q0);(q1)'
52
+ end
53
+
54
+ it '[{a: 1, b: 2}, {c: 3}] to (q0,q1);(q2)' do
55
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
56
+ [{ a: 1, b: 2 }, { c: 3 }]
57
+ ).key_maps_string).to eq '(q0,q1);(q2)'
58
+ end
59
+
60
+ it '[{a: [1, 2, 3], b: 1}, {c: 4, "-omit" => true}] to
61
+ (q0,q3);(q1,q3);(q2,q3);!(q4)' do
62
+
63
+ expect(Filemaker::Api::QueryCommands::CompoundFind.new(
64
+ [{ a: [1, 2, 3], b: 1 }, { c: 4, '-omit' => true }]
65
+ ).key_maps_string).to eq '(q0,q3);(q1,q3);(q2,q3);!(q4)'
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,257 @@
1
+ describe Filemaker::Error do
2
+
3
+ context '-1 to 100 errors' do
4
+ it 'raises UnknownError for -1' do
5
+ expect do
6
+ Filemaker::Error.raise_error_by_code(-1)
7
+ end.to raise_error Filemaker::Error::UnknownError
8
+ end
9
+
10
+ it 'raises UserCancelledError for 1' do
11
+ expect do
12
+ Filemaker::Error.raise_error_by_code(1)
13
+ end.to raise_error Filemaker::Error::UserCancelledError
14
+ end
15
+
16
+ it 'raises MemoryError for 2' do
17
+ expect do
18
+ Filemaker::Error.raise_error_by_code(2)
19
+ end.to raise_error Filemaker::Error::MemoryError
20
+ end
21
+
22
+ it 'raises CommandNotAvailableError for 3' do
23
+ expect do
24
+ Filemaker::Error.raise_error_by_code(3)
25
+ end.to raise_error Filemaker::Error::CommandNotAvailableError
26
+ end
27
+
28
+ it 'raises CommandUnknownError for 4' do
29
+ expect do
30
+ Filemaker::Error.raise_error_by_code(4)
31
+ end.to raise_error Filemaker::Error::CommandUnknownError
32
+ end
33
+
34
+ it 'raises CommandInvalidError for 5' do
35
+ expect do
36
+ Filemaker::Error.raise_error_by_code(5)
37
+ end.to raise_error Filemaker::Error::CommandInvalidError
38
+ end
39
+
40
+ it 'raises FileReadOnlyError for 6' do
41
+ expect do
42
+ Filemaker::Error.raise_error_by_code(6)
43
+ end.to raise_error Filemaker::Error::FileReadOnlyError
44
+ end
45
+
46
+ it 'raises OutOfMemoryError for 7' do
47
+ expect do
48
+ Filemaker::Error.raise_error_by_code(7)
49
+ end.to raise_error Filemaker::Error::OutOfMemoryError
50
+ end
51
+
52
+ it 'raises EmptyResultError for 8' do
53
+ expect do
54
+ Filemaker::Error.raise_error_by_code(8)
55
+ end.to raise_error Filemaker::Error::EmptyResultError
56
+ end
57
+
58
+ it 'raises InsufficientPrivilegesError for 9' do
59
+ expect do
60
+ Filemaker::Error.raise_error_by_code(9)
61
+ end.to raise_error Filemaker::Error::InsufficientPrivilegesError
62
+ end
63
+
64
+ it 'raises RequestedDataMissingError for 10' do
65
+ expect do
66
+ Filemaker::Error.raise_error_by_code(10)
67
+ end.to raise_error Filemaker::Error::RequestedDataMissingError
68
+ end
69
+ end
70
+
71
+ context '100 to 199 errors' do
72
+ it 'raises FileMissingError for 100' do
73
+ expect do
74
+ Filemaker::Error.raise_error_by_code(100)
75
+ end.to raise_error Filemaker::Error::FileMissingError
76
+ end
77
+
78
+ it 'raises RecordMissingError for 101' do
79
+ expect do
80
+ Filemaker::Error.raise_error_by_code(101)
81
+ end.to raise_error Filemaker::Error::RecordMissingError
82
+ end
83
+
84
+ it 'raises FieldMissingError for 102' do
85
+ expect do
86
+ Filemaker::Error.raise_error_by_code(102)
87
+ end.to raise_error Filemaker::Error::FieldMissingError
88
+ end
89
+
90
+ it 'raises ScriptMissingError for 104' do
91
+ expect do
92
+ Filemaker::Error.raise_error_by_code(104)
93
+ end.to raise_error Filemaker::Error::ScriptMissingError
94
+ end
95
+
96
+ it 'raises LayoutMissingError for 105' do
97
+ expect do
98
+ Filemaker::Error.raise_error_by_code(105)
99
+ end.to raise_error Filemaker::Error::LayoutMissingError
100
+ end
101
+
102
+ it 'raises TableMissingError for 106' do
103
+ expect do
104
+ Filemaker::Error.raise_error_by_code(106)
105
+ end.to raise_error Filemaker::Error::TableMissingError
106
+ end
107
+
108
+ it 'raises MissingError for 116' do
109
+ expect do
110
+ Filemaker::Error.raise_error_by_code(106)
111
+ end.to raise_error Filemaker::Error::MissingError
112
+ end
113
+ end
114
+
115
+ context '200 to 299 errors' do
116
+ it 'raises RecordAccessDeniedError for 200' do
117
+ expect do
118
+ Filemaker::Error.raise_error_by_code(200)
119
+ end.to raise_error Filemaker::Error::RecordAccessDeniedError
120
+ end
121
+
122
+ it 'raises FieldCannotBeModifiedError for 201' do
123
+ expect do
124
+ Filemaker::Error.raise_error_by_code(201)
125
+ end.to raise_error Filemaker::Error::FieldCannotBeModifiedError
126
+ end
127
+
128
+ it 'raises FieldAccessDeniedError for 202' do
129
+ expect do
130
+ Filemaker::Error.raise_error_by_code(202)
131
+ end.to raise_error Filemaker::Error::FieldAccessDeniedError
132
+ end
133
+ end
134
+
135
+ context '300 to 399 errors' do
136
+ it 'raises FileLockedError for 300' do
137
+ expect do
138
+ Filemaker::Error.raise_error_by_code(300)
139
+ end.to raise_error Filemaker::Error::FileLockedError
140
+ end
141
+
142
+ it 'raises FileLockedError for 301' do
143
+ expect do
144
+ Filemaker::Error.raise_error_by_code(301)
145
+ end.to raise_error Filemaker::Error::RecordInUseError
146
+ end
147
+
148
+ it 'raises TableInUseError for 302' do
149
+ expect do
150
+ Filemaker::Error.raise_error_by_code(302)
151
+ end.to raise_error Filemaker::Error::TableInUseError
152
+ end
153
+
154
+ it 'raises RecordModificationIdMismatchError for 306' do
155
+ expect do
156
+ Filemaker::Error.raise_error_by_code(306)
157
+ end.to raise_error Filemaker::Error::RecordModificationIdMismatchError
158
+ end
159
+ end
160
+
161
+ context '400 to 499 errors' do
162
+ it 'raises FindCriteriaEmptyError for 400' do
163
+ expect do
164
+ Filemaker::Error.raise_error_by_code(400)
165
+ end.to raise_error Filemaker::Error::FindCriteriaEmptyError
166
+ end
167
+
168
+ it 'raises NoRecordsFoundError for 401' do
169
+ expect do
170
+ Filemaker::Error.raise_error_by_code(401)
171
+ end.to raise_error Filemaker::Error::NoRecordsFoundError
172
+ end
173
+ end
174
+
175
+ context '500 to 599 errors' do
176
+ it 'raises DateValidationError for 500' do
177
+ expect do
178
+ Filemaker::Error.raise_error_by_code(500)
179
+ end.to raise_error Filemaker::Error::DateValidationError
180
+ end
181
+
182
+ it 'raises TimeValidationError for 501' do
183
+ expect do
184
+ Filemaker::Error.raise_error_by_code(501)
185
+ end.to raise_error Filemaker::Error::TimeValidationError
186
+ end
187
+
188
+ it 'raises NumberValidationError for 502' do
189
+ expect do
190
+ Filemaker::Error.raise_error_by_code(502)
191
+ end.to raise_error Filemaker::Error::NumberValidationError
192
+ end
193
+
194
+ it 'raises RangeValidationError for 503' do
195
+ expect do
196
+ Filemaker::Error.raise_error_by_code(503)
197
+ end.to raise_error Filemaker::Error::RangeValidationError
198
+ end
199
+
200
+ it 'raises UniquenessValidationError for 504' do
201
+ expect do
202
+ Filemaker::Error.raise_error_by_code(504)
203
+ end.to raise_error Filemaker::Error::UniquenessValidationError
204
+ end
205
+
206
+ it 'raises ExistingValidationError for 505' do
207
+ expect do
208
+ Filemaker::Error.raise_error_by_code(505)
209
+ end.to raise_error Filemaker::Error::ExistingValidationError
210
+ end
211
+
212
+ it 'raises ValueListValidationError for 506' do
213
+ expect do
214
+ Filemaker::Error.raise_error_by_code(506)
215
+ end.to raise_error Filemaker::Error::ValueListValidationError
216
+ end
217
+
218
+ it 'raises CalculationValidationError for 507' do
219
+ expect do
220
+ Filemaker::Error.raise_error_by_code(507)
221
+ end.to raise_error Filemaker::Error::CalculationValidationError
222
+ end
223
+
224
+ it 'raises InvalidFindModeValueValidationError for 508' do
225
+ expect do
226
+ Filemaker::Error.raise_error_by_code(508)
227
+ end.to raise_error Filemaker::Error::InvalidFindModeValueValidationError
228
+ end
229
+
230
+ it 'raises MaximumCharactersValidationError for 511' do
231
+ expect do
232
+ Filemaker::Error.raise_error_by_code(511)
233
+ end.to raise_error Filemaker::Error::MaximumCharactersValidationError
234
+ end
235
+ end
236
+
237
+ context '800 to 899 errors' do
238
+ it 'raises UnableToCreateFileError for 800' do
239
+ expect do
240
+ Filemaker::Error.raise_error_by_code(800)
241
+ end.to raise_error Filemaker::Error::UnableToCreateFileError
242
+ end
243
+
244
+ it 'raises UnableToCreateTempFileError for 801' do
245
+ expect do
246
+ Filemaker::Error.raise_error_by_code(801)
247
+ end.to raise_error Filemaker::Error::UnableToCreateTempFileError
248
+ end
249
+
250
+ it 'raises UnableToOpenFileError for 802' do
251
+ expect do
252
+ Filemaker::Error.raise_error_by_code(802)
253
+ end.to raise_error Filemaker::Error::UnableToOpenFileError
254
+ end
255
+ end
256
+
257
+ end
@@ -0,0 +1,229 @@
1
+ describe Filemaker::Layout do
2
+
3
+ it 'presets -db and -lay' do
4
+ database = Filemaker::Database.new('candidates', double)
5
+ layout = Filemaker::Layout.new('profile', double, database)
6
+ expected_params = { '-db' => 'candidates', '-lay' => 'profile' }
7
+ expect(layout.default_params).to eq expected_params
8
+ end
9
+
10
+ context 'api' do
11
+
12
+ before do
13
+ @server = Filemaker::Server.new do |config|
14
+ config.host = 'host'
15
+ config.account_name = 'account_name'
16
+ config.password = 'password'
17
+ end
18
+
19
+ fake_post_response(@server, nil, 'employment.xml')
20
+ @layout = @server.db['candidates']['Profile']
21
+ end
22
+
23
+ describe 'findany' do
24
+ it 'finds a random record' do
25
+ resultset = @layout.findany
26
+ expect(resultset.params).to have_key('-findany')
27
+ expect(resultset.params['-db']).to eq 'candidates'
28
+ expect(resultset.params['-lay']).to eq 'Profile'
29
+ expect(resultset.params['-findany']).to eq ''
30
+ end
31
+
32
+ it 'ignores -skip, -max' do
33
+ resultset = @layout.findany(max: 1, skip: 2)
34
+ expect(resultset.params).to_not have_key('-max')
35
+ expect(resultset.params).to_not have_key('-skip')
36
+ end
37
+ end
38
+
39
+ describe 'findall' do
40
+ it 'finds all records' do
41
+ resultset = @layout.findall
42
+ expect(resultset.params).to have_key('-findall')
43
+ expect(resultset.params['-db']).to eq 'candidates'
44
+ expect(resultset.params['-lay']).to eq 'Profile'
45
+ expect(resultset.params['-findall']).to eq ''
46
+ end
47
+
48
+ it 'allows -max, -skip' do
49
+ resultset = @layout.findall(
50
+ max: 5, skip: 10,
51
+ sortfield: %w(f1 f2), sortorder: ['descend']
52
+ )
53
+
54
+ expect(resultset.params['-max']).to eq 5
55
+ expect(resultset.params['-skip']).to eq 10
56
+ expect(resultset.params['-sortfield.1']).to eq 'f1'
57
+ expect(resultset.params['-sortfield.2']).to eq 'f2'
58
+ expect(resultset.params['-sortorder.1']).to eq 'descend'
59
+ expect(resultset.params['-sortorder.2']).to eq 'ascend'
60
+ end
61
+
62
+ it 'will not accept more than 9 sortfields' do
63
+ expect do
64
+ @layout.findall(
65
+ sortfield: %w(f1 f2 f3 f4 f5 f6 f7 f8 f9 f10),
66
+ sortorder: %w(o1 o2 o3 o4 o5 o6 o7 o8 o9)
67
+ )
68
+ end.to raise_error Filemaker::Error::ParameterError
69
+ end
70
+
71
+ it 'will not accept more than 9 sortorders' do
72
+ expect do
73
+ @layout.findall(
74
+ sortfield: %w(f1 f2 f3 f4 f5 f6 f7 f8 f9),
75
+ sortorder: %w(o1 o2 o3 o4 o5 o6 o7 o8 o9 o10)
76
+ )
77
+ end.to raise_error Filemaker::Error::ParameterError
78
+ end
79
+ end
80
+
81
+ describe 'find' do
82
+ it 'finds a single record using -recid' do
83
+ resultset = @layout.find(1)
84
+ expect(resultset.params).to have_key('-find')
85
+ expect(resultset.params['-db']).to eq 'candidates'
86
+ expect(resultset.params['-lay']).to eq 'Profile'
87
+ expect(resultset.params['-find']).to eq ''
88
+ expect(resultset.params['-recid']).to eq '1'
89
+ end
90
+
91
+ it 'finds some records with criteria' do
92
+ args = { name: 'Bob', day: Date.parse('25/8/2014') }
93
+ resultset = @layout.find(args, max: 1)
94
+
95
+ expect(resultset.params['name']).to eq 'Bob'
96
+ expect(resultset.params['day']).to eq '08/25/2014'
97
+ expect(resultset.params['-max']).to eq 1
98
+ end
99
+
100
+ it 'switches layout for response' do
101
+ resultset = @layout.find({}, lay_response: 'my_layout')
102
+ expect(resultset.params['-lay.response']).to eq 'my_layout'
103
+ end
104
+
105
+ it 'OR the query' do
106
+ resultset = @layout.find({}, lop: 'or')
107
+ expect(resultset.params['-lop']).to eq 'or'
108
+ end
109
+ end
110
+
111
+ describe 'delete' do
112
+ it 'deletes a record' do
113
+ resultset = @layout.delete(1)
114
+ expect(resultset.params).to have_key('-delete')
115
+ expect(resultset.params['-db']).to eq 'candidates'
116
+ expect(resultset.params['-lay']).to eq 'Profile'
117
+ expect(resultset.params['-delete']).to eq ''
118
+ expect(resultset.params['-recid']).to eq '1'
119
+ end
120
+ end
121
+
122
+ describe 'edit' do
123
+ it 'edits a record' do
124
+ resultset = @layout.edit(123, { first_name: 'Bob' }, modid: 55)
125
+ expect(resultset.params).to have_key('-edit')
126
+ expect(resultset.params['-db']).to eq 'candidates'
127
+ expect(resultset.params['-lay']).to eq 'Profile'
128
+ expect(resultset.params['-edit']).to eq ''
129
+ expect(resultset.params['-recid']).to eq '123'
130
+ expect(resultset.params['first_name']).to eq 'Bob'
131
+ expect(resultset.params['-modid']).to eq 55
132
+ end
133
+
134
+ it 'filters layout relatedset and returns all portal records' do
135
+ args = { first_name: 'Bob' }
136
+ options = { relatedsets_filter: 'layout', relatedsets_max: 'all' }
137
+ resultset = @layout.edit(123, args, options)
138
+ expect(resultset.params['-relatedsets.filter']).to eq 'layout'
139
+ expect(resultset.params['-relatedsets.max']).to eq 'all'
140
+ end
141
+
142
+ it 'deletes a portal record using -edit' do
143
+ resultset = @layout.edit(123, {}, delete_related: 'jobtable.20')
144
+ expect(resultset.params['-delete.related']).to eq 'jobtable.20'
145
+ end
146
+ end
147
+
148
+ describe 'new' do
149
+ it 'adds a new record' do
150
+ resultset = @layout.new({ first_name: 'Bob' })
151
+ expect(resultset.params).to have_key('-new')
152
+ expect(resultset.params['-db']).to eq 'candidates'
153
+ expect(resultset.params['-lay']).to eq 'Profile'
154
+ expect(resultset.params['-new']).to eq ''
155
+ expect(resultset.params['first_name']).to eq 'Bob'
156
+ end
157
+ end
158
+
159
+ describe 'dup' do
160
+ it 'duplicates a record' do
161
+ resultset = @layout.dup(123)
162
+ expect(resultset.params).to have_key('-dup')
163
+ expect(resultset.params['-db']).to eq 'candidates'
164
+ expect(resultset.params['-lay']).to eq 'Profile'
165
+ expect(resultset.params['-dup']).to eq ''
166
+ expect(resultset.params['-recid']).to eq '123'
167
+ end
168
+ end
169
+
170
+ describe 'view' do
171
+ it 'retrieves layout information with zero record' do
172
+ resultset = @layout.view
173
+ expect(resultset.params).to have_key('-view')
174
+ expect(resultset.params['-view']).to eq ''
175
+ end
176
+ end
177
+
178
+ describe 'query' do
179
+ it 'transform {a: [1,2]} to (q0);(q1)' do
180
+ resultset = @layout.query(status: %w(open closed))
181
+ expect(resultset.params['-query']).to eq '(q0);(q1)'
182
+ end
183
+
184
+ it 'transforms [{a:1, b:2}, {c:3}, {d:4}, {e:5, "-omit": true}] to \
185
+ (q0,q1);(q2);(q3);!(q4)' do
186
+
187
+ resultset = @layout.query(
188
+ [{ a: 1, b: 2 }, { c: 3 }, { d: 4 }, { e: 5, '-omit' => true }]
189
+ )
190
+ expect(resultset.params['-query']).to eq '(q0,q1);(q2);(q3);!(q4)'
191
+ end
192
+ end
193
+
194
+ context 'script, prefind, and presort' do
195
+ it 'can do -script' do
196
+ resultset = @layout.find(1, script: 'Remove Duplicates')
197
+ expect(resultset.params['-script']).to eq 'Remove Duplicates'
198
+ end
199
+
200
+ it 'can do -script.param' do
201
+ resultset = @layout.find(1, script: ['Remove Duplicates', 'reverse'])
202
+ expect(resultset.params['-script']).to eq 'Remove Duplicates'
203
+ expect(resultset.params['-script.param']).to eq 'reverse'
204
+ end
205
+
206
+ it 'can do -script.prefind' do
207
+ resultset = @layout.find(1, script_prefind: 'Unique')
208
+ expect(resultset.params['-script.prefind']).to eq 'Unique'
209
+ end
210
+
211
+ it 'can do -script.prefind.param' do
212
+ resultset = @layout.find(1, script_prefind: %w(Unique yes))
213
+ expect(resultset.params['-script.prefind']).to eq 'Unique'
214
+ expect(resultset.params['-script.prefind.param']).to eq 'yes'
215
+ end
216
+
217
+ it 'can do -script.presort' do
218
+ resultset = @layout.find(1, script_presort: 'Order')
219
+ expect(resultset.params['-script.presort']).to eq 'Order'
220
+ end
221
+
222
+ it 'can do -script.presort.param' do
223
+ resultset = @layout.find(1, script_presort: %w(Order ascend))
224
+ expect(resultset.params['-script.presort']).to eq 'Order'
225
+ expect(resultset.params['-script.presort.param']).to eq 'ascend'
226
+ end
227
+ end
228
+ end
229
+ end