ronin-code-sql 2.0.0.beta1 → 2.1.0

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +15 -0
  3. data/.rubocop.yml +13 -0
  4. data/.yardopts +1 -1
  5. data/ChangeLog.md +10 -1
  6. data/Gemfile +4 -0
  7. data/README.md +26 -16
  8. data/Rakefile +1 -0
  9. data/gemspec.yml +3 -3
  10. data/lib/ronin/code/sql/binary_expr.rb +35 -2
  11. data/lib/ronin/code/sql/clause.rb +19 -8
  12. data/lib/ronin/code/sql/clauses.rb +17 -15
  13. data/lib/ronin/code/sql/emittable.rb +9 -2
  14. data/lib/ronin/code/sql/emitter.rb +65 -26
  15. data/lib/ronin/code/sql/field.rb +31 -6
  16. data/lib/ronin/code/sql/fields.rb +1 -1
  17. data/lib/ronin/code/sql/function.rb +15 -4
  18. data/lib/ronin/code/sql/functions.rb +3 -15
  19. data/lib/ronin/code/sql/injection.rb +4 -4
  20. data/lib/ronin/code/sql/injection_expr.rb +1 -1
  21. data/lib/ronin/code/sql/literal.rb +17 -2
  22. data/lib/ronin/code/sql/literals.rb +1 -1
  23. data/lib/ronin/code/sql/mixin.rb +95 -0
  24. data/lib/ronin/code/sql/operators.rb +1 -1
  25. data/lib/ronin/code/sql/statement.rb +14 -3
  26. data/lib/ronin/code/sql/statement_list.rb +1 -1
  27. data/lib/ronin/code/sql/statements.rb +1 -1
  28. data/lib/ronin/code/sql/unary_expr.rb +24 -2
  29. data/lib/ronin/code/sql/version.rb +3 -3
  30. data/lib/ronin/code/sql.rb +5 -64
  31. data/lib/ronin/code/sqli.rb +30 -0
  32. data/ronin-code-sql.gemspec +5 -5
  33. metadata +10 -51
  34. data/spec/spec_helper.rb +0 -3
  35. data/spec/sql/binary_expr_examples.rb +0 -25
  36. data/spec/sql/binary_expr_spec.rb +0 -5
  37. data/spec/sql/clause_examples.rb +0 -43
  38. data/spec/sql/clause_spec.rb +0 -31
  39. data/spec/sql/clauses_spec.rb +0 -47
  40. data/spec/sql/emittable_spec.rb +0 -41
  41. data/spec/sql/emitter_spec.rb +0 -533
  42. data/spec/sql/field_spec.rb +0 -103
  43. data/spec/sql/fields_spec.rb +0 -40
  44. data/spec/sql/function_examples.rb +0 -30
  45. data/spec/sql/function_spec.rb +0 -25
  46. data/spec/sql/functions_spec.rb +0 -113
  47. data/spec/sql/injection_expr_spec.rb +0 -98
  48. data/spec/sql/injection_spec.rb +0 -172
  49. data/spec/sql/literal_spec.rb +0 -5
  50. data/spec/sql/literals_spec.rb +0 -46
  51. data/spec/sql/operators_spec.rb +0 -44
  52. data/spec/sql/statement_examples.rb +0 -39
  53. data/spec/sql/statement_list_spec.rb +0 -48
  54. data/spec/sql/statement_spec.rb +0 -38
  55. data/spec/sql/statements_spec.rb +0 -22
  56. data/spec/sql/unary_expr_examples.rb +0 -20
  57. data/spec/sql/unary_expr_spec.rb +0 -5
  58. data/spec/sql_spec.rb +0 -18
