<commit_before>//
//  JSONParserTests.swift
//  FreddyTests
//
//  Created by <NAME> on 4/18/15.
//  Copyright © 2015 <NAME>. Licensed under MIT.
//

import XCTest
import Freddy

private func ==(lhs: JSONParser.Error, rhs: JSONParser.Error) -> Bool {
    switch (lhs, rhs) {
    case (.endOfStreamUnexpected, .endOfStreamUnexpected):
        return true
    case let (.endOfStreamGarbage(lOffset), .endOfStreamGarbage(rOffset)):
        return lOffset == rOffset
    case let (.exceededNestingLimit(lOffset), .exceededNestingLimit(rOffset)):
        return lOffset == rOffset
    case let (.valueInvalid(lOffset, lValue), .valueInvalid(rOffset, rValue)):
        return lOffset == rOffset && lValue == rValue
    case let (.controlCharacterUnrecognized(lOffset), .controlCharacterUnrecognized(rOffset)):
        return lOffset == rOffset
    case let (.unicodeEscapeInvalid(lOffset), .unicodeEscapeInvalid(rOffset)):
        return lOffset == rOffset
    case let (.literalNilMisspelled(lOffset), .literalNilMisspelled(rOffset)):
        return lOffset == rOffset
    case let (.literalTrueMisspelled(lOffset), .literalTrueMisspelled(rOffset)):
        return lOffset == rOffset
    case let (.literalFalseMisspelled(lOffset), .literalFalseMisspelled(rOffset)):
        return lOffset == rOffset
    case let (.collectionMissingSeparator(lOffset), .collectionMissingSeparator(rOffset)):
        return lOffset == rOffset
    case let (.dictionaryMissingKey(lOffset), .dictionaryMissingKey(rOffset)):
        return lOffset == rOffset
    case let (.numberMissingFractionalDigits(lOffset), .numberMissingFractionalDigits(rOffset)):
        return lOffset == rOffset
    case let (.numberSymbolMissingDigits(lOffset), .numberSymbolMissingDigits(rOffset)):
        return lOffset == rOffset
    case (_, _):
        return false
    }
}

class JSONParserTests: XCTestCase {

    func testThatParserThrowsAnErrorForAnEmptyData() {
        
        do {
            _ = try JSONParser.parse("")
            XCTFail("Unexpectedly did not throw an error") 
        } catch let error as JSONParser.Error {
            XCTAssert(error == JSONParser.Error.endOfStreamUnexpected)
        } catch {
            XCTFail("Unexpected error \(error)")
        }
    }

    func testThatParserThrowsErrorForInsufficientData() {
        let hex: [UInt8] = [0x7B]
        let data = Data(bytes: UnsafePointer<UInt8>(hex), count: hex.count)

        do {
            _ = try JSONParser.parse(utf8: data)
            XCTFail("Unexpectedly did not throw an error")
        } catch JSONParser.Error.endOfStreamUnexpected {
            return
        } catch {
            XCTFail("Incorrect error received.: \(error)")
        }
    }
    
    func testThatParserCompletesWithSingleZero() {
        guard let data = "0".data(using: String.Encoding.utf8) else {
            XCTFail("Cannot create data from string")
            return
        }

        do {
            _ = try JSONParser.parse(utf8: data)
        } catch {
            XCTFail("Unexpected error \(error)")
        }
    }

    func testThatParserCompletesWithBOMAndSingleZero() {
        let hex: [UInt8] = [0xEF, 0xBB, 0xBF, 0x30]
        let data = Data(bytes: UnsafePointer<UInt8>(hex), count: hex.count)

        do {
            _ = try JSONParser.parse(utf8: data)
        } catch {
            XCTFail("Unexpected error \(error)")
        }
    }

    func testThatParserUnderstandsNull() {
        let value = try! JSONParser.parse("null")
        XCTAssertEqual(value, JSON.null)
    }

    func testThatParserSkipsLeadingWhitespace() {
        let value = try! JSONParser.parse("   \t\r\nnull")
        XCTAssertEqual(value, JSON.null)
    }

    func testThatParserAllowsTrailingWhitespace() {
        let value = try! JSONParser.parse("null   ")
        XCTAssertEqual(value, JSON.null)
    }

