New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial import of CCL Unit Mocking. #7
Changes from 1 commit
cef8d08
68c6749
c94684c
2000026
0978f41
104b004
1b83053
5f2970b
db8d4b4
145d2d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
;; this is the test | ||
;;; public::mainForSubroutineB is the workhorse. It will be called instead of public::main because of "with replace" | ||
|
||
/** | ||
* Confirms that subroutineB returns "subroutineBTest" when it is passed "Test" | ||
* and "subroutineBSubroutine" when it is passed "Subroutine". | ||
*/ | ||
subroutine (testSubroutineB(null) = null) | ||
|
||
execute the_script:dba with replace("MAIN", MAINFORSUBROUTINEB) | ||
|
||
end | ||
|
||
subroutine (public::mainForSubroutineB(null) = null) | ||
declare b_string = vc with protect, noconstant("") | ||
|
||
set b_string = subroutineB("Test") | ||
set stat = cclutAssertVCEqual(CURREF, "testSubroutineB Test", b_string, "subroutineBTest") | ||
|
||
set b_string = subroutineB("Subroutine") | ||
set stat = cclutAssertVCEqual(CURREF, "testSubroutineB Subroutine", b_string, "subroutineBSubroutine") | ||
end;;;mainForSubroutineB | ||
|
||
;; this is the script to be tested | ||
|
||
drop program the_script:dba go | ||
create program the_script:dba | ||
|
||
record reply ( | ||
%i cclsource:status_block.inc | ||
) | ||
|
||
subroutine (PUBLIC::subroutineA(id = f8) = vc) | ||
call echo("subroutineA") | ||
;;; do stuff | ||
return("subroutineA") | ||
end | ||
|
||
subroutine (PUBLIC::subroutineB(name = vc) = vc) | ||
call echo("subroutineB") | ||
;;; do stuff | ||
return(concat("subroutineB", name)) | ||
end | ||
|
||
subroutine (PUBLIC::subroutineC(null) = null) | ||
call echo("subroutineC") | ||
;;; do stuff | ||
call subroutineD(null) | ||
end | ||
|
||
subroutine (PUBLIC::subroutineD(null) = null) | ||
call echo("subroutineD") | ||
end | ||
|
||
subroutine(PUBLIC::main(null) = null) | ||
declare a_string = vc with protect, noconstant("") | ||
declare b_string = vc with protect, noconstant("") | ||
set a_string = subroutineA(1.0) | ||
set b_string = subroutineB(a_string) | ||
call subroutineC(null) | ||
end | ||
|
||
call main(null) | ||
|
||
#exit_script | ||
;; script finalizer code can go here | ||
;; a PUBLIC::exitScript(null) subroutine that encapsulates this work could be created and called | ||
;; if it does something that should occur for some unit tests. | ||
end go |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
;;; put the following script definition in a .prg file and compile it | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the introductory example for demonstrating the mocking api. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, technically the CCLUTMOCKING.md is supposed to be the introduction for mocking. I realize that people can read things in any order and hop around as they please, but this document links to it first, and there's a full example in there using tables. Would it be more helpful if I said: Or if that's not acceptable, should I just move the example from CCLUTMOCKING here (or create a separate file for it (forgot to do that on the last commit) and link to it from both spots)? This section was more based on the introduction of what mocking is than the full suite, and I was reusing your example from your blog which was just mocking the script, so my preference would be to clearly state that it's a basic example, or just reuse the CCLUTMOCKING example rather than having a separate example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it would make more sense if the stated purpose were "how to accomplish a basic 'with replace' while using the mocking framework" opposed to "demonstrate the mocking api". It would also be good to modify "Details on the API can be found....." to say "Example usage and details...". Otherwise this still feels like the first offering of any example usage of the mocking api. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, I'll make those changes. |
||
|
||
|
||
drop program mock_other_script go | ||
create program mock_other_script | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe document this as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do. |
||
free record reply | ||
set stat = copyrec(mock_other_script_reply, reply, 1) | ||
end go | ||
|
||
;;; put the following functions in a test case (.inc) | ||
|
||
/** | ||
* Test myFunction when other_script returns zero items | ||
*/ | ||
subroutine (testMyFunctionOtherScriptZero(null) = null) | ||
record mock_other_script_reply ( | ||
1 qual [*] | ||
2 id = f8 | ||
%i cclsource:status_block.inc | ||
) with protect | ||
|
||
set mock_other_script_reply->status_data->status = "Z" | ||
|
||
call cclutAddMockImplementation("OTHER_SCRIPT", "mock_other_script") | ||
call cclutExecuteProgramWithMocks("the_script", "") | ||
|
||
;assert things here | ||
end ;;;testMyFunctionZero | ||
|
||
/** | ||
* Test myFunction when other_script returns more than five items | ||
*/ | ||
subroutine (testMyFunctionOtherScriptMoreThanTen(null) = null) | ||
record mock_other_script_reply ( | ||
1 qual [*] | ||
2 id = f8 | ||
%i cclsource:status_block.inc | ||
) with protect | ||
|
||
set mock_other_script_reply->status_data->status = "S" | ||
set stat = alterlist(mock_other_script_reply->qual, 6) | ||
|
||
declare idx = i4 with protect, noconstant(0) | ||
for (idx = 1 to 6) | ||
set mock_other_script_reply->qual[idx].id = idx | ||
endfor | ||
|
||
call cclutAddMockImplementation("OTHER_SCRIPT", "mock_other_script") | ||
call cclutExecuteProgramWithMocks("the_script", "") | ||
|
||
;assert things here | ||
end ;;;testMyFunctionMoreThanTen | ||
|
||
/** | ||
* Test myFunction when other_script fails | ||
*/ | ||
subroutine (testMyFunctionOtherScriptFail(null) = null) | ||
record mock_other_script_reply ( | ||
1 qual [*] | ||
2 id = f8 | ||
%i cclsource:status_block.inc | ||
) with protect | ||
|
||
set mock_other_script_reply->status_data->status = "F" | ||
|
||
call cclutAddMockImplementation("OTHER_SCRIPT", "mock_other_script") | ||
call cclutExecuteProgramWithMocks("the_script", "") | ||
|
||
;assert things here | ||
end ;;;testMyFunctionOtherScriptFail |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/** | ||
* Executes a test knowing that every call to getPersonName(id) will return "Bob Marley". | ||
*/ | ||
subroutine (testGetNameReturnsBobMarley(null) = null) | ||
declare otherScriptCallCount = i4 with protect, noconstant(0) | ||
|
||
call cclutExecuteProgramWithMocks("the_script", "", "testGetNameReturnsBobMarley") | ||
|
||
; assert stuff here | ||
end | ||
subroutine (testGetNameReturnsBobMarley::getPersonName(id = f8) = vc) | ||
return ("Bob Marley") | ||
end ;;;testGetNameReturnsBobMarley |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
;;; here is the script | ||
|
||
drop program the_script go | ||
create program the_script | ||
execute other_script 4, 5 | ||
execute other_script 3, 2 | ||
execute other_script 0, 1 | ||
end go | ||
|
||
|
||
;;; put this definition in a .prg file and compile it | ||
|
||
drop program mock_other_script go | ||
create program mock_other_script | ||
prompt "param 1", "param 2" with param1, param2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. /** There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will change. |
||
|
||
set otherScriptCallCount = otherScriptCallCount + 1 | ||
call validateOtherScriptParams($param1, $param2) | ||
end go | ||
|
||
;;; put this functions in a test case (.inc) | ||
|
||
/** | ||
* confirms that the script executes other_script exactly three times passing in (4, 5) then (3, 2) then (0, 1) | ||
*/ | ||
subroutine (testOtherScriptCalledThreeTimes(null) = null) | ||
declare otherScriptCallCount = i4 with protect, noconstant(0) | ||
|
||
call cclutAddMockImplementation("OTHER_SCRIPT", "mock_other_script") | ||
call cclutExecuteProgramWithMocks("the_script", "") | ||
|
||
set stat = cclutAssertI4Equal(CURREF, "testMyFunction_6_9 a", otherScriptCallCount, 3) | ||
end ;;;testMyFunctionZero | ||
|
||
subroutine (validateOtherScriptParams(p1 = i4, p2 = i4) = null) | ||
case (otherScriptCallCount) | ||
of 1: | ||
set stat = cclutAssertI4Equal(CURREF, "validateOtherScriptParams 1 a", p1, 4) | ||
set stat = cclutAssertI4Equal(CURREF, "validateOtherScriptParams 1 b", p2, 5) | ||
of 2: | ||
set stat = cclutAssertI4Equal(CURREF, "validateOtherScriptParams 2 a", p1, 3) | ||
set stat = cclutAssertI4Equal(CURREF, "validateOtherScriptParams 2 b", p2, 2) | ||
of 3: | ||
set stat = cclutAssertI4Equal(CURREF, "validateOtherScriptParams 3 a", p1, 0) | ||
set stat = cclutAssertI4Equal(CURREF, "validateOtherScriptParams 3 b", p2, 1) | ||
endcase | ||
end ;;;validateOtherScriptParams |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,4 +78,7 @@ end | |
|
||
call internalSubroutine(null) | ||
|
||
set internalVariable = 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose internalVariable and internalRecord->item are used to confirm that the SUT was actually executed. Note that the adjective "internal" doesn't really fit here. Maybe "external" or "provided". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Actually, I was doing it to comply with the statement from here:
Although reading it again, it sounds like you wanted the declarations in SUT. Do you want me to just update these tests to move the declarations inside SUT? And, if so, should I leave it as "internal" or do you still want "external"/"provided"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct. To do this, the _namespace test would declare competing mock::rec and mock::var that would be updated rather than the public::rec and pulic::var declared by SUT. If SUT declares the public:: versions 'with protect', they will fall out of scope after the script returns (i.e., they will fail a validate check) yet the values will be set on the mock:: versions declared by the test. The 'with persistscript' check needs to be performed on yet some other thing declared within SUT and only needs to be checked by one test after SUT returns I imagine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. I'll update the _namespace test and update the _happy test to include a persistscript check. |
||
set internalRecord->item = 1 | ||
|
||
end go |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move line 2 into (at the end of) the documentation for testSubroutineB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing.