<commit_before>//
//  SwiftForthTests.swift
//  SwiftForthTests
//
//  Created by <NAME> on 17/07/14.
//  Copyright (c) 2014 <NAME>. All rights reserved.
//

import Foundation
import XCTest

class ErrorCounter : ErrorHandler {
    var errors = 0

    func HandleError(msg: String) {
        ++errors
    }
}

class FailOnError : ErrorHandler {
    func HandleError(msg: String) {
        XCTFail("unexpected evaluator error")
    }
}

class EvaluatorTest : XCTestCase {
    var evaluator = Evaluator()
    var errors = 0
    
    override func setUp() {
        evaluator.setErrorHandler(FailOnError())
    }

    func checkEvalSuccess(input: String, expectedOutput: String) {
        let result = evaluator.eval(input)
        XCTAssertEqual(Result.OK, result)

        let actualOutput = evaluator.readAndResetOutput()
        XCTAssertEqual(expectedOutput, actualOutput)
    }
    
    func checkEvalFailure(input: String) {
        let counter = ErrorCounter()
        evaluator.setErrorHandler(counter)
        let result = evaluator.eval(input)
        XCTAssertEqual(Result.KO, result)
        XCTAssert(counter.errors > 0)

        // Check compiler reset to correct state.
        checkEvalSuccess(": foo 42 ; foo .", expectedOutput: "42 ")
    }
    
    func testDotOnEmptyStack() {
        checkEvalFailure(".")
    }

    func testOnePlusTwo() {
        checkEvalSuccess("1 2 + .", expectedOutput: "3 ")
    }
    
    func testOnePlusTwoPlusThree() {
        checkEvalSuccess("1 2 + 3 + .", expectedOutput: "6 ")
    }

    func testAddWithoutOperand() {
        checkEvalFailure("+")
    }
    
    func testAddWithSingleOperand() {
        checkEvalFailure("1 +")
    }
    
    func testConstant() {
        checkEvalSuccess(": k 42 ;", expectedOutput: "")
        checkEvalSuccess("k 1 + .", expectedOutput: "43 ")
    }
    
    func testUnknownWord() {
        checkEvalFailure("foo")
    }
    
    func testLeaf() {
        checkEvalSuccess(": leaf 1 2 + ;", expectedOutput: "")
        checkEvalSuccess("leaf 1 + .", expectedOutput: "4 ")
    }
    
    func testNonLeaf() {
        checkEvalSuccess(": leaf 1 2 + ;", expectedOutput: "")
        checkEvalSuccess(": nonleaf 1 leaf + ;", expectedOutput: "")
        checkEvalSuccess("nonleaf 1 + .", expectedOutput: "5 ")
    }

    func testNumberAfterColon() {
        checkEvalFailure(": 1 2 ;")
    }
    
    func testSemicolonAfterColon() {
        checkEvalFailure(": ;")
    }
    
    func testSemicolonWithoutColon() {
        checkEvalFailure(";")
    }
    
    func testIfNotTaken() {
        checkEvalSuccess("10 0 IF 20 THEN .", expectedOutput: "10 ")
    }
    
    func testIfTaken() {
        checkEvalSuccess("10 1 IF 20 THEN .", expectedOutput: "20 ")
    }

    func testNestedIfNotTaken() {
        checkEvalSuccess("10 1 IF 0 IF 20 THEN THEN .", expectedOutput: "10 ")
    }

    func testNestedIfTaken() {
        checkEvalSuccess("10 1 IF 1 IF 20 THEN THEN .", expectedOutput: "20 ")
    }
    
    func testElseTaken() {
        checkEvalSuccess("10 0 IF 20 ELSE 30 THEN .", expectedOutput: "30 ")
    }

    func testElseNotTaken() {
        checkEvalSuccess("10 1 IF 20 ELSE 30 THEN .", expectedOutput: "20 ")
    }
    
    func testUnterminatedIfInDefinition() {
        checkEvalFailure(": foo 1 IF 20 ELSE 30 ;")
    }

    func testElseWithoutIf() {
        checkEvalFailure("ELSE")
    }
    
    func testThenWithoutIf() {
        checkEvalFailure("THEN")
    }
    
    func testEmit() {
        checkEvalSuccess("65 EMIT", expectedOutput: "A")
    }
    
    func testEmitEmptyStack() {
        checkEvalFailure("EMIT")
    }

    func testCR() {
        checkEvalSuccess("CR", expectedOutput: "\r")
    }
}

class DictionaryTest : XCTestCase {
    var dict = Dictionary()
    
    func testEmpty() {
        XCTAssert(!dict["foo"])
    }
    
    func testAddAndLookup() {
        dict.appendPhrase("a", phrase: [.Nop])
        let def = dict["a"]
        XCTAssert(def && def!.name == "a")
    }
}<commit_msg>refactor add tests<commit_after>//
//  SwiftForthTests.swift
//  SwiftForthTests
//
//  Created by <NAME> on 17/07/14.
//  Copyright (c) 2014 <NAME>. All rights reserved.
//