    func testThatParserFailsWhenTrailingDataIsPresent() {
        do {
            _ = try JSONParser.parse("null   true")
        } catch JSONParser.Error.endOfStreamGarbage(let offset) {
            XCTAssertEqual(offset, 7)
        } catch {
            XCTFail("Unexpected error \(error)")
        }
    }

    func testThatParserUnderstandsTrue() {
        let value = try! JSONParser.parse("true")
        XCTAssertEqual(value, JSON.bool(true))
    }

    func testThatParserUnderstandsFalse() {
        let value = try! JSONParser.parse("false")
        XCTAssertEqual(value, JSON.bool(false))
    }

    func testThatParserUnderstandsStringsWithoutEscapes() {
        let string = "a b c d 😀 x y z"
        let value = try! JSONParser.parse("\"\(string)\"")
        XCTAssertEqual(value, JSON.string(string))
    }

    func testThatParserUnderstandsStringsWithEscapedCharacters() {
        let expect = " \" \\ / \n \r \t \u{000c} \u{0008} "
        let value = try! JSONParser.parse("\" \\\" \\\\ \\/ \\n \\r \\t \\f \\b \"")
        XCTAssertEqual(value, JSON.string(expect))
    }

    func testThatParserUnderstandsStringsWithEscapedUnicode() {
        // try 1-, 2-, and 3-byte UTF8 sequences
        let expect = "\u{0060}\u{012a}\u{12AB}"
        let value = try! JSONParser.parse("\"\\u0060\\u012a\\u12AB\"")
        XCTAssertEqual(value, JSON.string(expect))
    }

