<commit_before>//
//  SpecTests.swift
//  SpecTests
//
//  Created by <NAME> on 8/30/16.
//  Copyright © 2016 dvappel. All rights reserved.
//

import XCTest
import JSON
@testable import MuttonChop
#if os(Linux)
    import Glibc
#endif

extension Context {
    init(from json: String) throws {
        try self.init(from: JSONParser().parse(data: json.data))
    }
    init(from json: JSON) {
        switch json {
        case let .array(array):
            self = .array(array.map(Context.init(from:)))
        case let .object(object):
            self = .dictionary(object.mapValues(Context.init(from:)))
        case let .number(number):
            switch number {
            case let .double(double) where floor(double) == double:
                self = .int(Int(double))
            case let .double(double):
                self = .double(double)
            case let .integer(int):
                self = .int(int)
            case let .unsignedInteger(int):
                self = .int(Int(int))
            }
        case let .boolean(bool):
            self = .bool(bool)
        case let .string(string):
            self = .string(string)
        case .null:
            fatalError("null is not supported")
        }
    }
}

#if os(OSX)
struct Test {
    let name: String
    let description: String
    let partials: [String:String]?
    let contextJSON: String
    let template: String
    let expected: String

    init(json: JSON) throws {
        name = try (json.get("name") as String)
            .replacingOccurrences(of: " ", with: "")
            .replacingOccurrences(of: "-", with: "_")
            .replacingOccurrences(of: ",", with: "_")
            .replacingOccurrences(of: "(", with: "_")
            .replacingOccurrences(of: ")", with: "")


        description = try (json.get("desc") as String)
            .replacingOccurrences(of: "\\\"", with: "\"")
            .replacingOccurrences(of: "\"", with: "\\\"")

        partials = try json["partials"]?.asDictionary()
            .mapValues { try $0.asString() }
            .mapValues { $0
                .replacingOccurrences(of: "\\\"", with: "\"")
                .replacingOccurrences(of: "\"", with: "\\\"")
                .replacingOccurrences(of: "\t", with: "\\t")
                .replacingOccurrences(of: "\r", with: "\\r")
                .replacingOccurrences(of: "\n", with: "\\n") }

        contextJSON = try JSONSerializer().serializeToString(json: .object(json.get("data")))
            .replacingOccurrences(of: "\\\"", with: "\"")
            .replacingOccurrences(of: "\"", with: "\\\"")
            .replacingOccurrences(of: "\t", with: "\\t")
            .replacingOccurrences(of: "\r", with: "\\r")
            .replacingOccurrences(of: "\n", with: "\\n")

        template = try (json.get("template") as String)
            .replacingOccurrences(of: "\\\"", with: "\"")
            .replacingOccurrences(of: "\"", with: "\\\"")
            .replacingOccurrences(of: "\t", with: "\\t")
            .replacingOccurrences(of: "\r", with: "\\r")
            .replacingOccurrences(of: "\n", with: "\\n")

        expected = try (json.get("expected") as String)
            .replacingOccurrences(of: "\\\"", with: "\"")
            .replacingOccurrences(of: "\"", with: "\\\"")
            .replacingOccurrences(of: "\t", with: "\\t")
            .replacingOccurrences(of: "\r", with: "\\r")
            .replacingOccurrences(of: "\n", with: "\\n")
    }
}

class GenerateTests: XCTestCase {
    let enabled = true
    let suites = ["Sections", "Interpolation", "Inverted", "Comments", "Partials", "Delimiters", "Inheritance"]

    func testGenerate() throws {
        guard enabled else { return }

        for suite in suites {
            let suite = try generateTestSuite(suite)
            print()
            print(suite)
            print()
        }
    }

    func generateTestSuite(_ suite: String) throws -> String {

        guard let file = Bundle.allBundles
            .flatMap({ $0.url(forResource: suite, withExtension: "json") })
            .first else {
                fatalError()
        }
        let data = try Data(contentsOf: file)

        let json = try JSONParser().parse(data: C7.Data(Array(data)))
        let overview = try json["overview"]?.asString() ?? ""
        let testsJSON = try json.get("tests") as [JSON]
<commit_msg>Disable code gen in tests (dev only)<commit_after>//
//  SpecTests.swift
//  SpecTests
//
//  Created by <NAME> on 8/30/16.
//  Copyright © 2016 dvappel. All rights reserved.
//

import XCTest
import JSON
@testable import MuttonChop
#if os(Linux)
    import Glibc
#endif

extension Context {
    init(from json: String) throws {
        try self.init(from: JSONParser().parse(data: json.data))
    }
    init(from json: JSON) {
        switch json {
        case let .array(array):
            self = .array(array.map(Context.init(from:)))
        case let .object(object):
            self = .dictionary(object.mapValues(Context.init(from:)))
        case let .number(number):
            switch number {
            case let .double(double) where floor(double) == double:
                self = .int(Int(double))
            case let .double(double):
                self = .double(double)
            case let .integer(int):
                self = .int(int)
            case let .unsignedInteger(int):
                self = .int(Int(int))
            }
        case let .boolean(bool):
            self = .bool(bool)
        case let .string(string):
            self = .string(string)
        case .null:
            fatalError("null is not supported")
        }
    }
}

#if os(OSX)
struct Test {
    let name: String
    let description: String
    let partials: [String:String]?
    let contextJSON: String
    let template: String
    let expected: String

    init(json: JSON) throws {
        name = try (json.get("name") as String)
            .replacingOccurrences(of: " ", with: "")
            .replacingOccurrences(of: "-", with: "_")
            .replacingOccurrences(of: ",", with: "_")
            .replacingOccurrences(of: "(", with: "_")
            .replacingOccurrences(of: ")", with: "")


        description = try (json.get("desc") as String)
            .replacingOccurrences(of: "\\\"", with: "\"")
            .replacingOccurrences(of: "\"", with: "\\\"")

        partials = try json["partials"]?.asDictionary()
            .mapValues { try $0.asString() }
            .mapValues { $0
                .replacingOccurrences(of: "\\\"", with: "\"")
                .replacingOccurrences(of: "\"", with: "\\\"")
                .replacingOccurrences(of: "\t", with: "\\t")
                .replacingOccurrences(of: "\r", with: "\\r")
                .replacingOccurrences(of: "\n", with: "\\n") }

        contextJSON = try JSONSerializer().serializeToString(json: .object(json.get("data")))
            .replacingOccurrences(of: "\\\"", with: "\"")
            .replacingOccurrences(of: "\"", with: "\\\"")
            .replacingOccurrences(of: "\t", with: "\\t")
            .replacingOccurrences(of: "\r", with: "\\r")
            .replacingOccurrences(of: "\n", with: "\\n")

        template = try (json.get("template") as String)
            .replacingOccurrences(of: "\\\"", with: "\"")
            .replacingOccurrences(of: "\"", with: "\\\"")
            .replacingOccurrences(of: "\t", with: "\\t")
            .replacingOccurrences(of: "\r", with: "\\r")
            .replacingOccurrences(of: "\n", with: "\\n")

        expected = try (json.get("expected") as String)
            .replacingOccurrences(of: "\\\"", with: "\"")
            .replacingOccurrences(of: "\"", with: "\\\"")
            .replacingOccurrences(of: "\t", with: "\\t")
            .replacingOccurrences(of: "\r", with: "\\r")
            .replacingOccurrences(of: "\n", with: "\\n")
    }
}

class GenerateTests: XCTestCase {
    let enabled = false
    let suites = ["Sections", "Interpolation", "Inverted", "Comments", "Partials", "Delimiters", "Inheritance"]

    func testGenerate() throws {
        guard enabled else { return }

        for suite in suites {
            let suite = try generateTestSuite(suite)
            print()
            print(suite)
            print()
        }
    }

    func generateTestSuite(_ suite: String) throws -> String {

        guard let file = Bundle.allBundles
            .flatMap({ $0.url(forResource: suite, withExtension: "json") })
            .first else {
                fatalError()
        }
        let data = try Data(contentsOf: file)

        let json = try JSONParser().parse(data: C7.Data(Array(data)))
        let overview = try json["overview"]?.asString() ?? ""
        let testsJSON = try json.get("tests") as [JSON]

{'fraction_non_alphanumeric': 0.16408032861706984, 'fraction_numerical': 0.0029666818804198994, 'mean_word_length': 1.9168053244592347, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '6182743', 'n_tokens_mistral': 2821, 'n_tokens_neox': 2593, 'n_words': 610}