<commit_before># AcceptanceMark

AcceptanceMark is a tool for running Acceptance Tests in Xcode, inspired by [Fitnesse](http://fitnesse.org/).

### Fitnesse advantages

* Easy to write business rules in tabular form in Markdown files.
* All shareholders can write Fitnesse tests.
* Convenient Test Report.

### Fitnesse disadvantages

* Does not integrate well with XCTest.
* Requires to run a separate server.
* Difficult to configure and run locally / on CI.

### The solution: AcceptanceMark

AcceptanceMark is the ideal tool to write Fitnesse-style acceptance tests that integrate seamlessly with XCTest:

* Write your tests inputs and expected values in markdown tables.
* AcceptanceMark generates XCTest test classes with **strong-typed input/outputs**. 
* Write test runners to evaluate the system under test with the given inputs.
* Run the chosen test target (Unit Tests or UI Tests both supported) and get a test report.

### How does this work?

Write your own test sets, like so:

```
image-tests.md

## Image Loading

| name:String   || loaded:Bool  |
| ------------- || ------------ |
| available.png || true         |
| missing.png   || false        |
```

_NOTE: The double-pipe syntax (`||`) is used as a delimiter between inputs and outputs. All test sets should have **exactly one** delimiter._

Run `amtool` as an XCode pre-compilation phase, which generates all the required test harness:

```swift
/*
 * File Auto-Generated by AcceptanceMark - DO NOT EDIT
 * input file: image-tests.md
 * generated file: ImageTests_ImageLoadingTests.swift
 *
 * Test specification
 *
 * ## Image Loading
 *
 * | name:String   || loaded:Bool  |
 * | ------------- || ------------ |
 * | available.png || true         |
 * | missing.png   || false        |
 *
 */

import XCTest
import AcceptanceMark

struct ImageTests_ImageLoadingInput {
    let name: String
}

struct ImageTests_ImageLoadingResult: Equatable {
    let loaded: Bool
}

protocol ImageTests_ImageLoadingTestRunnable {
    func run(input: ImageTests_ImageLoadingInput) throws -> ImageTests_ImageLoadingResult
}

class ImageTests_ImageLoadingTests: XCTestCase {
    
    var testRunner: ImageTests_ImageLoadingTestRunnable!
    
    override func setUp() {
        // MARK: Implement the ImageTests_ImageLoadingTestRunner() class!
        testRunner = ImageTests_ImageLoadingTestRunner()
    }
    
    func testImageLoading_0() {
        
        let input = ImageTests_ImageLoadingInput(name: "available.png")
        let expected = ImageTests_ImageLoadingResult(loaded: true)
        let result = try! testRunner.run(input: input)
        XCTAssertEqual(expected, result)
    }
    
    func testImageLoading_1() {
        
        let input = ImageTests_ImageLoadingInput(name: "missing.png")
        let expected = ImageTests_ImageLoadingResult(loaded: false)
        let result = try! testRunner.run(input: input)
        XCTAssertEqual(expected, result)
    }
}

func == (lhs: ImageTests_ImageLoadingResult, rhs: ImageTests_ImageLoadingResult) -> Bool {
    return lhs.loaded == rhs.loaded
}
```

Finally, write your test runner:

```swift
// User generated file. Put your test runner implementation here.
class ImageTests_ImageLoadingTestRunner: ImageTests_ImageLoadingTestRunnable {

    func run(input: ImageTests_ImageLoadingInput) throws -> ImageTests_ImageLoadingResult {
        // Your business logic here
        return ImageTests_ImageLoadingResult(loaded: true)
    }
}
```

### Notes

* Note the functional style of the test runner. It is simply a method that takes a stronly-typed input value, and returns a strongly-typed output value. **No state, no side effects**.

* As it is common for XCTests to have a `setUp()` method that is typically used to initialise each test with some state. While this _will_ be supported in **AcceptanceMark**, a more **functional style is preferred and encouraged**.

## FAQ

* _**Q**: I want to be able to have more than one table for each `.md` file. Is this possible?_
* **A**: Yes, as long as the file is structured as **Heading**, **Table**, **Heading**, **Table**, **...**, **AcceptanceMark** will generate multiple swift test files by using a `<filename>_<heading>.swift` naming convention. This way, each table gets its own swift classes all in one file. Note that **heading names should be unique per-file**. Whitespaces and punctuation will be stripped from headings.

* _**Q**: I want to preload application data/state for each test in a table (this is done with builders in Fitnesse). Can I do that?_
* **A**: This is in the roadmap. While the specification for this may change, one possible way of doing this is by allowing more than one table for each Heading, with the convention that the **last** table represents the input/output set, while all previous tables represent data to be preloaded.
Until this is implemented, all preloading can be done directly in the test runner's `setUp()` method.

```
## Image Loading

| Country:String | Code:Bool |
| -------------- | --------- |
| United Kingdom | GB        |
| Italy          | IT        |
| Germany        | DE        |
 
| name:String   || loaded:Bool  |
| ------------- || ------------ |
| available.png || true         |
| missing.png   || false        |<commit_msg>Clarification about state-less tests<commit_after># AcceptanceMark

AcceptanceMark is a tool for running Acceptance Tests in Xcode, inspired by [Fitnesse](http://fitnesse.org/).

### Fitnesse advantages

* Easy to write business rules in tabular form in Markdown files.
* All shareholders can write Fitnesse tests.
* Convenient Test Report.

### Fitnesse disadvantages

* Does not integrate well with XCTest.
* Requires to run a separate server.
* Difficult to configure and run locally / on CI.

### The solution: AcceptanceMark

AcceptanceMark is the ideal tool to write Fitnesse-style acceptance tests that integrate seamlessly with XCTest:

* Write your tests inputs and expected values in markdown tables.
* AcceptanceMark generates XCTest test classes with **strong-typed input/outputs**. 
* Write test runners to evaluate the system under test with the given inputs.
* Run the chosen test target (Unit Tests or UI Tests both supported) and get a test report.

### How does this work?

Write your own test sets, like so:

```
image-tests.md

## Image Loading

| name:String   || loaded:Bool  |
| ------------- || ------------ |
| available.png || true         |
| missing.png   || false        |
```

_NOTE: The double-pipe syntax (`||`) is used as a delimiter between inputs and outputs. All test sets should have **exactly one** delimiter._

Run `amtool` as an XCode pre-compilation phase, which generates all the required test harness:

```swift
/*
 * File Auto-Generated by AcceptanceMark - DO NOT EDIT
 * input file: image-tests.md
 * generated file: ImageTests_ImageLoadingTests.swift
 *
 * Test specification
 *
 * ## Image Loading
 *
 * | name:String   || loaded:Bool  |
 * | ------------- || ------------ |
 * | available.png || true         |
 * | missing.png   || false        |
 *
 */

import XCTest
import AcceptanceMark

struct ImageTests_ImageLoadingInput {
    let name: String
}

struct ImageTests_ImageLoadingResult: Equatable {
    let loaded: Bool
}

protocol ImageTests_ImageLoadingTestRunnable {
    func run(input: ImageTests_ImageLoadingInput) throws -> ImageTests_ImageLoadingResult
}

class ImageTests_ImageLoadingTests: XCTestCase {
    
    var testRunner: ImageTests_ImageLoadingTestRunnable!
    
    override func setUp() {
        // MARK: Implement the ImageTests_ImageLoadingTestRunner() class!
        testRunner = ImageTests_ImageLoadingTestRunner()
    }
    
    func testImageLoading_0() {
        
        let input = ImageTests_ImageLoadingInput(name: "available.png")
        let expected = ImageTests_ImageLoadingResult(loaded: true)
        let result = try! testRunner.run(input: input)
        XCTAssertEqual(expected, result)
    }
    
    func testImageLoading_1() {
        
        let input = ImageTests_ImageLoadingInput(name: "missing.png")
        let expected = ImageTests_ImageLoadingResult(loaded: false)
        let result = try! testRunner.run(input: input)
        XCTAssertEqual(expected, result)
    }
}

func == (lhs: ImageTests_ImageLoadingResult, rhs: ImageTests_ImageLoadingResult) -> Bool {
    return lhs.loaded == rhs.loaded
}
```

Finally, write your test runner:

```swift
// User generated file. Put your test runner implementation here.
class ImageTests_ImageLoadingTestRunner: ImageTests_ImageLoadingTestRunnable {

    func run(input: ImageTests_ImageLoadingInput) throws -> ImageTests_ImageLoadingResult {
        // Your business logic here
        return ImageTests_ImageLoadingResult(loaded: true)
    }
}
```

### Notes

* Note the functional style of the test runner. It is simply a method that takes a stronly-typed input value, and returns a strongly-typed output value. **No state, no side effects**.

* XCTests can have a `setUp()` method that is used to initialise all tests with the same initial state. While this _will_ be supported in **AcceptanceMark**, **state-less tests are preferred and encouraged here**.

## FAQ

* _**Q**: I want to be able to have more than one table for each `.md` file. Is this possible?_
* **A**: Yes, as long as the file is structured as **Heading**, **Table**, **Heading**, **Table**, **...**, **AcceptanceMark** will generate multiple swift test files by using a `<filename>_<heading>.swift` naming convention. This way, each table gets its own swift classes all in one file. Note that **heading names should be unique per-file**. Whitespaces and punctuation will be stripped from headings.

* _**Q**: I want to preload application data/state for each test in a table (this is done with builders in Fitnesse). Can I do that?_
* **A**: This is in the roadmap. While the specification for this may change, one possible way of doing this is by allowing more than one table for each Heading, with the convention that the **last** table represents the input/output set, while all previous tables represent data to be preloaded.
Until this is implemented, all preloading can be done directly in the test runner's `setUp()` method.

```
## Image Loading

| Country:String | Code:Bool |
| -------------- | --------- |
| United Kingdom | GB        |
| Italy          | IT        |
| Germany        | DE        |
 
| name:String   || loaded:Bool  |
| ------------- || ------------ |
| available.png || true         |
| missing.png   || false        |
{'fraction_non_alphanumeric': 0.10637287491689619, 'fraction_numerical': 0.0003799031247032007, 'mean_word_length': 3.324435318275154, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '433341', 'n_tokens_mistral': 2876, 'n_tokens_neox': 2783, 'n_words': 1128}