//
//  StringHelper.swift
//  ZamzamKit
//
//  Created by Basem Emara on 1/20/16.
//  Copyright © 2016 CocoaPods. All rights reserved.
//

import XCTest
import ZamzamKit

class StringTests: XCTestCase {
    
}

extension StringTests {
    
    func testRandom() {
        XCTAssertEqual(String(random: 10).count, 10)
        
        let test = String(random: 20, prefix: "TEST: ")
        XCTAssertEqual(test.count, 26)
        XCTAssertTrue(test.hasPrefix("TEST: "))
    }
}

extension StringTests {
    
    func testSubscript() {
        let test = "Abcdef123456"
        
        XCTAssertEqual(test[3]!, "d")
        XCTAssertNil(test[99])
    }
    
    func testSubscriptRange() {
        let test = "Abcdef123456"
        
        XCTAssertEqual(test[3..<6]!, "def")
        XCTAssertEqual(test[3...6]!, "def1")
        XCTAssertEqual(test[3...]!, "def123456")
        XCTAssertEqual(test[3...99], nil)
    }
}

extension StringTests {
    
    func testEmailRegEx() {
        let value = "test@example.com"
        let wrong = "zamzam"
        
        XCTAssertTrue(value.isEmail)
        XCTAssertFalse(wrong.isEmail)
    }
    
    func testNumberRegEx() {
        let value = "123456789"
        let wrong = "zamzam"
        
        XCTAssertTrue(value.isNumber)
        XCTAssertFalse(wrong.isNumber)
    }
    
    func testAlphaRegEx() {
        let value = "zamzam"
        let wrong = "zamzam123"
        
        XCTAssertTrue(value.isAlpha)
        XCTAssertFalse(wrong.isAlpha)
    }
    
    func testAlphaNumbericRegEx() {
        let value = "zamzam123"
        let wrong = "zamzam!"
        
        XCTAssertTrue(value.isAlphaNumeric)
        XCTAssertFalse(wrong.isAlphaNumeric)
    }
}

extension StringTests {
    
    func testTrimmed() {
        let test = " Abcdef123456 \n\r  "
        let expected = "Abcdef123456"
        XCTAssertEqual(test.trimmed, expected)
    }
    
    func testTruncated() {
        let test = "Abcdef123456"
        XCTAssertEqual(test.truncated(3), "Abc...")
        XCTAssertEqual(test.truncated(3, trailing: "***"), "Abc***")
    }
    
    func testContains() {
        let elements = CharacterSet(charactersIn: "AbCz456!")
        
        XCTAssertFalse("".contains(elements))
        XCTAssertTrue("Foo5".contains(elements))
        XCTAssertTrue("bar 222".contains(elements))
        XCTAssertFalse("none".contains(elements))
        XCTAssertFalse("999".contains(elements))
        XCTAssertFalse("#$23".contains(elements))
        XCTAssertTrue("qwe!".contains(elements))
        
        XCTAssertTrue("def".contains(CharacterSet(charactersIn: "Abcdef123456")))
        XCTAssertFalse("Xyz".contains(CharacterSet(charactersIn: "Abcdef123456")))
    }
    
    func testSeparator() {
        XCTAssertEqual("Abcdef123456".separated(every: 3, with: "-"), "Abc-def-123-456")
        XCTAssertEqual("Abcd".separated(every: 6, with: ":"), "Abcd")
        XCTAssertEqual("Abcdef123456".separated(every: 0, with: "-"), "Abcdef123456")
        XCTAssertEqual("Abcdef123456".separated(every: 1, with: "-"), "A-b-c-d-e-f-1-2-3-4-5-6")
        XCTAssertEqual("Abcdef123456".separated(every: 12, with: "-"), "Abcdef123456")
        XCTAssertEqual("Abcdef123456".separated(every: 11, with: "-"), "Abcdef12345-6")
        XCTAssertEqual("".separated(every: 6, with: ":"), "")
        XCTAssertEqual("112312451".separated(every: 2, with: ":"), "11:23:12:45:1")
        XCTAssertEqual("112312451".separated(every: 3, with: ":"), "112:312:451")
        XCTAssertEqual("112312451".separated(every: 4, with: ":"), "1123:1245:1")
    }
}

extension StringTests {
    
    func testMatchRegEx() {
        XCTAssertTrue("1234567890".match(regex: "^[0-9]+?$"))
        XCTAssertTrue("abc123xyz".match(regex: "^[A-Za-z0-9]+$"))
        XCTAssertFalse("abc123xyz".match(regex: "^[A-Za-z]+$"))
    }
    
    func testReplacingRegEx() {
        let value = "my car reg 1 - dD11 AAA  my car reg 2 - AA22 BbB"
        let pattern = "([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}"
        
        // Case insensitive
        let newValue = value.replacing(regex: pattern, with: "XX", caseSensitive: false)
        let expectedValue = "my car reg 1 - XX  my car reg 2 - XX"
        XCTAssertEqual(newValue, expectedValue)
        
        // Case sensitive
        let newValue2 = value.replacing(regex: pattern, with: "XX", caseSensitive: true)
        XCTAssertEqual(newValue2, value)
        
        XCTAssertEqual("aa1bb22cc3d888d4ee5".replacing(regex: "\\d", with: "*"), "aa*bb**cc*d***d*ee*")
    }
}

extension StringTests {
    
    func testHTMLStripped() {
        let test = "<p>This is <em>web</em> content with a <a href=\"http://example.com\">link</a>.</p>"
        let expected = "This is web content with a link."
        XCTAssertEqual(test.htmlStripped, expected)
    }
}

extension StringTests {
    
    func testBase64Encoded() {
        let test = "Abcdef123456"
        let expected = "QWJjZGVmMTIzNDU2"
        XCTAssertEqual(test.base64Encoded, expected)
    }
    
    func testBase64Decoded() {
        let test = "NjU0MzIxRmVkY2Jh"
        let expected = "654321Fedcba"
        XCTAssertEqual(test.base64Decoded, expected)
    }
}

extension StringTests {
    
    func testIsNilOrEmpty() {
        var test: String?
        
        XCTAssertTrue(test.isNilOrEmpty)
        XCTAssertFalse(!test.isNilOrEmpty)
        
        test = ""
        XCTAssertTrue(test.isNilOrEmpty)
        XCTAssertFalse(!test.isNilOrEmpty)
        
        test = "abc"
        XCTAssertFalse(test.isNilOrEmpty)
        XCTAssertTrue(!test.isNilOrEmpty)
    }
}

extension StringTests {
    
    func testIsNilOrEmptyInfix() {
        var result: String
        var test: String?
        
        result = test ??+ "Abc"
        XCTAssertEqual(result, "Abc")
        
        test = ""
        result = test ??+ "Abc"
        XCTAssertEqual(result, "Abc")
        
        test = "Xyz"
        result = test ??+ "Abc"
        XCTAssertEqual(result, "Xyz")
    }
}