    func testThatParserFailsWhenIncompleteDataIsPresent() {
        for s in [" ", "[0,", "{\"\":"] {
            do {
                let value = try JSONParser.parse(" ")
                XCTFail("Unexpectedly parsed \(s) as \(value)")
            } catch JSONParser.Error.endOfStreamUnexpected {
                // expected error - do nothing<commit_msg>Fixing test testThatParserFailsWhenIncompleteDataIsPresent<commit_after>//
//  JSONParserTests.swift
//  FreddyTests
//
//  Created by <NAME> on 4/18/15.
//  Copyright © 2015 Big Nerd Ranch. Licensed under MIT.
//

import XCTest
import Freddy

private func ==(lhs: JSONParser.Error, rhs: JSONParser.Error) -> Bool {
    switch (lhs, rhs) {
    case (.endOfStreamUnexpected, .endOfStreamUnexpected):
        return true
    case let (.endOfStreamGarbage(lOffset), .endOfStreamGarbage(rOffset)):
        return lOffset == rOffset
    case let (.exceededNestingLimit(lOffset), .exceededNestingLimit(rOffset)):
        return lOffset == rOffset
    case let (.valueInvalid(lOffset, lValue), .valueInvalid(rOffset, rValue)):
        return lOffset == rOffset && lValue == rValue
    case let (.controlCharacterUnrecognized(lOffset), .controlCharacterUnrecognized(rOffset)):
        return lOffset == rOffset
    case let (.unicodeEscapeInvalid(lOffset), .unicodeEscapeInvalid(rOffset)):
        return lOffset == rOffset
    case let (.literalNilMisspelled(lOffset), .literalNilMisspelled(rOffset)):
        return lOffset == rOffset
    case let (.literalTrueMisspelled(lOffset), .literalTrueMisspelled(rOffset)):
        return lOffset == rOffset
    case let (.literalFalseMisspelled(lOffset), .literalFalseMisspelled(rOffset)):
        return lOffset == rOffset
    case let (.collectionMissingSeparator(lOffset), .collectionMissingSeparator(rOffset)):
        return lOffset == rOffset
    case let (.dictionaryMissingKey(lOffset), .dictionaryMissingKey(rOffset)):
        return lOffset == rOffset
    case let (.numberMissingFractionalDigits(lOffset), .numberMissingFractionalDigits(rOffset)):
        return lOffset == rOffset
    case let (.numberSymbolMissingDigits(lOffset), .numberSymbolMissingDigits(rOffset)):
        return lOffset == rOffset
    case (_, _):
        return false
    }
}

class JSONParserTests: XCTestCase {

    func testThatParserThrowsAnErrorForAnEmptyData() {
        
        do {
            _ = try JSONParser.parse("")
            XCTFail("Unexpectedly did not throw an error") 
        } catch let error as JSONParser.Error {
            XCTAssert(error == JSONParser.Error.endOfStreamUnexpected)
        } catch {
            XCTFail("Unexpected error \(error)")
        }
    }

    func testThatParserThrowsErrorForInsufficientData() {
        let hex: [UInt8] = [0x7B]
        let data = Data(bytes: UnsafePointer<UInt8>(hex), count: hex.count)

        do {
            _ = try JSONParser.parse(utf8: data)
            XCTFail("Unexpectedly did not throw an error")
        } catch JSONParser.Error.endOfStreamUnexpected {
            return
        } catch {
            XCTFail("Incorrect error received.: \(error)")
        }
    }
    
    func testThatParserCompletesWithSingleZero() {
        guard let data = "0".data(using: String.Encoding.utf8) else {
            XCTFail("Cannot create data from string")
            return
        }

        do {
            _ = try JSONParser.parse(utf8: data)
        } catch {
            XCTFail("Unexpected error \(error)")
        }
    }

    func testThatParserCompletesWithBOMAndSingleZero() {
        let hex: [UInt8] = [0xEF, 0xBB, 0xBF, 0x30]
        let data = Data(bytes: UnsafePointer<UInt8>(hex), count: hex.count)

        do {
            _ = try JSONParser.parse(utf8: data)
        } catch {
            XCTFail("Unexpected error \(error)")
        }
    }

    func testThatParserUnderstandsNull() {
        let value = try! JSONParser.parse("null")
        XCTAssertEqual(value, JSON.null)
    }

    func testThatParserSkipsLeadingWhitespace() {
        let value = try! JSONParser.parse("   \t\r\nnull")
        XCTAssertEqual(value, JSON.null)
    }

    func testThatParserAllowsTrailingWhitespace() {
        let value = try! JSONParser.parse("null   ")
        XCTAssertEqual(value, JSON.null)
    }

    func testThatParserFailsWhenTrailingDataIsPresent() {
        do {
            _ = try JSONParser.parse("null   true")
        } catch JSONParser.Error.endOfStreamGarbage(let offset) {
            XCTAssertEqual(offset, 7)
        } catch {
            XCTFail("Unexpected error \(error)")
        }
    }

    func testThatParserUnderstandsTrue() {
        let value = try! JSONParser.parse("true")
        XCTAssertEqual(value, JSON.bool(true))
    }

    func testThatParserUnderstandsFalse() {
        let value = try! JSONParser.parse("false")
        XCTAssertEqual(value, JSON.bool(false))
    }

    func testThatParserUnderstandsStringsWithoutEscapes() {
        let string = "a b c d 😀 x y z"
        let value = try! JSONParser.parse("\"\(string)\"")
        XCTAssertEqual(value, JSON.string(string))
    }

    func testThatParserUnderstandsStringsWithEscapedCharacters() {
        let expect = " \" \\ / \n \r \t \u{000c} \u{0008} "
        let value = try! JSONParser.parse("\" \\\" \\\\ \\/ \\n \\r \\t \\f \\b \"")
        XCTAssertEqual(value, JSON.string(expect))
    }

    func testThatParserUnderstandsStringsWithEscapedUnicode() {
        // try 1-, 2-, and 3-byte UTF8 sequences
        let expect = "\u{0060}\u{012a}\u{12AB}"
        let value = try! JSONParser.parse("\"\\u0060\\u012a\\u12AB\"")
        XCTAssertEqual(value, JSON.string(expect))
    }

    func testThatParserFailsWhenIncompleteDataIsPresent() {
        for s in [" ", "[0,", "{\"\":"] {
            do {
                let value = try JSONParser.parse(s)
                XCTFail("Unexpectedly parsed \(s) as \(value)")
            } catch JSONParser.Error.endOfStreamUnexpected {
                // expected error - do nothing
{'fraction_non_alphanumeric': 0.11626457758390457, 'fraction_numerical': 0.010148669099973293, 'mean_word_length': 2.4953329184816426, 'pattern_counts': {'":': 2, '<': 10, '<?xml version=': 0, '>': 12, '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': '2104076', 'n_tokens_mistral': 3442, 'n_tokens_neox': 3272, 'n_words': 721}