-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* develop: Initial Import of Framework
- Loading branch information
Showing
12 changed files
with
414 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
# MonkeyMock | ||
# MonkeyTest | ||
|
||
A ConnectIQ mocking framework | ||
A ConnectIQ testing framework. | ||
|
||
## Description | ||
|
||
Class driven testing framework with support for Test suites and Mocks. Provides | ||
clean output of test results, and simplifies the process of writing good unit | ||
tests for ConnectIQ applications and libraries |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,13 @@ | ||
<!-- This is a generated file. It is highly recommended that you DO NOT edit this file. --><iq:manifest xmlns:iq="http://www.garmin.com/xml/connectiq" version="3"> | ||
<iq:barrel id="7c46f82e-9b95-4cb1-9c8e-126ebe2f5f10" module="MonkeyMock" version="0.0.0"> | ||
<!-- This is a generated file. It is highly recommended that you DO NOT edit this file. --> | ||
<iq:manifest xmlns:iq="http://www.garmin.com/xml/connectiq" version="3"> | ||
<iq:barrel id="7c46f82e9b954cb19c8e126ebe2f5f10" module="MonkeyTest" version="0.0.1"> | ||
<iq:products/> | ||
<iq:permissions/> | ||
<iq:languages/> | ||
<iq:barrels/> | ||
<iq:annotations/> | ||
<iq:annotations> | ||
<iq:annotation>Mocks</iq:annotation> | ||
<iq:annotation>Tests</iq:annotation> | ||
</iq:annotations> | ||
</iq:barrel> | ||
</iq:manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
APP_NAME="MonkeyInject" | ||
APP_NAME="MonkeyTest" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
project.manifest = manifest.xml | ||
base.sourcePath = source | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//! ExpectationException.mc | ||
//! | ||
//! Copyright Greg Caufield 2020 | ||
|
||
using MonkeyTest.Tests; | ||
|
||
module MonkeyTest { | ||
(:Mocks) | ||
module Mocks{ | ||
class ExpectationException extends Tests.TestException { | ||
function initialize() { | ||
TestException.initialize("Expectation not met"); | ||
} | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//! UnexpectedInvocationException.mc | ||
//! | ||
//! Copyright Greg Caufield 2020 | ||
|
||
using MonkeyTest.Tests; | ||
|
||
module MonkeyTest { | ||
(:Mocks) | ||
module Mocks { | ||
//! Exception for a function invocation that was not declared | ||
class UnexpectedInvocationException extends Tests.TestException { | ||
function initialize(functionName) { | ||
TestException.initialize(""); | ||
self.mMessage = "Unexpected Invocation of function " + functionName; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
//! Expectation.mc | ||
//! | ||
//! Copyright Greg Caufield 2020 | ||
|
||
module MonkeyTest { | ||
|
||
(:Mocks) | ||
module Mocks { | ||
//! Represents an expectation that has been set on a mock | ||
class Expectation { | ||
private var _expectedArgs = null; | ||
private var _timesExpected = 1; | ||
private var _timesCalled = 0; | ||
|
||
function initialize() { | ||
} | ||
|
||
function withArgs(args) { | ||
_expectedArgs = []; | ||
_expectedArgs.addAll(args); | ||
return self; | ||
} | ||
|
||
function isSaturated() { | ||
if(_timesExpected == null) { | ||
// If times expected is null then we don't care how many times this is | ||
// called. | ||
return false; | ||
} | ||
|
||
if((_timesCalled < _timesExpected)) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
function times(num) { | ||
_timesExpected = num; | ||
} | ||
|
||
function isMatch(args) { | ||
if(_expectedArgs == null) { | ||
// No args specified, all calls match. | ||
return true; | ||
} | ||
|
||
if(args.size() != _expectedArgs.size()) { | ||
return false; | ||
} | ||
|
||
for(var i = 0; i < args.size(); i++) { | ||
var expectedArg = _expectedArgs[i]; | ||
|
||
if(expectedArg == :any) { | ||
continue; | ||
} | ||
else if((expectedArg instanceof Matcher) && !expectedArg.isMatch(args[i])) { | ||
// Matcher check failed | ||
return false; | ||
} | ||
else if( expectedArg != args[i]) { | ||
return false; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
function execute(args) { | ||
if(isSaturated()) { | ||
// TODO (caufield) create an exception for this | ||
// Error Expectation Over Saturated | ||
throw new ExpectationException(); | ||
} | ||
|
||
_timesCalled++; | ||
} | ||
|
||
function verify() { | ||
if((_timesExpected != null) && (_timesExpected != _timesCalled)) { | ||
throw new ExpectationException(); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
//! Matcher.mc | ||
//! | ||
//! Copyright Greg Caufield 2020 | ||
|
||
module MonkeyTest { | ||
(:Mocks) | ||
module Mocks { | ||
class Matcher { | ||
function isMatch(other) { | ||
return false; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
//! Mock.mc | ||
//! | ||
//! Copyright Greg Caufield 2020 | ||
using Toybox.System; | ||
|
||
module MonkeyTest { | ||
|
||
(:Mocks) | ||
module Mocks { | ||
enum { | ||
MOCK_TYPE_NICE, | ||
MOCK_TYPE_NAGGY, | ||
MOCK_TYPE_STRICT | ||
} | ||
|
||
//! Base class for Mock Classes | ||
class Mock { | ||
private var _expectations = {}; | ||
private var _type; | ||
|
||
public function initialize(mockType) { | ||
_type = mockType; | ||
} | ||
|
||
public function expect(key) { | ||
var expectation = new Expectation(); | ||
|
||
if(!_expectations.hasKey(key)) { | ||
_expectations[key] = []; | ||
} | ||
|
||
_expectations[key].add(expectation); | ||
return expectation; | ||
} | ||
|
||
public function verifyAndClear() { | ||
var keys = _expectations.keys(); | ||
|
||
for(var i = 0; i < keys.size(); i++) { | ||
var expectations = _expectations[keys[i]]; | ||
for(var j = 0; j < expectations.size(); j++) { | ||
expectations[j].verify(); | ||
} | ||
} | ||
} | ||
|
||
protected function getFunctionName(key) { | ||
return "Unknown"; | ||
} | ||
|
||
//! Execute any expectations for the mock | ||
protected function execute(key, arguments) { | ||
var list = _expectations[key]; | ||
|
||
if(list == null) { | ||
switch(_type) { | ||
case MOCK_TYPE_NAGGY: | ||
System.println( | ||
"Unexpected call to Mock function " + getFunctionName(key)); | ||
return; | ||
case MOCK_TYPE_NICE: | ||
return; | ||
default: | ||
case MOCK_TYPE_STRICT: | ||
throw new UnexpectedInvocationException(getFunctionName(key)); | ||
} | ||
} | ||
|
||
var candidate = null; | ||
var match = false; | ||
|
||
for(var i = 0; i < list.size(); i++) { | ||
var expectation = list[i]; | ||
if(expectation.isMatch(arguments)) { | ||
match = true; | ||
if(expectation.isSaturated()) { | ||
candidate = expectation; | ||
continue; | ||
} | ||
|
||
// Unsaturated expectation that matches the arguments, | ||
// call it and clear any potential saturated candidates. | ||
expectation.execute(arguments); | ||
candidate = null; | ||
break; | ||
} | ||
} | ||
|
||
if(!match) { | ||
// TODO (caufield) Create an Exception for this | ||
// No Valid Expectation for Arguments | ||
throw new UnexpectedInvocationException(getFunctionName(key)); | ||
} | ||
|
||
// A saturated candidate was found, we will call it so that an error will | ||
// occur | ||
if(candidate != null) { | ||
candidate.execute(arguments); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//! TestException.mc | ||
//! | ||
//! Copyright Greg Caufield 2020 | ||
using Toybox.Lang; | ||
|
||
module MonkeyTest { | ||
(:Tests) | ||
module Tests { | ||
//! Base Exception for Failures from the test framework | ||
class TestException extends Lang.Exception { | ||
function initialize(msg) { | ||
Exception.initialize(); | ||
self.mMessage = msg; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
//! Test.mc | ||
//! | ||
//! Copyright Greg Caufield 2020 | ||
module MonkeyTest { | ||
|
||
(:Tests) | ||
module Tests { | ||
//! Base class of the Test Suite | ||
class Test { | ||
//! Child classes are expected to override this and return the suite name | ||
public function name() { | ||
return "Unknown"; | ||
} | ||
|
||
//! Child classes are expected to override this and return a dictionary | ||
//! mapping test symbols to thier names | ||
public function testList() { | ||
return {}; | ||
} | ||
|
||
function setUp() { | ||
} | ||
|
||
function tearDown() { | ||
} | ||
|
||
function expectEq(expected, actual) { | ||
if( actual != expected ) { | ||
throw new TestException("Expected equality. " + actual + " != " + expected); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.