Skip to content

Commit 7636860

Browse files
committed
Ensure that optional calls and strictly ordered calls play nicely together. Closes #12.
1 parent d90b9ac commit 7636860

File tree

4 files changed

+43
-8
lines changed

4 files changed

+43
-8
lines changed

rockspecs/mach-git-0.rockspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ build = {
1919
['mach.ExpectedCall'] = 'mach/ExpectedCall.lua',
2020
['mach.unexpected_call_error'] = 'mach/unexpected_call_error.lua',
2121
['mach.unexpected_args_error'] = 'mach/unexpected_args_error.lua',
22+
['mach.out_of_order_call_error'] = 'mach/out_of_order_call_error.lua',
2223
}
2324
}

spec/mach_spec.lua

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ describe('The mach library', function()
345345
end)
346346

347347
it('should not allow calls to happen out of order when and_then is used', function()
348-
should_fail_with('unexpected function call f2()', function()
348+
should_fail_with('out of order function call f2()', function()
349349
f1:should_be_called():
350350
and_then(f2:should_be_called()):
351351
when(function()
@@ -365,7 +365,7 @@ describe('The mach library', function()
365365
end)
366366

367367
it('should catch out of order calls when mixed with unordered calls', function()
368-
should_fail_with('unexpected function call f3()', function()
368+
should_fail_with('out of order function call f3()', function()
369369
f1:should_be_called():
370370
and_also(f2:should_be_called()):
371371
and_then(f3:should_be_called()):
@@ -390,6 +390,21 @@ describe('The mach library', function()
390390
end)
391391
end)
392392

393+
it('should allow a strictly ordered call to occur after a missing optional call', function()
394+
f1:may_be_called():and_then(f2:should_be_called()):when(function()
395+
f2()
396+
end)
397+
end)
398+
399+
it('should not allow order to be violated for an optional call', function()
400+
should_fail_with('unexpected function call f1()', function()
401+
f1:may_be_called():and_then(f2:should_be_called()):when(function()
402+
f2()
403+
f1()
404+
end)
405+
end)
406+
end)
407+
393408
it('should allow soft expectations to be called', function()
394409
f:may_be_called():when(function() f() end)
395410
end)

src/mach/Expectation.lua

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
local ExpectedCall = require 'mach.ExpectedCall'
22
local unexpected_call_error = require 'mach.unexpected_call_error'
33
local unexpected_args_error = require 'mach.unexpected_args_error'
4+
local out_of_order_call_error = require 'mach.out_of_order_call_error'
45

56
local expectation = {}
67
expectation.__index = expectation
@@ -42,16 +43,25 @@ function expectation:when(thunk)
4243
error('incomplete expectation', 2)
4344
end
4445

46+
local current = 1
47+
4548
local function called(m, name, args)
4649
local valid_function_found = false
50+
local incomplete_expectation_found = false
51+
52+
for i = current, #self._calls do
53+
local call = self._calls[i]
4754

48-
for i, call in ipairs(self._calls) do
4955
if call:function_matches(m) then
5056
valid_function_found = true
5157

5258
if call:args_match(args) then
53-
if call:has_fixed_order() and i > 1 then
54-
self._calls[i - 1]:fix_order()
59+
if call:has_fixed_order() and incomplete_expectation_found then
60+
out_of_order_call_error(name, args, 2)
61+
end
62+
63+
if call:has_fixed_order() then
64+
current = i
5565
end
5666

5767
table.remove(self._calls, i)
@@ -64,7 +74,9 @@ function expectation:when(thunk)
6474
end
6575
end
6676

67-
if call:has_fixed_order() then break end
77+
if call:is_required() then
78+
incomplete_expectation_found = true;
79+
end
6880
end
6981

7082
if not self._ignore_other_calls then
@@ -94,9 +106,8 @@ function expectation:after(thunk)
94106
end
95107

96108
function expectation:and_then(other)
97-
self._calls[#self._calls]:fix_order()
98-
99109
for _, call in ipairs(other._calls) do
110+
call:fix_order()
100111
table.insert(self._calls, call)
101112
end
102113

src/mach/out_of_order_call_error.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
return function(name, args, level)
2+
local arg_strings = {}
3+
for _, arg in ipairs(args) do
4+
table.insert(arg_strings, tostring(arg))
5+
end
6+
7+
error('out of order function call ' .. name .. '(' .. table.concat(arg_strings, ', ') .. ')', level + 1)
8+
end

0 commit comments

Comments
 (0)