@@ -1,533 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/code/sql/literal'
3
- require 'ronin/code/sql/unary_expr'
4
- require 'ronin/code/sql/binary_expr'
5
- require 'ronin/code/sql/field'
6
- require 'ronin/code/sql/statement'
7
- require 'ronin/code/sql/statement_list'
8
- require 'ronin/code/sql/emitter'
9
-
10
- describe Ronin::Code::SQL::Emitter do
11
- describe "#initialize" do
12
- context "without options" do
13
- it { expect(subject.space).to eq(' ') }
14
- it { expect(subject.quotes).to eq(:single) }
15
- end
16
- end
17
-
18
- describe "#emit_keyword" do
19
- context "when passed an Array of Symbols" do
20
- let(:keywords) { [:DROP, :TABLE] }
21
-
22
- it "should join the keywords" do
23
- expect(subject.emit_keyword(keywords)).to eq("DROP TABLE")
24
- end
25
-
26
- context "when :space is set" do
27
- subject { described_class.new(space: '/**/') }
28
-
29
- it "should join the keywords" do
30
- expect(subject.emit_keyword(keywords)).to eq("DROP/**/TABLE")
31
- end
32
- end
33
- end
34
-
35
- context "when case is :upper" do
36
- let(:keyword) { :select }
37
-
38
- subject { described_class.new(case: :upper) }
39
-
40
- it "should upcase the keyword" do
41
- expect(subject.emit_keyword(keyword)).to eq('SELECT')
42
- end
43
- end
44
-
45
- context "when case is :lower" do
46
- let(:keyword) { :SELECT }
47
-
48
- subject { described_class.new(case: :lower) }
49
-
50
- it "should upcase the keyword" do
51
- expect(subject.emit_keyword(keyword)).to eq('select')
52
- end
53
- end
54
-
55
- context "when case is :random" do
56
- let(:keyword) { :select }
57
-
58
- subject { described_class.new(case: :random) }
59
-
60
- it "should contain at least one upper-case character" do
61
- expect(subject.emit_keyword(keyword)).to match(/[SELECT]/)
62
- end
63
- end
64
-
65
- context "when case is nil" do
66
- subject { described_class.new(case: nil) }
67
-
68
- let(:keyword) { 'Select' }
69
-
70
- it "should emit the keyword as is" do
71
- expect(subject.emit_keyword(keyword)).to eq(keyword)
72
- end
73
- end
74
- end
75
-
76
- describe "#emit_operator" do
77
- context "when the operator is a symbol" do
78
- it "should emit a String" do
79
- expect(subject.emit_operator(:"!=")).to eq('!=')
80
- end
81
- end
82
-
83
- context "otherwise" do
84
- subject { described_class.new(case: :lower) }
85
-
86
- it "should emit a keyword" do
87
- expect(subject.emit_operator(:AS)).to eq('as')
88
- end
89
- end
90
- end
91
-
92
- describe "#emit_null" do
93
- it "should emit the NULL keyword" do
94
- expect(subject.emit_null).to eq('NULL')
95
- end
96
- end
97
-
98
- describe "#emit_false" do
99
- it "should emit 1=0" do
100
- expect(subject.emit_false).to eq('1=0')
101
- end
102
- end
103
-
104
- describe "#emit_true" do
105
- it "should emit 1=1" do
106
- expect(subject.emit_true).to eq('1=1')
107
- end
108
- end
109
-
110
- describe "#emit_integer" do
111
- it "should emit a String" do
112
- expect(subject.emit_integer(10)).to eq('10')
113
- end
114
- end
115
-
116
- describe "#emit_decimal" do
117
- it "should emit a String" do
118
- expect(subject.emit_decimal(2.5)).to eq('2.5')
119
- end
120
- end
121
-
122
- describe "#emit_string" do
123
- it "should emit a String" do
124
- expect(subject.emit_string("O'Brian")).to eq("'O''Brian'")
125
- end
126
-
127
- context "when :quotes is :double" do
128
- subject { described_class.new(quotes: :double) }
129
-
130
- it "should double quote Strings" do
131
- expect(subject.emit_string("O'Brian")).to eq("\"O'Brian\"")
132
- end
133
- end
134
- end
135
-
136
- describe "#emit_field" do
137
- subject { described_class.new(case: :upper) }
138
-
139
- let(:field) { Ronin::Code::SQL::Field.new(:id) }
140
-
141
- it "should emit the name as a keyword" do
142
- expect(subject.emit_field(field)).to eq('ID')
143
- end
144
-
145
- context "when the field has a parent" do
146
- let(:parent) { Ronin::Code::SQL::Field.new(:users) }
147
- let(:field) { Ronin::Code::SQL::Field.new(:id,parent) }
148
-
149
- it "should emit the parent then the field name" do
150
- expect(subject.emit_field(field)).to eq('USERS.ID')
151
- end
152
- end
153
- end
154
-
155
- describe "#emit_list" do
156
- it "should emit a ',' separated list" do
157
- expect(subject.emit_list([1,2,3,'foo'])).to eq("(1,2,3,'foo')")
158
- end
159
- end
160
-
161
- describe "#emit_assignments" do
162
- let(:values) { {x: 1, y: 2} }
163
-
164
- it "should emit a list of column names and values" do
165
- expect(subject.emit_assignments(values)).to eq('x=1,y=2')
166
- end
167
- end
168
-
169
- describe "#emit_argument" do
170
- context "when the value is a Statement" do
171
- let(:stmt) { Ronin::Code::SQL::Statement.new(:SELECT,1) }
172
-
173
- it "should wrap the statement in ( )" do
174
- expect(subject.emit_argument(stmt)).to eq('(SELECT 1)')
175
- end
176
- end
177
-
178
- context "otherwise" do
179
- let(:value) { 'hello' }
180
-
181
- it "should emit the value" do
182
- expect(subject.emit_argument(value)).to eq("'hello'")
183
- end
184
- end
185
- end
186
-
187
- describe "#emit_expression" do
188
- context "when the expression is a BinaryExpr" do
189
- context "when the operator is alphabetic" do
190
- subject { described_class.new(case: :upper) }
191
-
192
- let(:expr) { Ronin::Code::SQL::BinaryExpr.new(:id,:is,1) }
193
-
194
- it "should emit the operands and operator as a keyword with spaces" do
195
- expect(subject.emit_expression(expr)).to eq('ID IS 1')
196
- end
197
- end
198
-
199
- context "when the operator is symbolic" do
200
- let(:expr) { Ronin::Code::SQL::BinaryExpr.new(:id,:"=",1) }
201
-
202
- it "should emit the operands and operator without spaces" do
203
- expect(subject.emit_expression(expr)).to eq('id=1')
204
- end
205
- end
206
-
207
- context "when the left-hand operand is a Statement" do
208
- let(:expr) do
209
- Ronin::Code::SQL::BinaryExpr.new(
210
- Ronin::Code::SQL::Statement.new(:SELECT,1), :"=", 1
211
- )
212
- end
213
-
214
- it "should wrap the left-hand operand in parenthesis" do
215
- expect(subject.emit_expression(expr)).to eq('(SELECT 1)=1')
216
- end
217
- end
218
-
219
- context "when the right-hand operand is a Statement" do
220
- let(:expr) do
221
- Ronin::Code::SQL::BinaryExpr.new(
222
- 1, :"=", Ronin::Code::SQL::Statement.new(:SELECT,1)
223
- )
224
- end
225
-
226
- it "should wrap the left-hand operand in parenthesis" do
227
- expect(subject.emit_expression(expr)).to eq('1=(SELECT 1)')
228
- end
229
- end
230
- end
231
-
232
- context "when the expression is a UnaryExpr" do
233
- context "when the operator is upper-case alpha" do
234
- let(:expr) { Ronin::Code::SQL::UnaryExpr.new(:NOT,:admin) }
235
-
236
- it "should emit the operand and operator with spaces" do
237
- expect(subject.emit_expression(expr)).to eq('NOT admin')
238
- end
239
- end
240
-
241
- context "when the operator is symbolic" do
242
- let(:expr) { Ronin::Code::SQL::UnaryExpr.new(:"-",1) }
243
-
244
- it "should emit the operand and operator without spaces" do
245
- expect(subject.emit_expression(expr)).to eq('-1')
246
- end
247
- end
248
-
249
- context "when the operand is a Statement" do
250
- let(:expr) do
251
- Ronin::Code::SQL::UnaryExpr.new(
252
- :NOT, Ronin::Code::SQL::Statement.new(:SELECT,1)
253
- )
254
- end
255
-
256
- it "should wrap the operand in parenthesis" do
257
- expect(subject.emit_expression(expr)).to eq('NOT (SELECT 1)')
258
- end
259
- end
260
- end
261
- end
262
-
263
- describe "#emit_function" do
264
- let(:func) { Ronin::Code::SQL::Function.new(:NOW) }
265
-
266
- it "should emit the function name as a keyword" do
267
- expect(subject.emit_function(func)).to eq('NOW()')
268
- end
269
-
270
- context "with arguments" do
271
- let(:func) { Ronin::Code::SQL::Function.new(:MAX,1,2) }
272
-
273
- it "should emit the function arguments" do
274
- expect(subject.emit_function(func)).to eq('MAX(1,2)')
275
- end
276
- end
277
- end
278
-
279
- describe "#emit" do
280
- context "when passed nil" do
281
- it "should emit the NULL keyword" do
282
- expect(subject.emit(nil)).to eq('NULL')
283
- end
284
- end
285
-
286
- context "when passed true" do
287
- it "should emit true" do
288
- expect(subject.emit(true)).to eq('1=1')
289
- end
290
- end
291
-
292
- context "when passed false" do
293
- it "should emit false" do
294
- expect(subject.emit(false)).to eq('1=0')
295
- end
296
- end
297
-
298
- context "when passed an Integer" do
299
- it "should emit an integer" do
300
- expect(subject.emit(10)).to eq('10')
301
- end
302
- end
303
-
304
- context "when passed a Float" do
305
- it "should emit a decimal" do
306
- expect(subject.emit(2.5)).to eq('2.5')
307
- end
308
- end
309
-
310
- context "when passed a String" do
311
- it "should emit a string" do
312
- expect(subject.emit("O'Brian")).to eq("'O''Brian'")
313
- end
314
- end
315
-
316
- context "when passed a Literal" do
317
- let(:literal) { Ronin::Code::SQL::Literal.new(42) }
318
-
319
- it "should emit the value" do
320
- expect(subject.emit(literal)).to eq('42')
321
- end
322
- end
323
-
324
- context "when passed a Field" do
325
- let(:table) { Ronin::Code::SQL::Field.new(:users) }
326
- let(:column) { Ronin::Code::SQL::Field.new(:id,table) }
327
-
328
- it "should emit a field" do
329
- expect(subject.emit(column)).to eq('users.id')
330
- end
331
- end
332
-
333
- context "when passed a Symbol" do
334
- it "should emit a field" do
335
- expect(subject.emit(:id)).to eq('id')
336
- end
337
- end
338
-
339
- context "when passed an Array" do
340
- it "should emit a list" do
341
- expect(subject.emit([1,2,3,'foo'])).to eq("(1,2,3,'foo')")
342
- end
343
- end
344
-
345
- context "when passed a Hash" do
346
- it "should emit a list of assignments" do
347
- expect(subject.emit(x: 1, y: 2)).to eq('x=1,y=2')
348
- end
349
- end
350
-
351
- context "when passed a BinaryExpr" do
352
- let(:expr) { Ronin::Code::SQL::BinaryExpr.new(:id,:"=",1) }
353
-
354
- it "should emit an expression" do
355
- expect(subject.emit(expr)).to eq('id=1')
356
- end
357
- end
358
-
359
- context "when passed a UnaryExpr" do
360
- let(:expr) { Ronin::Code::SQL::UnaryExpr.new(:NOT,:admin) }
361
-
362
- it "should emit an expression" do
363
- expect(subject.emit(expr)).to eq('NOT admin')
364
- end
365
- end
366
-
367
- context "when passed a Function" do
368
- let(:func) { Ronin::Code::SQL::Function.new(:MAX,1,2) }
369
-
370
- it "should emit the function" do
371
- expect(subject.emit(func)).to eq('MAX(1,2)')
372
- end
373
- end
374
-
375
- context "when passed a Statment" do
376
- let(:stmt) { Ronin::Code::SQL::Statement.new(:SELECT,1) }
377
-
378
- it "should emit a statement" do
379
- expect(subject.emit(stmt)).to eq('SELECT 1')
380
- end
381
- end
382
-
383
- context "when the object responds to #to_sql" do
384
- let(:object) { double(:sql_object) }
385
- let(:sql) { "EXEC sp_configure 'xp_cmdshell', 0;" }
386
-
387
- it "should call #to_sql" do
388
- allow(object).to receive(:to_sql).and_return(sql)
389
-
390
- expect(subject.emit(object)).to eq(sql)
391
- end
392
- end
393
-
394
- context "otherwise" do
395
- let(:object) { Object.new }
396
-
397
- it "should raise an ArgumentError" do
398
- expect {
399
- subject.emit(object)
400
- }.to raise_error(ArgumentError)
401
- end
402
- end
403
- end
404
-
405
- describe "#emit_clause" do
406
- let(:clause) { Ronin::Code::SQL::Clause.new(:"NOT INDEXED") }
407
-
408
- it "should emit the clause keyword" do
409
- expect(subject.emit_clause(clause)).to eq("NOT INDEXED")
410
- end
411
-
412
- context "with an argument" do
413
- let(:argument) { 100 }
414
- let(:clause) { Ronin::Code::SQL::Clause.new(:LIMIT,argument) }
415
-
416
- it "should also emit the clause argument" do
417
- expect(subject.emit_clause(clause)).to eq("LIMIT #{argument}")
418
- end
419
- end
420
-
421
- context "with custom :space" do
422
- subject { described_class.new(space: '/**/') }
423
-
424
- let(:clause) { Ronin::Code::SQL::Clause.new(:LIMIT,100) }
425
-
426
- it "should emit the custom white-space deliminater" do
427
- expect(subject.emit_clause(clause)).to eq('LIMIT/**/100')
428
- end
429
- end
430
- end
431
-
432
- describe "#emit_clauses" do
433
- let(:clauses) do
434
- [
435
- Ronin::Code::SQL::Clause.new(:LIMIT, 100),
436
- Ronin::Code::SQL::Clause.new(:OFFSET, 10)
437
- ]
438
- end
439
-
440
- it "should emit multiple clauses" do
441
- expect(subject.emit_clauses(clauses)).to eq('LIMIT 100 OFFSET 10')
442
- end
443
-
444
- context "with custom :space" do
445
- subject { described_class.new(space: '/**/') }
446
-
447
- it "should emit the custom white-space deliminater" do
448
- expect(subject.emit_clauses(clauses)).to eq('LIMIT/**/100/**/OFFSET/**/10')
449
- end
450
- end
451
- end
452
-
453
- describe "#emit_statement" do
454
- subject { described_class.new(case: :lower) }
455
-
456
- context "without an argument" do
457
- let(:stmt) { Ronin::Code::SQL::Statement.new(:SELECT) }
458
-
459
- it "should emit the statment keyword" do
460
- expect(subject.emit_statement(stmt)).to eq('select')
461
- end
462
- end
463
-
464
- context "with an argument" do
465
- let(:stmt) { Ronin::Code::SQL::Statement.new(:SELECT,1) }
466
-
467
- it "should emit the statment argument" do
468
- expect(subject.emit_statement(stmt)).to eq('select 1')
469
- end
470
-
471
- context "when the argument is an Array" do
472
- let(:stmt) { Ronin::Code::SQL::Statement.new(:SELECT,[1,2,3]) }
473
-
474
- it "should emit a list" do
475
- expect(subject.emit_statement(stmt)).to eq('select (1,2,3)')
476
- end
477
-
478
- context "with only one element" do
479
- let(:stmt) { Ronin::Code::SQL::Statement.new(:SELECT,[1]) }
480
-
481
- it "should emit the element" do
482
- expect(subject.emit_statement(stmt)).to eq('select 1')
483
- end
484
- end
485
- end
486
-
487
- context "with custom :space" do
488
- subject { described_class.new(case: :lower, space: '/**/') }
489
-
490
- it "should emit the custom white-space deliminater" do
491
- expect(subject.emit_statement(stmt)).to eq('select/**/1')
492
- end
493
- end
494
- end
495
-
496
- context "with clauses" do
497
- let(:stmt) { Ronin::Code::SQL::Statement.new(:SELECT,1).offset(1).limit(100) }
498
-
499
- it "should emit the statment argument" do
500
- expect(subject.emit_statement(stmt)).to eq('select 1 offset 1 limit 100')
501
- end
502
-
503
- context "with custom :space" do
504
- subject { described_class.new(case: :lower, space: '/**/') }
505
-
506
- it "should emit the custom white-space deliminater" do
507
- expect(subject.emit_statement(stmt)).to eq('select/**/1/**/offset/**/1/**/limit/**/100')
508
- end
509
- end
510
- end
511
- end
512
-
513
- describe "#emit_statement_list" do
514
- let(:stmts) do
515
- sql = Ronin::Code::SQL::StatementList.new
516
- sql << Ronin::Code::SQL::Statement.new(:SELECT, 1)
517
- sql << Ronin::Code::SQL::Statement.new([:DROP, :TABLE], :users)
518
- sql
519
- end
520
-
521
- it "should emit multiple statements separated by '; '" do
522
- expect(subject.emit_statement_list(stmts)).to eq('SELECT 1; DROP TABLE users')
523
- end
524
-
525
- context "with custom :space" do
526
- subject { described_class.new(space: '/**/') }
527
-
528
- it "should emit the custom white-space deliminater" do
529
- expect(subject.emit_statement_list(stmts)).to eq('SELECT/**/1;/**/DROP/**/TABLE/**/users')
530
- end
531
- end
532
- end
533
- end
@@ -1,103 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/code/sql/field'
3
-
4
- describe Ronin::Code::SQL::Field do
5
- describe "#initialize" do
6
- it "should convert name to a String" do
7
- expect(described_class.new(:table).name).to eq('table')
8
- end
9
-
10
- it "should default parent to nil" do
11
- expect(described_class.new('table').parent).to be_nil
12
- end
13
- end
14
-
15
- describe "parse" do
16
- context "when passed a single field" do
17
- let(:name) { "column" }
18
-
19
- subject { described_class.parse(name) }
20
-
21
- it "should parse the field name" do
22
- expect(subject.name).to eq(name)
23
- end
24
-
25
- it "should not have a parent" do
26
- expect(subject.parent).to be_nil
27
- end
28
- end
29
-
30
- context "when parsing multiple fields" do
31
- let(:parent) { "table" }
32
- let(:name) { "column" }
33
-
34
- subject { described_class.parse("#{parent}.#{name}") }
35
-
36
- it "should parse the field name" do
37
- expect(subject.name).to eq(name)
38
- end
39
-
40
- it "should parse the parent field" do
41
- expect(subject.parent.name).to eq(parent)
42
- end
43
- end
44
- end
45
-
46
- describe "#to_s" do
47
- context "when parent is nil" do
48
- let(:name) { "column" }
49
-
50
- subject { described_class.new(name) }
51
-
52
- it "should return the name" do
53
- expect(subject.to_s).to eq(name)
54
- end
55
- end
56
-
57
- context "when parent is set" do
58
- let(:parent) { "table" }
59
- let(:name) { "column" }
60
-
61
- subject { described_class.new(name,described_class.new(parent)) }
62
-
63
- it "should return the name" do
64
- expect(subject.to_s).to eq("#{parent}.#{name}")
65
- end
66
- end
67
- end
68
-
69
- describe "#method_missing" do
70
- context "at depth 1" do
71
- subject { described_class.new('table') }
72
-
73
- it "should allow accessing sub-fields" do
74
- expect(subject.column.name).to eq('column')
75
- end
76
- end
77
-
78
- context "at depth 2" do
79
- subject { described_class.new('table',described_class.new('db')) }
80
-
81
- it "should allow accessing sub-fields" do
82
- expect(subject.column.name).to eq('column')
83
- end
84
- end
85
-
86
- context "at depth 3" do
87
- subject do
88
- described_class.new(
89
- 'column',
90
- described_class.new(
91
- 'table', described_class.new('db')
92
- )
93
- )
94
- end
95
-
96
- it "should not allow accessing sub-fields" do
97
- expect {
98
- subject.column
99
- }.to raise_error(NoMethodError)
100
- end
101
- end
102
- end
103
- end
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
- require 'ronin/code/sql/fields'
3
-
4
- describe Ronin::Code::SQL::Fields do
5
- subject { Object.new.extend(described_class) }
6
-
7
- describe "#respond_to_missing?" do
8
- it "should return true" do
9
- expect(subject).to respond_to(:foo)
10
- end
11
- end
12
-
13
- it { expect(subject.to_ary).to be_nil }
14
-
15
- describe "#method_missing" do
16
- let(:name) { 'users' }
17
-
18
- context "when called with no arguments and no block" do
19
- it "should create a Field" do
20
- expect(subject.send(name).name).to eq(name)
21
- end
22
- end
23
-
24
- context "when called with arguments" do
25
- it "should raise a NoMethodError" do
26
- expect {
27
- subject.sned(name,1,2,3)
28
- }.to raise_error(NoMethodError)
29
- end
30
- end
31
-
32
- context "when called with a block" do
33
- it "should raise a NoMethodError" do
34
- expect {
35
- subject.sned(name) { 1 + 1 }
36
- }.to raise_error(NoMethodError)
37
- end
38
- end
39
- end
40
- end
@@ -1,30 +0,0 @@
1
- require 'spec_helper'
2
-
3
- shared_examples_for "Function" do |method,arguments=[],additional_arguments=[]|
4
- describe "##{method}" do
5
- let(:name) { method.upcase }
6
- let(:func) { subject.send(method,*arguments) }
7
-
8
- it "should create a #{method.upcase} function" do
9
- expect(func.name).to eq(name)
10
- end
11
-
12
- unless arguments.empty?
13
- it "should set the arguments" do
14
- expect(func.arguments).to eq(arguments)
15
- end
16
- end
17
-
18
- unless additional_arguments.empty?
19
- context "when passed additional arguments" do
20
- let(:func) { subject.send(method,*additional_arguments) }
21
-
22
- it "should set the arguments" do
23
- expect(func.arguments).to eq(additional_arguments)
24
- end
25
- end
26
- end
27
- end
28
- end
29
-
30
-