Skip to content
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

fix spelling #239

Merged
merged 3 commits into from
Oct 4, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 25 additions & 26 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Simple, mocha-inspired, flexible, fun Brightscript test framework for ROKU apps
</h3>


## FEATrueS
## Features
- [Easy to integrate](#easy-to-integrate)
- [Simple, annotation-based, syntax for writing tests](#simple-syntax-for-writing-tests)
- [No need for special file names, or method names](#no-need-for-special-file-or-method-names)
Expand All @@ -18,7 +18,6 @@ Simple, mocha-inspired, flexible, fun Brightscript test framework for ROKU apps
- [Node specific assertions](#node-specific-assertions)
- [Parameterized testing](#parameterized-testing)
- [Mocks and stubs](#mocks-and-stubs)
- [Mocks node](#mocks-node)
- [Execute tests on scenegraph nodes](#execute-tests-on-scenegraph-nodes)
- [Incorporate your own util methods](#incorporate-your-own-util-methods)
- [Hook into your global setup mechanisms](#hook-into-your-global-setup-mechanisms)
Expand Down Expand Up @@ -260,15 +259,15 @@ The following annotations are supported.
| @beforeEach | Run before each test. Can be specified for the `@suite`, or for each `@it` group | |
| @afterEach | Run after each test. Can be specified for the `@suite`, or for each `@it` group | |
| @describe | Indicates a group of tests. Groupings improve readability. A group might denote various tests for a given method, or even an aspect of functionality | Name of the describe group, which is used in the test output |
| @it | Indicates a test. Must directly precede a function definition | The name of the test acse, which will be reported in the test output |
| @it | Indicates a test. Must directly precede a function definition | The name of the test case, which will be reported in the test output |
| @only | Precedes a Suite, Describe group, or it test, to indicate that _only that item_ should be executed. This can be used to rapidly filter out tests. Only other `@only` items will be run. | |
| @ignore | Precedes a suite, Describe group or it test, to indicate that that item should be ignored. If an `@ignore` tag is found before an item, then it will not be executed as part of the test run | |
| @params[p1,p2,...,p6] | Indicates a Parameterized test. Must come _after_ a `@it` annotation. Can accept up to 6 arguments, which are comma separated. When using parameterized tests, the test function signatrue _must_ accept the same number of arguments, and each of params statemens, must also have the same number of params | Up to 6 arguments can be any valid brightscript code, which can be parsed with an `eval` function |
| @ignoreParams[p1,p2,...,p6] | A Convenience tag, which makes it easy to temporarily _comment out_ params tests we do not want to run. | As per `@params` |
| @onlyParams[p1,p2,...,p6] | A Convenience tag, which makes it easy to temporarily _solor_ params, so you can run one or more of the params in a params block. Very useful for focusing on a failing test case | As per `@params` |
| @onlyParams[p1,p2,...,p6] | A Convenience tag, which makes it easy to temporarily run just one set of params, so you can run one or more of the params in a params block. Very useful for focusing on a failing test case | As per `@params` |
| @tags("one","two"..."n") | Allows indicating the tags to apply to the group,test or suite. This is a really effective way to categorise your test suite. These tags can be used to filter tests in your rooibos bsconfig options. | List of tag names to apply |
| @noatch | If present, will not catch errors for the test or suite it is placed on. This is handy when developing, and you want to debug the exact line on which an error occurred. | none |
| @noearlyexit | If present, will not exit a test on an assertion failure, which prevents crashes/skewed results. This annotation is mainly used for testing, such as testing rooibos framework itself. It is recommend that you _do not_ use this annotation. | none |
| @noCatch | If present, will not catch errors for the test or suite it is placed on. This is handy when developing, and you want to debug the exact line on which an error occurred. | none |
| @noEarlyexit | If present, will not exit a test on an assertion failure, which prevents crashes/skewed results. This annotation is mainly used for testing, such as testing rooibos framework itself. It is recommend that you _do not_ use this annotation. | none |
| @async | If present, on a test suite or test case (e.g. @it) indicates that the test will execute asynchronously. This will allow you to use observeField in your tests. The only argument is timeout in ms e.g. @async(2000). Default time out is 2000ms for a test, and 6000 for a test suite | max time in ms |


Expand Down Expand Up @@ -616,15 +615,15 @@ In all of these cases, you can use Rooibos's mocks and stubs in place of real me
### Mocks, Stubs and Fakes

#### Fakes
Fakes are objects, which you can use in place of real methods. They are invoked, receive parameters, and can return values, just like real methods. As far as the invokee is concerned, it _is_ the real method you intended to be executed in your code. Fakes are what Rooibos uses under the hood, to facilitate it's Stub and Mock implementations.
Fakes are objects, which you can use in place of real methods. They are invoked, receive parameters, and can return values, just like real methods. As far as the invoked function is concerned, it _is_ the real method you intended to be executed in your code. Fakes are what Rooibos uses under the hood, to facilitate it's Stub and Mock implementations.

#### Stubs
Stubs are Fakes which are not tracked. This means that you can execute your unit tests, using the fake methods; but Rooibos will not fail your tests if things were not as expected (i.e. wrong params, wrong number of invocations). These can be very handy for setting certain test conditions (i.e. you can create a fake network response that will return a specific result, which drives your test)

To create a stub, we use the `Stub` method:
To create a stub, we use the `stubCall` method:

```
function Stub(target, methodName, expectedInvocations = 1, expectedArgs = invalid, returnValue = invalid) as object
function stubCall(invocation, returnValue = invalid) as object
```

- The target is the object which will have it's method replaced,
Expand All @@ -636,8 +635,8 @@ function Stub(target, methodName, expectedInvocations = 1, expectedArgs = invali
##### A simple example
Given a ViewModel, named DetailsVM, which has a method LoadDetails, as such:
```
function LoadDetails()
isNetworkRequestExecuted = m.ExecuteNetRequest("http://my.data.com/get")
function loadDetails()
isNetworkRequestExecuted = m.executeNetRequest("http://my.data.com/get")
m.isLoading = isNetworkRequestExecuted
m.isShowingError = not isNetworkRequestExecuted
end function
Expand All @@ -646,26 +645,26 @@ end function
We can use a stub, to facilitate testing against the network layer

```
detailsVM = CreateDetailsVM()
detailsVM = createDetailsVM()
returnJson = {success:false}
m.Stub(detailsVM,"ExecuteNetRequest", invalid, returnJson)
m.stubCall(detailsVM.rexecuteNetRequest, returnJson)

detailsVM.LoadDetails()
detailsVM.loadDetails()

m.assertFalse(detailsVM.isLoading)
m.assertTrue(detailsVM.isShowingError)
```

In this case, our detailsVM object, will not actually call ExecuteNetRequests's source code; but will instead call a _fake_ (i.e fake method body), which can return predtermined values, or be later checked for invocation arg conformance.
In this case, our detailsVM object, will not actually call executeNetRequests's source code; but will instead call a _fake_ (i.e fake method body), which can return predtermined values, or be later checked for invocation arg conformance.

#### Mocks
Mocks are _expected_ fakes. Your code will invoke the method, as if it _is_ the real method; but the difference is that Rooibos will track the invoction of mocks, and if the method was not invoked in the manner you expected (i.e. with the expected parameters and the expected number of invocations) then a unit test failure will result.

We create mocks by using the methods:


- ExpectCalled(invocation, result)
- ExpectNotCalled(method)
- expectCalled(invocation, result)
- expectNotCalled(method)

These are advanced functions, using the rooibos plugin to greatly simplify mocking. Simply include the actual invocation you expect, or the method you don't expect to be called, and the framework does the rest.

Expand All @@ -690,9 +689,9 @@ For the regular class method variation, you can simply pass a pointer to the fun

Under the hood rooibos leverages these methods; but with the modern syntax you will not typicall interact with these methods.

- Expect - Creates a generic mock
- ExpectOnce - Creates a mock, which we expect to be called once _or can created individual overloaded calls to the same method_
- ExpectNone - Creates a mock, which we _never_ expect to be invoked
- expect - Creates a generic mock
- expectOnce - Creates a mock, which we expect to be called once _or can created individual overloaded calls to the same method_
- expectNone - Creates a mock, which we _never_ expect to be invoked


### Asserting mocks
Expand Down Expand Up @@ -748,7 +747,7 @@ You can save yourself a lot of time, and really think about and kick the tyres o
- Up to 15 arguments are supported on mocked methods
- You can have up to 24 mocks.

#### Expecting several calls to the same method, with verified invocation params
#### expecting several calls to the same method, with verified invocation params

You may wish to call the same method various times, and return different values, or check different arguments were invoked

Expand Down Expand Up @@ -784,7 +783,7 @@ Note, this feature is NOT available for @. invocations.

If you only care about *some* arguments, then you can use `m.ignoreValue` to instruct rooibos to not assert equality for the arguments you've ignored.

In the above example, the assertion will be satisfied with a mock confiugred thusly:
In the above example, the assertion will be satisfied with a mock configured thusly:

```m.expectCalled(myObj.myMethod("a", "b", m.ignoreValue), true)```

Expand All @@ -793,7 +792,7 @@ This will pass when `myMethod` is invoked with args: `"a", "b", "c"`, or `"a", "

#### Using matchers to assert mock invocation args

In addition to the other basic matchers described above, rooibos provides a set of pre-defined _any_ matchers, and a mechansim for you to provide custom matchers for any mock argument.
In addition to the other basic matchers described above, rooibos provides a set of pre-defined _any_ matchers, and a mechanism for you to provide custom matchers for any mock argument.

##### Built in matchers

Expand Down Expand Up @@ -843,7 +842,7 @@ And inline:

#### returning values from your mocks
Simply set your return value to a non-invalid value, to specify a return value.
You can also specify multiple return values, if you expect your mock to be executed multiple times, and would like to use different values. In that case, return a pobo, with the special key : `multiResult`. The value will be returned for each invocation - if the mock is invoked more than the number of return values, the last one is reutrned. e.g.
You can also specify multiple return values, if you expect your mock to be executed multiple times, and would like to use different values. In that case, return a pobo, with the special key : `multiResult`. The value will be returned for each invocation - if the mock is invoked more than the number of return values, the last one is returned. e.g.

```
m.expectCalled(obj.mockMethod(5), {"multiResult": ["one", 2, invalid, "last"]}, true)
Expand All @@ -866,7 +865,7 @@ As a sanity check, rooibos will expect a method to exist on an object before all

This behavior can be disabled by passing in the last argument of the mock/stub/fake function (`allowNonExistingMethods`) as `true`. In this case, rooibos will still log a warning; but you will be allowed to create the fake method.

This is handy for quickly creating mock dependencies with simple _pobos_ (plain old brightscript objects). e.g.
This is handy for quickly creating mock dependencies with simple aa objects. e.g.

```
videoService = {}
Expand Down Expand Up @@ -1056,7 +1055,7 @@ There are many articles on the benefits of TDD, and how to go about TDD, which y

Personally, I get great mileage doing TDD in roku by using MVVM pattern (I'm soon to release a lightweight MVVM framework). You can get more info on that [here](https://medium.com/flawless-app-stories/how-to-use-a-model-view-viewmodel-architectrue-for-ios-46963c67be1b) (for iOS), and ideas on how that benefits roku dev [here](https://medium.com/plexlabs/xml-code-good-times-rsg-application-b963f0cec01b)

I use these practices as much as possible becuase:
I use these practices as much as possible because:

1. Keeps my view and business logic separated
2. Tests are super fast to run (I generally run about 400 or so in each of my projects in < 5 seconds, and when running 1 test, turn around time is < 3 seconds)
Expand Down