import Foundation
import XCTest

class ErrorCounter : ErrorHandler {
    var errors = 0

    func HandleError(msg: String) {
        ++errors
    }
}

class FailOnError : ErrorHandler {
    func HandleError(msg: String) {
        XCTFail("unexpected evaluator error")
    }
}

class EvaluatorTest : XCTestCase {
    var evaluator = Evaluator()
    var errors = 0
    
    override func setUp() {
        evaluator.setErrorHandler(FailOnError())
    }

    func checkEvalSuccess(input: String, expectedOutput: String) {
        let result = evaluator.eval(input)
        XCTAssertEqual(Result.OK, result)

        let actualOutput = evaluator.readAndResetOutput()
        XCTAssertEqual(expectedOutput, actualOutput)
    }
    
    func checkEvalFailure(input: String) {
        let counter = ErrorCounter()
        evaluator.setErrorHandler(counter)
        let result = evaluator.eval(input)
        XCTAssertEqual(Result.KO, result)
        XCTAssert(counter.errors > 0)

        // Check compiler reset to correct state.
        checkEvalSuccess(": foo 42 ; foo .", expectedOutput: "42 ")
    }
    
    func testDotOnEmptyStack() {
        checkEvalFailure(".")
    }

    func testConstant() {
        checkEvalSuccess(": k 42 ;", expectedOutput: "")
        checkEvalSuccess("k 1 + .", expectedOutput: "43 ")
    }
    
    func testUnknownWord() {
        checkEvalFailure("foo")
    }
    
    func testLeaf() {
        checkEvalSuccess(": leaf 1 2 + ;", expectedOutput: "")
        checkEvalSuccess("leaf 1 + .", expectedOutput: "4 ")
    }
    
    func testNonLeaf() {
        checkEvalSuccess(": leaf 1 2 + ;", expectedOutput: "")
        checkEvalSuccess(": nonleaf 1 leaf + ;", expectedOutput: "")
        checkEvalSuccess("nonleaf 1 + .", expectedOutput: "5 ")
    }

    func testNumberAfterColon() {
        checkEvalFailure(": 1 2 ;")
    }
    
    func testSemicolonAfterColon() {
        checkEvalFailure(": ;")
    }
    
    func testSemicolonWithoutColon() {
        checkEvalFailure(";")
    }
    
    func testIfNotTaken() {
        checkEvalSuccess("10 0 IF 20 THEN .", expectedOutput: "10 ")
    }
    
    func testIfTaken() {
        checkEvalSuccess("10 1 IF 20 THEN .", expectedOutput: "20 ")
    }

    func testNestedIfNotTaken() {
        checkEvalSuccess("10 1 IF 0 IF 20 THEN THEN .", expectedOutput: "10 ")
    }

    func testNestedIfTaken() {
        checkEvalSuccess("10 1 IF 1 IF 20 THEN THEN .", expectedOutput: "20 ")
    }
    
    func testElseTaken() {
        checkEvalSuccess("10 0 IF 20 ELSE 30 THEN .", expectedOutput: "30 ")
    }

    func testElseNotTaken() {
        checkEvalSuccess("10 1 IF 20 ELSE 30 THEN .", expectedOutput: "20 ")
    }
    
    func testUnterminatedIfInDefinition() {
        checkEvalFailure(": foo 1 IF 20 ELSE 30 ;")
    }

    func testElseWithoutIf() {
        checkEvalFailure("ELSE")
    }
    
    func testThenWithoutIf() {
        checkEvalFailure("THEN")
    }
    
    func testEmit() {
        checkEvalSuccess("65 EMIT", expectedOutput: "A")
    }
    
    func testEmitEmptyStack() {
        checkEvalFailure("EMIT")
    }

    func testCR() {
        checkEvalSuccess("CR", expectedOutput: "\r")
    }
}

class AddTest : EvaluatorTest {
    func testBinary() {
        checkEvalSuccess("1 2 + .", expectedOutput: "3 ")
    }
    
    func testTernary() {
        checkEvalSuccess("1 2 + 3 + .", expectedOutput: "6 ")
        checkEvalSuccess("1 2 3 + + .", expectedOutput: "6 ")
    }
    
    func testWithoutOperand() {
        checkEvalFailure("+")
    }
    
    func testWithSingleOperand() {
        checkEvalFailure("1 +")
    }
}

class DictionaryTest : XCTestCase {
    var dict = Dictionary()
    
    func testEmpty() {
        XCTAssert(!dict["foo"])
    }
    
    func testAddAndLookup() {
        dict.appendPhrase("a", phrase: [.Nop])
        let def = dict["a"]
        XCTAssert(def && def!.name == "a")
    }
}
{'fraction_non_alphanumeric': 0.12193619903929055, 'fraction_numerical': 0.024140904052223182, 'mean_word_length': 2.2994717594473792, 'pattern_counts': {'":': 16, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4875618', 'n_tokens_mistral': 2665, 'n_tokens_neox': 2472, 'n_words': 566}