Best Nimble code snippet using MatchTest
MatchTests.swift
Source:MatchTests.swift
...123 file: StaticString = #file,124 line: UInt = #line125) {126 for (test, expect) in tests {127 firstMatchTest(128 regex,129 input: test,130 match: expect ? test : nil,131 syntax: syntax,132 enableTracing: enableTracing,133 dumpAST: dumpAST,134 xfail: xfail,135 file: file,136 line: line)137 }138}139// TODO: Adjust below to also check captures140/// Test the first match in a string, via `firstRange(of:)`141func firstMatchTest(142 _ regex: String,143 input: String,144 match: String?,145 syntax: SyntaxOptions = .traditional,146 enableTracing: Bool = false,147 dumpAST: Bool = false,148 xfail: Bool = false,149 file: StaticString = #filePath,150 line: UInt = #line151) {152 do {153 let (found, _) = try _firstMatch(154 regex,155 input: input,156 syntax: syntax,157 enableTracing: enableTracing)158 if xfail {159 XCTAssertNotEqual(found, match, file: file, line: line)160 } else {161 XCTAssertEqual(found, match, file: file, line: line)162 }163 } catch {164 // FIXME: This allows non-matches to succeed even when xfail'd165 // When xfail == true, this should report failure for match == nil166 if !xfail && match != nil {167 XCTFail("\(error)", file: file, line: line)168 }169 return170 }171}172func firstMatchTests(173 _ regex: String,174 _ tests: (input: String, match: String?)...,175 syntax: SyntaxOptions = .traditional,176 enableTracing: Bool = false,177 dumpAST: Bool = false,178 xfail: Bool = false,179 file: StaticString = #filePath,180 line: UInt = #line181) {182 for (input, match) in tests {183 firstMatchTest(184 regex,185 input: input,186 match: match,187 syntax: syntax,188 enableTracing: enableTracing,189 dumpAST: dumpAST,190 xfail: xfail,191 file: file,192 line: line)193 }194}195extension RegexTests {196 func testMatch() {197 firstMatchTest(198 "abc", input: "123abcxyz", match: "abc")199 firstMatchTest(200 #"abc\+d*"#, input: "123abc+xyz", match: "abc+")201 firstMatchTest(202 #"abc\+d*"#, input: "123abc+dddxyz", match: "abc+ddd")203 firstMatchTest(204 "a(b)", input: "123abcxyz", match: "ab")205 firstMatchTest(206 "(.)*(.*)", input: "123abcxyz", match: "123abcxyz")207 firstMatchTest(208 #"abc\d"#, input: "xyzabc123", match: "abc1")209 // MARK: Allowed combining characters210 firstMatchTest("e\u{301}", input: "e\u{301}", match: "e\u{301}")211 firstMatchTest("1\u{358}", input: "1\u{358}", match: "1\u{358}")212 firstMatchTest(#"\ \#u{361}"#, input: " \u{361}", match: " \u{361}")213 // MARK: Alternations214 firstMatchTest(215 "abc(?:de)+fghi*k|j", input: "123abcdefghijxyz", match: "j")216 firstMatchTest(217 "abc(?:de)+fghi*k|j", input: "123abcdedefghkxyz", match: "abcdedefghk")218 firstMatchTest(219 "a(?:b|c)?d", input: "123adxyz", match: "ad")220 firstMatchTest(221 "a(?:b|c)?d", input: "123abdxyz", match: "abd")222 firstMatchTest(223 "a(?:b|c)?d", input: "123acdxyz", match: "acd")224 firstMatchTest(225 "a?b??c+d+?e*f*?", input: "123abcdefxyz", match: "abcde")226 firstMatchTest(227 "a?b??c+d+?e*f*?", input: "123bcddefxyz", match: "bcd")228 firstMatchTest(229 "a|b?c", input: "123axyz", match: "a")230 firstMatchTest(231 "a|b?c", input: "123bcxyz", match: "bc")232 firstMatchTest(233 "(a|b)c", input: "123abcxyz", match: "bc")234 // Alternations with empty branches are permitted.235 firstMatchTest("|", input: "ab", match: "")236 firstMatchTest("(|)", input: "ab", match: "")237 firstMatchTest("a|", input: "ab", match: "a")238 firstMatchTest("a|", input: "ba", match: "")239 firstMatchTest("|b", input: "ab", match: "")240 firstMatchTest("|b", input: "ba", match: "")241 firstMatchTest("|b|", input: "ab", match: "")242 firstMatchTest("|b|", input: "ba", match: "")243 firstMatchTest("a|b|", input: "ab", match: "a")244 firstMatchTest("a|b|", input: "ba", match: "b")245 firstMatchTest("a|b|", input: "ca", match: "")246 firstMatchTest("||c|", input: "ab", match: "")247 firstMatchTest("||c|", input: "cb", match: "")248 firstMatchTest("|||", input: "ab", match: "")249 firstMatchTest("a|||d", input: "bc", match: "")250 firstMatchTest("a|||d", input: "abc", match: "a")251 firstMatchTest("a|||d", input: "d", match: "")252 // MARK: Unicode scalars253 firstMatchTest(254 #"a\u0065b\u{00000065}c\x65d\U00000065"#,255 input: "123aebecedexyz", match: "aebecede")256 firstMatchTest(257 #"\u{00000000000000000000000000A}"#,258 input: "123\nxyz", match: "\n")259 firstMatchTest(260 #"\x{00000000000000000000000000A}"#,261 input: "123\nxyz", match: "\n")262 firstMatchTest(263 #"\o{000000000000000000000000007}"#,264 input: "123\u{7}xyz", match: "\u{7}")265 firstMatchTest(#"\o{70}"#, input: "1238xyz", match: "8")266 firstMatchTest(#"\0"#, input: "123\0xyz", match: "\0")267 firstMatchTest(#"\01"#, input: "123\u{1}xyz", match: "\u{1}")268 firstMatchTest(#"\070"#, input: "1238xyz", match: "8")269 firstMatchTest(#"\07A"#, input: "123\u{7}Axyz", match: "\u{7}A")270 firstMatchTest(#"\08"#, input: "123\08xyz", match: "\08")271 firstMatchTest(#"\0707"#, input: "12387\u{1C7}xyz", match: "\u{1C7}")272 // code point sequence273 firstMatchTest(#"\u{61 62 63}"#, input: "123abcxyz", match: "abc")274 firstMatchTest(#"3\u{ 61 62 63 }"#, input: "123abcxyz", match: "3abc")275 firstMatchTest(#"\u{61 62}\u{63}"#, input: "123abcxyz", match: "abc")276 firstMatchTest(#"\u{61}\u{62 63}"#, input: "123abcxyz", match: "abc")277 firstMatchTest(#"9|\u{61 62 63}"#, input: "123abcxyz", match: "abc")278 firstMatchTest(#"(?:\u{61 62 63})"#, input: "123abcxyz", match: "abc")279 firstMatchTest(#"23\u{61 62 63}xy"#, input: "123abcxyz", match: "23abcxy")280 // o + horn + dot_below281 firstMatchTest(282 #"\u{006f 031b 0323}"#,283 input: "\u{006f}\u{031b}\u{0323}",284 match: "\u{006f}\u{031b}\u{0323}"285 )286 // Escape sequences that represent scalar values.287 firstMatchTest(#"\a[\b]\e\f\n\r\t"#,288 input: "\u{7}\u{8}\u{1B}\u{C}\n\r\t",289 match: "\u{7}\u{8}\u{1B}\u{C}\n\r\t")290 firstMatchTest(#"[\a][\b][\e][\f][\n][\r][\t]"#,291 input: "\u{7}\u{8}\u{1B}\u{C}\n\r\t",292 match: "\u{7}\u{8}\u{1B}\u{C}\n\r\t")293 firstMatchTest(#"\r\n"#, input: "\r\n", match: "\r\n")294 // MARK: Quotes295 firstMatchTest(296 #"a\Q .\Eb"#,297 input: "123a .bxyz", match: "a .b")298 firstMatchTest(299 #"a\Q \Q \\.\Eb"#,300 input: #"123a \Q \\.bxyz"#, match: #"a \Q \\.b"#)301 firstMatchTest(302 #"\d\Q...\E"#,303 input: "Countdown: 3... 2... 1...", match: "3...")304 // MARK: Comments305 firstMatchTest(306 #"a(?#comment)b"#, input: "123abcxyz", match: "ab")307 firstMatchTest(308 #"a(?#. comment)b"#, input: "123abcxyz", match: "ab")309 }310 func testMatchQuantification() {311 // MARK: Quantification312 firstMatchTest(313 #"a{1,2}"#, input: "123aaaxyz", match: "aa")314 firstMatchTest(315 #"a{ 1 , 2 }"#, input: "123aaaxyz", match: "aa")316 firstMatchTest(317 #"a{,2}"#, input: "123aaaxyz", match: "")318 firstMatchTest(319 #"a{ , 2 }"#, input: "123aaaxyz", match: "")320 firstMatchTest(321 #"a{,2}x"#, input: "123aaaxyz", match: "aax")322 firstMatchTest(323 #"a{,2}x"#, input: "123xyz", match: "x")324 firstMatchTest(325 #"a{2,}"#, input: "123aaaxyz", match: "aaa")326 firstMatchTest(327 #"a{1}"#, input: "123aaaxyz", match: "a")328 firstMatchTest(329 #"a{ 1 }"#, input: "123aaaxyz", match: "a")330 firstMatchTest(331 #"a{1,2}?"#, input: "123aaaxyz", match: "a")332 firstMatchTest(333 #"a{1,2}?x"#, input: "123aaaxyz", match: "aax")334 firstMatchTest(335 #"xa{0}y"#, input: "123aaaxyz", match: "xy")336 firstMatchTest(337 #"xa{0,0}y"#, input: "123aaaxyz", match: "xy")338 firstMatchTest(339 #"(a|a){2}a"#, input: "123aaaxyz", match: "aaa")340 firstMatchTest(341 #"(a|a){3}a"#, input: "123aaaxyz", match: nil)342 firstMatchTest("a.*", input: "dcba", match: "a")343 firstMatchTest("a*", input: "", match: "")344 firstMatchTest("a*", input: "a", match: "a")345 firstMatchTest("a*", input: "aaa", match: "aaa")346 firstMatchTest("a*?", input: "", match: "")347 firstMatchTest("a*?", input: "a", match: "")348 firstMatchTest("a*?a", input: "aaa", match: "a")349 firstMatchTest("xa*?x", input: "_xx__", match: "xx")350 firstMatchTest("xa*?x", input: "_xax__", match: "xax")351 firstMatchTest("xa*?x", input: "_xaax__", match: "xaax")352 firstMatchTest("a+", input: "", match: nil)353 firstMatchTest("a+", input: "a", match: "a")354 firstMatchTest("a+", input: "aaa", match: "aaa")355 firstMatchTest("a+?", input: "", match: nil)356 firstMatchTest("a+?", input: "a", match: "a")357 firstMatchTest("a+?a", input: "aaa", match: "aa")358 firstMatchTest("xa+?x", input: "_xx__", match: nil)359 firstMatchTest("xa+?x", input: "_xax__", match: "xax")360 firstMatchTest("xa+?x", input: "_xaax__", match: "xaax")361 firstMatchTest("a??", input: "", match: "")362 firstMatchTest("a??", input: "a", match: "")363 firstMatchTest("a??a", input: "aaa", match: "a")364 firstMatchTest("xa??x", input: "_xx__", match: "xx")365 firstMatchTest("xa??x", input: "_xax__", match: "xax")366 firstMatchTest("xa??x", input: "_xaax__", match: nil)367 // Possessive .* will consume entire input368 firstMatchTests(369 ".*+x",370 ("abc", nil), ("abcx", nil), ("", nil))371 firstMatchTests(372 "a+b",373 ("abc", "ab"),374 ("aaabc", "aaab"),375 ("b", nil))376 firstMatchTests(377 "a++b",378 ("abc", "ab"),379 ("aaabc", "aaab"),380 ("b", nil))381 firstMatchTests(382 "a+?b",383 ("abc", "ab"),384 ("aaabc", "aaab"), // firstRange will match from front385 ("b", nil))386 firstMatchTests(387 "a+a",388 ("babc", nil),389 ("baaabc", "aaa"),390 ("bb", nil))391 firstMatchTests(392 "a++a",393 ("babc", nil),394 ("baaabc", nil),395 ("bb", nil),396 xfail: true)397 firstMatchTests(398 "a+?a",399 ("babc", nil),400 ("baaabc", "aa"),401 ("bb", nil))402 firstMatchTests(403 "a{2,4}a",404 ("babc", nil),405 ("baabc", nil),406 ("baaabc", "aaa"),407 ("baaaaabc", "aaaaa"),408 ("baaaaaaaabc", "aaaaa"),409 ("bb", nil))410 firstMatchTests(411 "a{,4}a",412 ("babc", "a"),413 ("baabc", "aa"),414 ("baaabc", "aaa"),415 ("baaaaabc", "aaaaa"),416 ("baaaaaaaabc", "aaaaa"),417 ("bb", nil))418 firstMatchTests(419 "a{2,}a",420 ("babc", nil),421 ("baabc", nil),422 ("baaabc", "aaa"),423 ("baaaaabc", "aaaaa"),424 ("baaaaaaaabc", "aaaaaaaa"),425 ("bb", nil))426 firstMatchTests(427 "a{2,4}?a",428 ("babc", nil),429 ("baabc", nil),430 ("baaabc", "aaa"),431 ("baaaaabc", "aaa"),432 ("baaaaaaaabc", "aaa"),433 ("bb", nil))434 firstMatchTests(435 "a{,4}?a",436 ("babc", "a"),437 ("baabc", "a"),438 ("baaabc", "a"),439 ("baaaaabc", "a"),440 ("baaaaaaaabc", "a"),441 ("bb", nil))442 firstMatchTests(443 "a{2,}?a",444 ("babc", nil),445 ("baabc", nil),446 ("baaabc", "aaa"),447 ("baaaaabc", "aaa"),448 ("baaaaaaaabc", "aaa"),449 ("bb", nil))450 firstMatchTests(451 "a{2,4}+a",452 ("babc", nil),453 ("baabc", nil),454 ("baaaaabc", "aaaaa"),455 ("baaaaaaaabc", "aaaaa"),456 ("bb", nil))457 firstMatchTests(458 "a{,4}+a",459 ("baaaaabc", "aaaaa"),460 ("baaaaaaaabc", "aaaaa"),461 ("bb", nil))462 firstMatchTests(463 "a{2,}+a",464 ("babc", nil),465 ("baabc", nil),466 ("bb", nil))467 468 // XFAIL'd versions of the above469 firstMatchTests(470 "a{2,4}+a",471 ("baaabc", nil),472 xfail: true)473 firstMatchTests(474 "a{,4}+a",475 ("babc", nil),476 ("baabc", nil),477 ("baaabc", nil),478 xfail: true)479 firstMatchTests(480 "a{2,}+a",481 ("baaabc", nil),482 ("baaaaabc", nil),483 ("baaaaaaaabc", nil),484 xfail: true)485 // XFAIL'd possessive tests486 firstMatchTests(487 "a?+a",488 ("a", nil),489 xfail: true)490 firstMatchTests(491 "(a|a)?+a",492 ("a", nil),493 xfail: true)494 firstMatchTests(495 "(a|a){2,4}+a",496 ("a", nil),497 ("aa", nil))498 firstMatchTests(499 "(a|a){2,4}+a",500 ("aaa", nil),501 ("aaaa", nil),502 xfail: true)503 firstMatchTests(504 "(?:a{2,4}?b)+",505 ("aab", "aab"),506 ("aabaabaab", "aabaabaab"),507 ("aaabaaaabaabab", "aaabaaaabaab")508 // TODO: Nested reluctant reentrant example, xfailed509 )510 // Reluctant by default - '*/+/.' and '*?/+?/.?' are swapped511 firstMatchTest("(?U)a*", input: "aaa", match: "")512 firstMatchTest("(?U)a*a", input: "aaa", match: "a")513 firstMatchTest("(?U)a*?", input: "aaa", match: "aaa")514 firstMatchTest("(?U)a*?a", input: "aaa", match: "aaa")515 firstMatchTest("(?U)a+", input: "aaa", match: "a")516 firstMatchTest("(?U)a+?", input: "aaa", match: "aaa")517 firstMatchTest("(?U)a?", input: "a", match: "")518 firstMatchTest("(?U)a?a", input: "aaa", match: "a")519 firstMatchTest("(?U)a??", input: "a", match: "a")520 firstMatchTest("(?U)a??a", input: "aaa", match: "aa")521 // TODO: After captures, easier to test these522 }523 func testMatchCharacterClasses() {524 // MARK: Character classes525 firstMatchTest(#"abc\d"#, input: "xyzabc123", match: "abc1")526 firstMatchTest(527 "[-|$^:?+*())(*-+-]", input: "123(abc)xyz", match: "(")528 firstMatchTest(529 "[-|$^:?+*())(*-+-]", input: "123-abcxyz", match: "-")530 firstMatchTest(531 "[-|$^:?+*())(*-+-]", input: "123^abcxyz", match: "^")532 firstMatchTest(533 "[a-b-c]", input: "123abcxyz", match: "a")534 firstMatchTest(535 "[a-b-c]", input: "123-abcxyz", match: "-")536 firstMatchTest("[-a-]", input: "123abcxyz", match: "a")537 firstMatchTest("[-a-]", input: "123-abcxyz", match: "-")538 firstMatchTest("[a-z]", input: "123abcxyz", match: "a")539 firstMatchTest("[a-z]", input: "123ABCxyz", match: "x")540 firstMatchTest("[a-z]", input: "123-abcxyz", match: "a")541 firstMatchTest("(?x)[ a - z ]+", input: " 123-abcxyz", match: "abcxyz")542 // Character class subtraction543 firstMatchTest("[a-d--a-c]", input: "123abcdxyz", match: "d")544 firstMatchTest("[-]", input: "123-abcxyz", match: "-")545 // These are metacharacters in certain contexts, but normal characters546 // otherwise.547 firstMatchTest(":-]", input: "123:-]xyz", match: ":-]")548 firstMatchTest(549 "[^abc]", input: "123abcxyz", match: "1")550 firstMatchTest(551 "[a^]", input: "123abcxyz", match: "a")552 firstMatchTest(553 #"\D\S\W"#, input: "123ab-xyz", match: "ab-")554 firstMatchTest(555 #"[\dd]"#, input: "xyzabc123", match: "1")556 firstMatchTest(557 #"[\dd]"#, input: "xyzabcd123", match: "d")558 firstMatchTest(559 #"[^[\D]]"#, input: "xyzabc123", match: "1")560 firstMatchTest(561 "[[ab][bc]]", input: "123abcxyz", match: "a")562 firstMatchTest(563 "[[ab][bc]]", input: "123cbaxyz", match: "c")564 firstMatchTest(565 "[[ab]c[de]]", input: "123abcxyz", match: "a")566 firstMatchTest(567 "[[ab]c[de]]", input: "123cbaxyz", match: "c")568 firstMatchTest(569 #"[ab[:space:]\d[:^upper:]cd]"#,570 input: "123abcxyz", match: "1")571 firstMatchTest(572 #"[ab[:space:]\d[:^upper:]cd]"#,573 input: "xyzabc123", match: "x")574 firstMatchTest(575 #"[ab[:space:]\d[:^upper:]cd]"#,576 input: "XYZabc123", match: "a")577 firstMatchTest(578 #"[ab[:space:]\d[:^upper:]cd]"#,579 input: "XYZ abc123", match: " ")580 firstMatchTest("[[[:space:]]]", input: "123 abc xyz", match: " ")581 firstMatchTest("[[:alnum:]]", input: "[[:alnum:]]", match: "a")582 firstMatchTest("[[:blank:]]", input: "123\tabc xyz", match: "\t")583 firstMatchTest(584 "[[:graph:]]",585 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: "a")586 firstMatchTest(587 "[[:print:]]",588 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: " ")589 firstMatchTest(590 "[[:word:]]",591 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: "a")592 firstMatchTest(593 "[[:xdigit:]]",594 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: "a")595 firstMatchTest("[[:isALNUM:]]", input: "[[:alnum:]]", match: "a")596 firstMatchTest("[[:AL_NUM:]]", input: "[[:alnum:]]", match: "a")597 firstMatchTest("[[:script=Greek:]]", input: "123αβγxyz", match: "α")598 func scalar(_ u: UnicodeScalar) -> UInt32 { u.value }599 for s in scalar("\u{C}") ... scalar("\u{1B}") {600 let u = UnicodeScalar(s)!601 firstMatchTest(#"[\f-\e]"#, input: "\u{B}\u{1C}\(u)", match: "\(u)")602 }603 for u: UnicodeScalar in ["\u{7}", "\u{8}"] {604 firstMatchTest(#"[\a-\b]"#, input: "\u{6}\u{9}\(u)", match: "\(u)")605 }606 for s in scalar("\u{A}") ... scalar("\u{D}") {607 let u = UnicodeScalar(s)!608 firstMatchTest(#"[\n-\r]"#, input: "\u{9}\u{E}\(u)", match: "\(u)")609 }610 firstMatchTest(#"[\t-\t]"#, input: "\u{8}\u{A}\u{9}", match: "\u{9}")611 // Currently not supported in the matching engine.612 for c: UnicodeScalar in ["a", "b", "c"] {613 firstMatchTest(#"[\c!-\C-#]"#, input: "def\(c)", match: "\(c)",614 xfail: true)615 }616 for c: UnicodeScalar in ["$", "%", "&", "'"] {617 firstMatchTest(#"[\N{DOLLAR SIGN}-\N{APOSTROPHE}]"#,618 input: "#()\(c)", match: "\(c)", xfail: true)619 }620 // MARK: Operators621 firstMatchTest(622 #"[a[bc]de&&[^bc]\d]+"#, input: "123bcdxyz", match: "d")623 // Empty intersection never matches, should this be a compile time error?624 // matchTest("[a&&b]", input: "123abcxyz", match: "")625 firstMatchTest(626 "[abc--def]", input: "123abcxyz", match: "a")627 // We left-associate for chained operators.628 firstMatchTest(629 "[ab&&b~~cd]", input: "123abcxyz", match: "b")630 firstMatchTest(631 "[ab&&b~~cd]", input: "123acdxyz", match: "c") // this doesn't match NSRegularExpression's behavior632 // Operators are only valid in custom character classes.633 firstMatchTest(634 "a&&b", input: "123a&&bcxyz", match: "a&&b")635 firstMatchTest(636 "&?", input: "123a&&bcxyz", match: "")637 firstMatchTest(638 "&&?", input: "123a&&bcxyz", match: "&&")639 firstMatchTest(640 "--+", input: "123---xyz", match: "---")641 firstMatchTest(642 "~~*", input: "123~~~xyz", match: "~~~")643 // Quotes in character classes.644 firstMatchTest(#"[\Qabc\E]"#, input: "QEa", match: "a")645 firstMatchTest(#"[\Qabc\E]"#, input: "cxx", match: "c")646 firstMatchTest(#"[\Qabc\E]+"#, input: "cba", match: "cba")647 firstMatchTest(#"[\Qa-c\E]+"#, input: "a-c", match: "a-c")648 firstMatchTest(#"["a-c"]+"#, input: "abc", match: "a",649 syntax: .experimental)650 firstMatchTest(#"["abc"]+"#, input: "cba", match: "cba",651 syntax: .experimental)652 firstMatchTest(#"["abc"]+"#, input: #""abc""#, match: "abc",653 syntax: .experimental)654 firstMatchTest(#"["abc"]+"#, input: #""abc""#, match: #""abc""#)655 }656 func testCharacterProperties() {657 // MARK: Character names.658 firstMatchTest(#"\N{ASTERISK}"#, input: "123***xyz", match: "*")659 firstMatchTest(#"[\N{ASTERISK}]"#, input: "123***xyz", match: "*")660 firstMatchTest(661 #"\N{ASTERISK}+"#, input: "123***xyz", match: "***")662 firstMatchTest(663 #"\N {2}"#, input: "123 xyz", match: "3 ", xfail: true)664 firstMatchTest(#"\N{U+2C}"#, input: "123,xyz", match: ",")665 firstMatchTest(#"\N{U+1F4BF}"#, input: "123ð¿xyz", match: "ð¿")666 firstMatchTest(#"\N{U+00001F4BF}"#, input: "123ð¿xyz", match: "ð¿")667 // MARK: Character properties.668 firstMatchTest(#"\p{L}"#, input: "123abcXYZ", match: "a")669 firstMatchTest(#"\p{gc=L}"#, input: "123abcXYZ", match: "a")670 firstMatchTest(#"\p{Lu}"#, input: "123abcXYZ", match: "X")671 // U+0374 GREEK NUMERAL SIGN (Lm)672 // U+00AA FEMININE ORDINAL INDICATOR (Lo)673 firstMatchTest(#"\p{L}"#, input: "\u{0374}\u{00AA}123abcXYZ", match: "\u{0374}")674 firstMatchTest(#"\p{Lc}"#, input: "\u{0374}\u{00AA}123abcXYZ", match: "a")675 firstMatchTest(#"\p{Lc}"#, input: "\u{0374}\u{00AA}123XYZ", match: "X")676 firstMatchTest(#"\p{L&}"#, input: "\u{0374}\u{00AA}123abcXYZ", match: "a")677 firstMatchTest(#"\p{L&}"#, input: "\u{0374}\u{00AA}123XYZ", match: "X")678 firstMatchTest(679 #"\P{Cc}"#, input: "\n\n\nXYZ", match: "X")680 firstMatchTest(681 #"\P{Z}"#, input: " XYZ", match: "X")682 firstMatchTest(#"[\p{C}]"#, input: "123\n\n\nXYZ", match: "\n")683 firstMatchTest(#"\p{C}+"#, input: "123\n\n\nXYZ", match: "\n\n\n")684 // UAX44-LM3 means all of the below are equivalent.685 firstMatchTest(#"\p{ll}"#, input: "123abcXYZ", match: "a")686 firstMatchTest(#"\p{gc=ll}"#, input: "123abcXYZ", match: "a")687 firstMatchTest(688 #"\p{General_Category=Ll}"#, input: "123abcXYZ", match: "a")689 firstMatchTest(690 #"\p{General-Category=isLl}"#,691 input: "123abcXYZ", match: "a")692 firstMatchTest(#"\p{ __l_ l _ }"#, input: "123abcXYZ", match: "a")693 firstMatchTest(694 #"\p{ g_ c =- __l_ l _ }"#, input: "123abcXYZ", match: "a")695 firstMatchTest(696 #"\p{ general ca-tegory = __l_ l _ }"#,697 input: "123abcXYZ", match: "a")698 firstMatchTest(699 #"\p{- general category = is__l_ l _ }"#,700 input: "123abcXYZ", match: "a")701 firstMatchTest(702 #"\p{ general category -= IS__l_ l _ }"#,703 input: "123abcXYZ", match: "a")704 firstMatchTest(#"\p{Any}"#, input: "123abcXYZ", match: "1")705 firstMatchTest(#"\p{Assigned}"#, input: "123abcXYZ", match: "1")706 firstMatchTest(#"\p{ascii}"#, input: "123abcXYZ", match: "1")707 firstMatchTest(#"\p{isAny}"#, input: "123abcXYZ", match: "1")708 firstMatchTest(#"\p{sc=grek}"#, input: "123αβγxyz", match: "α")709 firstMatchTest(#"\p{sc=isGreek}"#, input: "123αβγxyz", match: "α")710 firstMatchTest(#"\p{Greek}"#, input: "123αβγxyz", match: "α")711 firstMatchTest(#"\p{isGreek}"#, input: "123αβγxyz", match: "α")712 firstMatchTest(#"\P{Script=Latn}"#, input: "abcαβγxyz", match: "α")713 firstMatchTest(#"\p{script=Greek}"#, input: "123αβγxyz", match: "α")714 firstMatchTest(#"\p{ISscript=isGreek}"#, input: "123αβγxyz", match: "α")715 firstMatchTest(#"\p{scx=bamum}"#, input: "123ê ê¡ê¢xyz", match: "ê ")716 firstMatchTest(#"\p{ISBAMUM}"#, input: "123ê ê¡ê¢xyz", match: "ê ")717 firstMatchTest(#"\p{Script=Unknown}"#, input: "\u{10FFFF}", match: "\u{10FFFF}")718 firstMatchTest(#"\p{scx=Gujr}"#, input: "\u{a839}", match: "\u{a839}")719 firstMatchTest(#"\p{Gujr}"#, input: "\u{a839}", match: "\u{a839}")720 firstMatchTest(#"\p{alpha}"#, input: "123abcXYZ", match: "a")721 firstMatchTest(#"\P{alpha}"#, input: "123abcXYZ", match: "1")722 firstMatchTest(723 #"\p{alphabetic=True}"#, input: "123abcXYZ", match: "a")724 // This is actually available-ed...725 firstMatchTest(726 #"\p{emoji=t}"#, input: "123ð¿xyz", match: "a",727 xfail: true)728 firstMatchTest(#"\p{Alpha=no}"#, input: "123abcXYZ", match: "1")729 firstMatchTest(#"\P{Alpha=no}"#, input: "123abcXYZ", match: "a")730 firstMatchTest(#"\p{isAlphabetic}"#, input: "123abcXYZ", match: "a")731 firstMatchTest(732 #"\p{isAlpha=isFalse}"#, input: "123abcXYZ", match: "1")733 // Oniguruma special support not in stdlib734 firstMatchTest(735 #"\p{In_Runic}"#, input: "123á á¡á¢XYZ", match: "á ",736 xfail: true)737 // TODO: PCRE special738 firstMatchTest(739 #"\p{Xan}"#, input: "[[:alnum:]]", match: "a",740 xfail: true)741 firstMatchTest(742 #"\p{Xps}"#, input: "123 abc xyz", match: " ",743 xfail: true)744 firstMatchTest(745 #"\p{Xsp}"#, input: "123 abc xyz", match: " ",746 xfail: true)747 firstMatchTest(748 #"\p{Xuc}"#, input: "$var", match: "$",749 xfail: true)750 firstMatchTest(751 #"\p{Xwd}"#, input: "[[:alnum:]]", match: "a",752 xfail: true)753 firstMatchTest(#"\p{alnum}"#, input: "[[:alnum:]]", match: "a")754 firstMatchTest(#"\p{is_alnum}"#, input: "[[:alnum:]]", match: "a")755 firstMatchTest(#"\p{blank}"#, input: "123\tabc xyz", match: "\t")756 firstMatchTest(757 #"\p{graph}"#,758 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: "a")759 firstMatchTest(760 #"\p{print}"#,761 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: " ")762 firstMatchTest(763 #"\p{word}"#,764 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: "a")765 firstMatchTest(766 #"\p{xdigit}"#,767 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: "a")768 firstMatchTest("[[:alnum:]]", input: "[[:alnum:]]", match: "a")769 firstMatchTest("[[:blank:]]", input: "123\tabc xyz", match: "\t")770 firstMatchTest("[[:graph:]]",771 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: "a")772 firstMatchTest("[[:print:]]",773 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: " ")774 firstMatchTest("[[:word:]]",775 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: "a")776 firstMatchTest("[[:xdigit:]]",777 input: "\u{7}\u{1b}\u{a}\n\r\t abc", match: "a")778 }779 func testAssertions() {780 // MARK: Assertions781 firstMatchTest(782 #"\d+(?= dollars)"#,783 input: "Price: 100 dollars", match: "100")784 firstMatchTest(785 #"\d+(?= pesos)"#,786 input: "Price: 100 dollars", match: nil)787 firstMatchTest(788 #"(?=\d+ dollars)\d+"#,789 input: "Price: 100 dollars", match: "100",790 xfail: true) // TODO791 firstMatchTest(792 #"\d+(*pla: dollars)"#,793 input: "Price: 100 dollars", match: "100")794 firstMatchTest(795 #"\d+(*positive_lookahead: dollars)"#,796 input: "Price: 100 dollars", match: "100")797 firstMatchTest(798 #"\d+(?! dollars)"#,799 input: "Price: 100 pesos", match: "100")800 firstMatchTest(801 #"\d+(?! dollars)"#,802 input: "Price: 100 dollars", match: "10")803 firstMatchTest(804 #"(?!\d+ dollars)\d+"#,805 input: "Price: 100 pesos", match: "100")806 firstMatchTest(807 #"\d+(*nla: dollars)"#,808 input: "Price: 100 pesos", match: "100")809 firstMatchTest(810 #"\d+(*negative_lookahead: dollars)"#,811 input: "Price: 100 pesos", match: "100")812 firstMatchTest(813 #"(?<=USD)\d+"#, input: "Price: USD100", match: "100", xfail: true)814 firstMatchTest(815 #"(*plb:USD)\d+"#, input: "Price: USD100", match: "100", xfail: true)816 firstMatchTest(817 #"(*positive_lookbehind:USD)\d+"#,818 input: "Price: USD100", match: "100", xfail: true)819 // engines generally enforce that lookbehinds are fixed width820 firstMatchTest(821 #"\d{3}(?<=USD\d{3})"#, input: "Price: USD100", match: "100", xfail: true)822 firstMatchTest(823 #"(?<!USD)\d+"#, input: "Price: JYP100", match: "100", xfail: true)824 firstMatchTest(825 #"(*nlb:USD)\d+"#, input: "Price: JYP100", match: "100", xfail: true)826 firstMatchTest(827 #"(*negative_lookbehind:USD)\d+"#,828 input: "Price: JYP100", match: "100", xfail: true)829 // engines generally enforce that lookbehinds are fixed width830 firstMatchTest(831 #"\d{3}(?<!USD\d{3})"#, input: "Price: JYP100", match: "100", xfail: true)832 }833 func testMatchAnchors() {834 // MARK: Anchors835 firstMatchTests(836 #"^\d+"#,837 ("123", "123"),838 (" 123", nil),839 ("123 456", "123"),840 (" 123 \n456", nil),841 (" \n123 \n456", nil))842 firstMatchTests(843 #"\d+$"#,844 ("123", "123"),845 (" 123", "123"),846 (" 123 \n456", "456"),847 (" 123\n456", "456"),848 ("123 456", "456"))849 firstMatchTests(850 #"\A\d+"#,851 ("123", "123"),852 (" 123", nil),853 (" 123 \n456", nil),854 (" 123\n456", nil),855 ("123 456", "123"))856 firstMatchTests(857 #"\d+\Z"#,858 ("123", "123"),859 (" 123", "123"),860 ("123\n", "123"),861 (" 123\n", "123"),862 (" 123 \n456", "456"),863 (" 123\n456", "456"),864 (" 123\n456\n", "456"),865 ("123 456", "456"))866 firstMatchTests(867 #"\d+\z"#,868 ("123", "123"),869 (" 123", "123"),870 ("123\n", nil),871 (" 123\n", nil),872 (" 123 \n456", "456"),873 (" 123\n456", "456"),874 (" 123\n456\n", nil),875 ("123 456", "456"))876 firstMatchTests(877 #"\d+\b"#,878 ("123", "123"),879 (" 123", "123"),880 ("123 456", "123"),881 ("123A 456", "456"))882 firstMatchTests(883 #"\d+\b\s\b\d+"#,884 ("123", nil),885 (" 123", nil),886 ("123 456", "123 456"))887 firstMatchTests(888 #"\B\d+"#,889 ("123", "23"),890 (" 123", "23"),891 ("123 456", "23"))892 // TODO: \G and \K893 // TODO: Oniguruma \y and \Y894 firstMatchTests(895 #"\u{65}"#, // Scalar 'e' is present in both896 ("Cafe\u{301}", nil), // but scalar mode requires boundary at end of match897 xfail: true)898 firstMatchTests(899 #"\u{65}"#, // Scalar 'e' is present in both900 ("Sol Cafe", "e")) // standalone is okay901 firstMatchTests(902 #"\u{65}\y"#, // Grapheme boundary assertion903 ("Cafe\u{301}", nil),904 ("Sol Cafe", "e"))905 906 // FIXME: Figure out (?X) and (?u) semantics907 firstMatchTests(908 #"(?u)\u{65}\Y"#, // Grapheme non-boundary assertion909 ("Cafe\u{301}", "e"),910 ("Sol Cafe", nil), xfail: true)911 }912 func testMatchGroups() {913 // MARK: Groups914 // Named captures915 firstMatchTest(916 #"a(?<label>b)c"#, input: "123abcxyz", match: "abc")917 firstMatchTest(918 #"a(?'label'b)c"#, input: "123abcxyz", match: "abc")919 firstMatchTest(920 #"a(?P<label>b)c"#, input: "123abcxyz", match: "abc")921 // Other groups922 firstMatchTest(923 #"a(?:b)c"#, input: "123abcxyz", match: "abc")924 firstMatchTest(925 "(?|(a)|(b)|(c))", input: "123abcxyz", match: "a", xfail: true)926 firstMatchTest(927 #"(?:a|.b)c"#, input: "123abcacxyz", match: "abc")928 firstMatchTest(929 #"(?>a|.b)c"#, input: "123abcacxyz", match: "ac", xfail: true)930 firstMatchTest(931 "(*atomic:a|.b)c", input: "123abcacxyz", match: "ac", xfail: true)932 firstMatchTest(933 #"(?:a+)[a-z]c"#, input: "123aacacxyz", match: "aac")934 firstMatchTest(935 #"(?>a+)[a-z]c"#, input: "123aacacxyz", match: "ac", xfail: true)936 // TODO: Test example where non-atomic is significant937 firstMatchTest(938 #"\d+(?* dollars)"#,939 input: "Price: 100 dollars", match: "100", xfail: true)940 firstMatchTest(941 #"(?*\d+ dollars)\d+"#,942 input: "Price: 100 dollars", match: "100", xfail: true)943 firstMatchTest(944 #"\d+(*napla: dollars)"#,945 input: "Price: 100 dollars", match: "100", xfail: true)946 firstMatchTest(947 #"\d+(*non_atomic_positive_lookahead: dollars)"#,948 input: "Price: 100 dollars", match: "100", xfail: true)949 // TODO: Test example where non-atomic is significant950 firstMatchTest(951 #"(?<*USD)\d+"#, input: "Price: USD100", match: "100", xfail: true)952 firstMatchTest(953 #"(*naplb:USD)\d+"#, input: "Price: USD100", match: "100", xfail: true)954 firstMatchTest(955 #"(*non_atomic_positive_lookbehind:USD)\d+"#,956 input: "Price: USD100", match: "100", xfail: true)957 // engines generally enforce that lookbehinds are fixed width958 firstMatchTest(959 #"\d{3}(?<*USD\d{3})"#, input: "Price: USD100", match: "100", xfail: true)960 // https://www.effectiveperlprogramming.com/2019/03/match-only-the-same-unicode-script/961 firstMatchTest(962 #"abc(*sr:\d+)xyz"#, input: "abcÛµÛ²Û¸528੫੨੮xyz", match: "ÛµÛ²Û¸", xfail: true)963 firstMatchTest(964 #"abc(*script_run:\d+)xyz"#,965 input: "abcÛµÛ²Û¸528੫੨੮xyz", match: "ÛµÛ²Û¸", xfail: true)966 // TODO: Test example where atomic is significant967 firstMatchTest(968 #"abc(*asr:\d+)xyz"#, input: "abcÛµÛ²Û¸528੫੨੮xyz", match: "ÛµÛ²Û¸", xfail: true)969 firstMatchTest(970 #"abc(*atomic_script_run:\d+)xyz"#,971 input: "abcÛµÛ²Û¸528੫੨੮xyz", match: "ÛµÛ²Û¸", xfail: true)972 }973 func testMatchCaptureBehavior() {974 flatCaptureTest(975 #"a(b)c|abe"#,976 ("abc", ["b"]),977 ("abe", [nil]),978 ("axbe", nil))979 flatCaptureTest(980 #"a(bc)d|abce"#,981 ("abcd", ["bc"]),982 ("abce", [nil]),983 ("abxce", nil))984 flatCaptureTest(985 #"a(bc)+d|abce"#,986 ("abcbcbcd", ["bc"]),987 ("abcbce", nil),988 ("abce", [nil]),989 ("abcbbd", nil))990 flatCaptureTest(991 #"a(bc)+d|(a)bce"#,992 ("abcbcbcd", ["bc", nil]),993 ("abce", [nil, "a"]),994 ("abcbbd", nil))995 flatCaptureTest(996 #"a(b|c)+d|(a)bce"#,997 ("abcbcbcd", ["c", nil]),998 ("abce", [nil, "a"]),999 ("abcbbd", ["b", nil]))1000 flatCaptureTest(1001 #"a(b+|c+)d|(a)bce"#,1002 ("abbbd", ["bbb", nil]),1003 ("acccd", ["ccc", nil]),1004 ("abce", [nil, "a"]),1005 ("abbbe", nil),1006 ("accce", nil),1007 ("abcbbd", nil))1008 flatCaptureTest(1009 #"(?:\w\1|:(\w):)+"#,1010 (":a:bacada", ["a"]),1011 (":a:baca:o:boco", ["o"]),1012 ("bacada", nil),1013 (":a:boco", ["a"]) // this matches only the ':a:' prefix1014 )1015 }1016 func testMatchReferences() {1017 firstMatchTest(1018 #"(.)\1"#,1019 input: "112", match: "11")1020 firstMatchTest(1021 #"(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\10"#,1022 input: "aaaaaaaaabbc", match: "aaaaaaaaabb")1023 firstMatchTest(1024 #"(.)(.)(.)(.)(.)(.)(.)(.)(.)(?<a1>.)(?P=a1)"#,1025 input: "aaaaaaaaabbc", match: "aaaaaaaaabb")1026 firstMatchTest(1027 #"(.)\g001"#,1028 input: "112", match: "11")1029 firstMatchTest(#"(?<a>.)(.)\k<a>"#, input: "abac", match: "aba")1030 firstMatchTest(#"(?<a>.)(?<b>.)(?<c>.)\k<c>\k<a>\k<b>"#,1031 input: "xyzzxy", match: "xyzzxy")1032 firstMatchTest(#"\1(.)"#, input: "112", match: nil)1033 firstMatchTest(#"\k<a>(?<a>.)"#, input: "112", match: nil)1034 // TODO: Implement subpattern matching.1035 firstMatchTest(#"(.)(.)\g-02"#, input: "abac", match: "aba", xfail: true)1036 firstMatchTest(#"\g'+2'(.)(.)"#, input: "abac", match: "aba", xfail: true)1037 }1038 1039 func testMatchExamples() {1040 // Backreferences1041 matchTest(1042 #"(sens|respons)e and \1ibility"#,1043 ("sense and sensibility", true),1044 ("response and responsibility", true),1045 ("response and sensibility", false),1046 ("sense and responsibility", false))1047 matchTest(1048 #"a(?'name'b(c))d\1\2|abce"#,1049 ("abcdbcc", true),1050 ("abcdbc", false),1051 ("abce", true)1052 )1053 // Subpatterns1054 matchTest(1055 #"(sens|respons)e and (?1)ibility"#,1056 ("sense and sensibility", true),1057 ("response and responsibility", true),1058 ("response and sensibility", true),1059 ("sense and responsibility", true),1060 xfail: true)1061 // Palindromes1062 matchTest(1063 #"(\w)(?:(?R)|\w?)\1"#,1064 ("abccba", true),1065 ("abcba", true),1066 ("abba", true),1067 ("stackcats", true),1068 ("racecar", true),1069 ("a anna c", true), // OK: Partial match1070 ("abc", false),1071 ("cat", false),1072 xfail: true1073 )1074 matchTest(1075 #"^((\w)(?:(?1)|\w?)\2)$"#,1076 ("abccba", true),1077 ("abcba", true),1078 ("abba", true),1079 ("stackcats", true),1080 ("racecar", true),1081 ("a anna c", false), // FAIL: Not whole line1082 ("abc", false),1083 ("cat", false),1084 xfail: true1085 )1086 // HTML tags1087 matchTest(1088 #"<([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>.*?</\1>"#,1089 ("<html> a b c </html>", true),1090 (#"<table style="float:right"> a b c </table>"#, true),1091 ("<html> a b c </htm>", false),1092 ("<htm> a b c </html>", false),1093 (#"<table style="float:right"> a b c </tab>"#, false)1094 )1095 // Doubled words1096 flatCaptureTest(1097 #"\b(\w+)\s+\1\b"#,1098 ("this does have one one in it", ["one"]),1099 ("pass me the the kettle", ["the"]),1100 ("this doesn't have any", nil)1101 )1102 // Floats1103 flatCaptureTest(1104 #"^([-+])?([0-9]*)(?:\.([0-9]+))?(?:[eE]([-+]?[0-9]+))?$"#,1105 ("123.45", [nil, "123", "45", nil]),1106 ("-123e12", ["-", "123", nil, "12"]),1107 ("+123.456E-12", ["+", "123", "456", "-12"]),1108 ("-123e1.2", nil)1109 )1110 }1111 1112 func testSingleLineMode() {1113 firstMatchTest(#".+"#, input: "a\nb", match: "a")1114 firstMatchTest(#"(?s:.+)"#, input: "a\nb", match: "a\nb")1115 }1116 1117 func testCaseSensitivity() {1118 matchTest(1119 #"c..e"#,1120 ("cafe", true),1121 ("Cafe", false))1122 matchTest(1123 #"(?i)c.f."#,1124 ("cafe", true),1125 ("Cafe", true),1126 ("caFe", true))1127 matchTest(1128 #"(?i)cafe"#,1129 ("cafe", true),1130 ("Cafe", true),1131 ("caFe", true))1132 matchTest(1133 #"(?i)café"#,1134 ("café", true),1135 ("CafÃ", true))1136 matchTest(1137 #"(?i)\u{63}af\u{e9}"#,1138 ("café", true),1139 ("CafÃ", true))1140 1141 matchTest(1142 #"[caFE]{4}"#,1143 ("cafe", false),1144 ("CAFE", false),1145 ("caFE", true),1146 ("EFac", true))1147 matchTest(1148 #"(?i)[caFE]{4}"#,1149 ("cafe", true),1150 ("CaFe", true),1151 ("EfAc", true))1152 matchTest(1153 #"(?i)[a-f]{4}"#,1154 ("cafe", true),1155 ("CaFe", true),1156 ("EfAc", true))1157 }1158 func testNonSemanticWhitespace() {1159 firstMatchTest(#" \t "#, input: " \t ", match: " \t ")1160 firstMatchTest(#"(?xx) \t "#, input: " \t ", match: "\t")1161 firstMatchTest(#"[ \t]+"#, input: " \t ", match: " \t ")1162 firstMatchTest(#"(?xx)[ \t]+"#, input: " \t ", match: "\t")1163 firstMatchTest(#"(?xx)[ \t]+"#, input: " \t\t ", match: "\t\t")1164 firstMatchTest(#"(?xx)[ \t]+"#, input: " \t \t", match: "\t")1165 firstMatchTest("(?xx)[ a && ab ]+", input: " aaba ", match: "aa")1166 1167 // Preserve whitespace in quoted section inside extended syntax region1168 firstMatchTest(1169 #"(?x) a b \Q c d \E e f"#, input: "ab c d ef", match: "ab c d ef")1170 firstMatchTest(1171 #"(?x)[a b]+ _ [a\Q b\E]+"#, input: "aba_ a b a", match: "aba_ a b a")1172 firstMatchTest(1173 #"(?x)[a b]+ _ [a\Q b\E]+"#, input: "aba _ a b a", match: nil)1174 }1175 1176 func testASCIIClasses() {1177 // 'D' ASCII-only digits1178 matchTest(1179 #"\d+"#,1180 ("123", true),1181 ("¹೨¾", true))1182 matchTest(1183 #"(?D)\d+"#,1184 ("123", true),1185 ("¹೨¾", false))1186 matchTest(1187 #"(?P)\d+"#,1188 ("123", true),1189 ("¹೨¾", false))1190 // 'W' ASCII-only word characters (and word boundaries)1191 matchTest(1192 #"\w+"#,1193 ("aeiou", true),1194 ("Ã¥e\u{301}ïôú", true))1195 matchTest(1196 #"(?W)\w+"#,1197 ("aeiou", true),1198 ("Ã¥e\u{301}ïôú", false))1199 matchTest(1200 #"(?P)\w+"#,1201 ("aeiou", true),1202 ("Ã¥e\u{301}ïôú", false))1203 matchTest(1204 #"abcd\b.+"#,1205 ("abcd ef", true),1206 ("abcdef", false),1207 ("abcdéf", false))1208 matchTest(1209 #"(?W)abcd\b.+"#,1210 ("abcd ef", true),1211 ("abcdef", false),1212 ("abcdéf", true)) // "dé" matches /d\b./ because "é" isn't ASCII1213 matchTest(1214 #"(?P)abcd\b.+"#,1215 ("abcd ef", true),1216 ("abcdef", false),1217 ("abcdéf", true)) // "dé" matches /d\b./ because "é" isn't ASCII1218 // 'S' ASCII-only spaces1219 matchTest(1220 #"a\sb"#,1221 ("a\tb", true),1222 ("a\u{202f}b", true)) // NARROW NO-BREAK SPACE1223 matchTest(1224 #"(?S)a\sb"#,1225 ("a\tb", true),1226 ("a\u{202f}b", false))1227 matchTest(1228 #"(?P)a\sb"#,1229 ("a\tb", true),1230 ("a\u{202f}b", false))1231 }1232 1233 func testAnchorMatching() throws {1234 let string = """1235 01: Alabama1236 02: Alaska1237 03: Arizona1238 04: Arkansas1239 05: California1240 """1241 XCTAssertTrue(string.contains(try Regex(#"^\d+"#)))1242 XCTAssertEqual(string.ranges(of: try Regex(#"^\d+"#)).count, 1)1243 XCTAssertEqual(string.ranges(of: try Regex(#"(?m)^\d+"#)).count, 5)1244 let regex = try Regex(#"^\d+: [\w ]+$"#)1245 XCTAssertFalse(string.contains(regex))1246 let allRanges = string.ranges(of: regex.anchorsMatchLineEndings())1247 XCTAssertEqual(allRanges.count, 5)1248 }1249 1250 func testMatchingOptionsScope() {1251 // `.` only matches newlines when the 's' option (single-line mode)1252 // is turned on. Standalone option-setting groups (e.g. `(?s)`) are1253 // scoped only to the current group.1254 1255 firstMatchTest(#"(?s)a.b"#, input: "a\nb", match: "a\nb")1256 firstMatchTest(#"((?s)a.)b"#, input: "a\nb", match: "a\nb")1257 firstMatchTest(#"(?-s)((?s)a.)b"#, input: "a\nb", match: "a\nb")1258 firstMatchTest(#"(?-s)(?s:a.)b"#, input: "a\nb", match: "a\nb")1259 firstMatchTest(#"((?s)a).b"#, input: "a\nb", match: nil)1260 firstMatchTest(#"((?s))a.b"#, input: "a\nb", match: nil)1261 firstMatchTest(#"(?:(?s))a.b"#, input: "a\nb", match: nil)1262 firstMatchTest(#"((?s)a(?s)).b"#, input: "a\nb", match: nil)1263 firstMatchTest(#"(?s)a(?-s).b"#, input: "a\nb", match: nil)1264 firstMatchTest(#"(?s)a(?-s:.b)"#, input: "a\nb", match: nil)1265 firstMatchTest(#"(?:(?s)a).b"#, input: "a\nb", match: nil)1266 firstMatchTest(#"(((?s)a)).b"#, input: "a\nb", match: nil)1267 firstMatchTest(#"(?s)(((?-s)a)).b"#, input: "a\nb", match: "a\nb")1268 firstMatchTest(#"(?s)((?-s)((?i)a)).b"#, input: "a\nb", match: "a\nb")1269 // Matching option changing persists across alternations.1270 firstMatchTest(#"a(?s)b|c|.d"#, input: "abc", match: "ab")1271 firstMatchTest(#"a(?s)b|c|.d"#, input: "c", match: "c")1272 firstMatchTest(#"a(?s)b|c|.d"#, input: "a\nd", match: "\nd")1273 firstMatchTest(#"a(?s)(?^)b|c|.d"#, input: "a\nd", match: nil)1274 firstMatchTest(#"a(?s)b|.c(?-s)|.d"#, input: "a\nd", match: nil)1275 firstMatchTest(#"a(?s)b|.c(?-s)|.d"#, input: "a\nc", match: "\nc")1276 firstMatchTest(#"a(?s)b|c(?-s)|(?^s).d"#, input: "a\nd", match: "\nd")1277 firstMatchTest(#"a(?:(?s).b)|.c|.d"#, input: "a\nb", match: "a\nb")1278 firstMatchTest(#"a(?:(?s).b)|.c"#, input: "a\nc", match: nil)1279 }1280 1281 func testOptionMethods() throws {1282 let regex = try Regex("c.f.")1283 XCTAssertTrue ("cafe".contains(regex))1284 XCTAssertFalse("CaFe".contains(regex))1285 1286 let caseInsensitiveRegex = regex.ignoresCase()1287 XCTAssertTrue("cafe".contains(caseInsensitiveRegex))1288 XCTAssertTrue("CaFe".contains(caseInsensitiveRegex))1289 }1290 1291 // MARK: Character Semantics1292 1293 var eComposed: String { "é" }1294 var eDecomposed: String { "e\u{301}" }1295 1296 func testIndividualScalars() {1297 // Expectation: A standalone Unicode scalar value in a regex literal1298 // can match either that specific scalar value or participate in matching1299 // as a character.1300 firstMatchTest(#"\u{65}\u{301}$"#, input: eDecomposed, match: eDecomposed)1301 firstMatchTest(#"\u{65}\u{301}$"#, input: eComposed, match: eComposed)1302 firstMatchTest(#"\u{65 301}$"#, input: eDecomposed, match: eDecomposed)1303 firstMatchTest(#"\u{65 301}$"#, input: eComposed, match: eComposed)1304 // FIXME: Implicit \y at end of match1305 firstMatchTest(#"\u{65}"#, input: eDecomposed, match: nil,1306 xfail: true)1307 firstMatchTest(#"\u{65}$"#, input: eDecomposed, match: nil)1308 // FIXME: \y is unsupported1309 firstMatchTest(#"\u{65}\y"#, input: eDecomposed, match: nil,1310 xfail: true)1311 // FIXME: Unicode scalars are only matched at the start of a grapheme cluster1312 firstMatchTest(#"\u{301}"#, input: eDecomposed, match: "\u{301}",1313 xfail: true)1314 // FIXME: \y is unsupported1315 firstMatchTest(#"\y\u{301}"#, input: eDecomposed, match: nil,1316 xfail: true)1317 }1318 func testCanonicalEquivalence() throws {1319 // Expectation: Matching should use canonical equivalence whenever comparing1320 // characters, so a user can write characters using any equivalent spelling1321 // in either a regex literal or the string targeted for matching.1322 1323 matchTest(1324 #"é$"#,1325 (eComposed, true),1326 (eDecomposed, true))1327 matchTest(1328 #"e\u{301}$"#,1329 (eComposed, true),1330 (eDecomposed, true))1331 matchTest(1332 #"e$"#,1333 (eComposed, false),1334 (eDecomposed, false))1335 }1336 func testCanonicalEquivalenceCharacterClass() throws {1337 // Expectation: Character classes should match equivalent characters to the1338 // same degree, regardless of how they are spelled. Unicode "property1339 // classes" should match characters when all the code points that comprise1340 // the character are members of the property class.1341 1342 // \w1343 matchTest(1344 #"^\w$"#,1345 (eComposed, true),1346 (eDecomposed, true))1347 // \p{Letter}1348 firstMatchTest(#"\p{Letter}$"#, input: eComposed, match: eComposed)1349 firstMatchTest(#"\p{Letter}$"#, input: eDecomposed, match: eDecomposed)1350 1351 // \d1352 firstMatchTest(#"\d"#, input: "5", match: "5")1353 // FIXME: \d shouldn't match a digit composed with a non-digit character1354 firstMatchTest(#"\d"#, input: "5\u{305}", match: nil,1355 xfail: true)1356 // \p{Number}1357 firstMatchTest(#"\p{Number}"#, input: "5", match: "5")1358 // FIXME: \p{Number} shouldn't match a number composed with a non-number character1359 firstMatchTest(#"\p{Number}"#, input: "5\u{305}", match: nil,1360 xfail: true)1361 1362 // Should this match the '5' but not the ZWJ, or should it treat '5'+ZWJ1363 // as one entity and fail to match altogether?1364 firstMatchTest(#"^\d"#, input: "5\u{200d}0", match: "5",1365 xfail: true)1366 1367 // \s1368 firstMatchTest(#"\s"#, input: " ", match: " ")1369 // FIXME: \s shouldn't match a number composed with a non-number character1370 firstMatchTest(#"\s\u{305}"#, input: " ", match: nil,1371 xfail: true)1372 // \p{Whitespace}1373 firstMatchTest(#"\s"#, input: " ", match: " ")1374 // FIXME: \p{Whitespace} shouldn't match whitespace composed with a non-whitespace character1375 firstMatchTest(#"\s\u{305}"#, input: " ", match: nil,1376 xfail: true)1377 }1378 1379 func testCanonicalEquivalenceCustomCharacterClass() throws {1380 // Expectation: Concatenations with custom character classes should be able1381 // to match within a grapheme cluster. That is, a regex should be able to1382 // match the scalar values that comprise a grapheme cluster in separate,1383 // or repeated, custom character classes.1384 1385 matchTest(1386 #"[áéÃóú]$"#,1387 (eComposed, true),1388 (eDecomposed, true))1389 // FIXME: Custom char classes don't use canonical equivalence with composed characters1390 firstMatchTest(#"e[\u{301}]$"#, input: eComposed, match: eComposed,1391 xfail: true)1392 firstMatchTest(#"e[\u{300}-\u{320}]$"#, input: eComposed, match: eComposed,1393 xfail: true)1394 firstMatchTest(#"[a-z][\u{300}-\u{320}]$"#, input: eComposed, match: eComposed,1395 xfail: true)1396 // FIXME: Custom char classes don't match decomposed characters1397 firstMatchTest(#"e[\u{301}]$"#, input: eDecomposed, match: eDecomposed,1398 xfail: true)1399 firstMatchTest(#"e[\u{300}-\u{320}]$"#, input: eDecomposed, match: eDecomposed,1400 xfail: true)1401 firstMatchTest(#"[a-z][\u{300}-\u{320}]$"#, input: eDecomposed, match: eDecomposed,1402 xfail: true)1403 let flag = "ð°ð·"1404 firstMatchTest(#"ð°ð·"#, input: flag, match: flag)1405 firstMatchTest(#"[ð°ð·]"#, input: flag, match: flag)1406 firstMatchTest(#"\u{1F1F0}\u{1F1F7}"#, input: flag, match: flag)1407 firstMatchTest(#"\u{1F1F0 1F1F7}"#, input: flag, match: flag)1408 // First Unicode scalar followed by CCC of regional indicators1409 firstMatchTest(#"\u{1F1F0}[\u{1F1E6}-\u{1F1FF}]"#, input: flag, match: flag,1410 xfail: true)1411 // FIXME: CCC of Regional Indicator doesn't match with both parts of a flag character1412 // A CCC of regional indicators x 21413 firstMatchTest(#"[\u{1F1E6}-\u{1F1FF}]{2}"#, input: flag, match: flag,1414 xfail: true)1415 // FIXME: A single CCC of regional indicators matches the whole flag character1416 // A CCC of regional indicators followed by the second Unicode scalar1417 firstMatchTest(#"[\u{1F1E6}-\u{1F1FF}]\u{1F1F7}"#, input: flag, match: flag,1418 xfail: true)1419 // A single CCC of regional indicators1420 firstMatchTest(#"[\u{1F1E6}-\u{1F1FF}]"#, input: flag, match: nil,1421 xfail: true)1422 1423 // A single CCC of actual flag emojis / combined regional indicators1424 firstMatchTest(#"[ð¦ð«-ð¿ð¼]"#, input: flag, match: flag)1425 // This succeeds (correctly) because \u{1F1F0} is lexicographically1426 // within the CCC range1427 firstMatchTest(#"[ð¦ð«-ð¿ð¼]"#, input: "\u{1F1F0}abc", match: "\u{1F1F0}")1428 }1429 1430 func testAnyChar() throws {1431 // Expectation: \X and, in grapheme cluster mode, `.` should consume an1432 // entire character, regardless of how it's spelled. \O should consume only1433 // a single Unicode scalar value, leaving any other grapheme scalar1434 // components to be matched.1435 1436 // FIXME: Figure out (?X) and (?u) semantics1437 firstMatchTest(#"(?u:.)"#, input: eDecomposed, match: "e", xfail: true)1438 matchTest(1439 #".\u{301}"#,1440 (eComposed, false),1441 (eDecomposed, false))1442 matchTest(1443 #"\X\u{301}"#,1444 (eComposed, false),1445 (eDecomposed, false))1446 1447 // FIXME: Figure out (?X) and (?u) semantics1448 // FIXME: \O is unsupported1449 firstMatchTest(1450 #"(?u)\O\u{301}"#,1451 input: eDecomposed,1452 match: eDecomposed,1453 xfail: true1454 )1455 firstMatchTest(1456 #"(?u)e\O"#,1457 input: eDecomposed,1458 match: eDecomposed,1459 xfail: true1460 )1461 firstMatchTest(#"\O"#, input: eComposed, match: eComposed)1462 firstMatchTest(#"\O"#, input: eDecomposed, match: nil,1463 xfail: true)1464 // FIXME: Figure out (?X) and (?u) semantics1465 matchTest(1466 #"(?u).\u{301}"#,1467 (eComposed, false),1468 (eDecomposed, true), xfail: true)1469 firstMatchTest(#"(?u).$"#, input: eComposed, match: eComposed, xfail: true)1470 1471 // Option permutations for 'u' and 's'1472 matchTest(1473 #"...."#,1474 ("e\u{301}ab", false),1475 ("e\u{301}abc", true),1476 ("e\u{301}\nab", false))1477 matchTest(1478 #"(?s)...."#,1479 ("e\u{301}ab", false),1480 ("e\u{301}abc", true),1481 ("e\u{301}\nab", true))1482 1483 // FIXME: Figure out (?X) and (?u) semantics...
GameViewModelTest.swift
Source:GameViewModelTest.swift
1//2// RPSLSTests.swift3// RPSLSTests4//5// Created by Mark Christian Buot on 12/08/2019.6// Copyright © 2019 Mark Christian Buot. All rights reserved.7//8import XCTest9@testable import RPSLS10enum MoveEnum: Int {11 case Rock = 012 case Paper13 case Scissors14 case Lizard15 case Spock16}17enum TestCase {18 19 case ResultDriven20 case ScoreDriven21}22class GameViewModelTest: XCTestCase {23 var gameManager: MockGameManager?24 var gameMode: GameMode?25 var viewModel: GameViewModel?26 var testCase: TestCase?27 var expectedResult: GameManager.GameResult?28 29 override func setUp() {30 // Put setup code here. This method is called before the invocation of each test method in the class.31 }32 override func tearDown() {33 // Put teardown code here. This method is called after the invocation of each test method in the class.34 }35 func createDependency(game: GameMode.Game) {36 gameMode = GameMode(playType: .PVC)37 gameMode?.game = game38 gameManager = MockGameManager(gameMode: gameMode)39 viewModel = ViewModelFactory.createGameViewModel(gameManager: gameManager,40 gameMode: gameMode,41 delegate: self)42 }43 44 func matchTest(computer: Move?,45 index: Int,46 expectedResult: GameManager.GameResult) {47 self.testCase = .ResultDriven48 self.expectedResult = expectedResult49 gameManager?.mockMove = computer50 51 viewModel?.setMoveAt(IndexPath(row: index,52 section: 0))53 54 viewModel?.match()55 }56 57 func testRPSRock() {58 createDependency(game: .RPS)59 60 matchTest(computer: gameManager?.createScissors(),61 index: MoveEnum.Rock.rawValue,62 expectedResult: .Win)63 }64 65 func testRPSPaper() {66 createDependency(game: .RPS)67 68 matchTest(computer: gameManager?.createRock(),69 index: MoveEnum.Paper.rawValue,70 expectedResult: .Win)71 }72 73 func testRPSScissors() {74 createDependency(game: .RPS)75 76 matchTest(computer: gameManager?.createPaper(),77 index: MoveEnum.Scissors.rawValue,78 expectedResult: .Win)79 }80 81 func testRPSLSLizard() {82 createDependency(game: .RPSLS)83 84 matchTest(computer: gameManager?.createSpock(),85 index: MoveEnum.Lizard.rawValue,86 expectedResult: .Win)87 }88 89 func testRPSLSSpock() {90 createDependency(game: .RPSLS)91 92 matchTest(computer: gameManager?.createScissors(),93 index: MoveEnum.Spock.rawValue,94 expectedResult: .Win)95 }96 97 func testRPSRockDraw() {98 createDependency(game: .RPS)99 100 matchTest(computer: gameManager?.createRock(),101 index: MoveEnum.Rock.rawValue,102 expectedResult: .Draw)103 }104 105 func testRPSPaperDraw() {106 createDependency(game: .RPS)107 108 matchTest(computer: gameManager?.createPaper(),109 index: MoveEnum.Paper.rawValue,110 expectedResult: .Draw)111 }112 113 func testRPSScissorsDraw() {114 createDependency(game: .RPS)115 116 matchTest(computer: gameManager?.createScissors(),117 index: MoveEnum.Scissors.rawValue,118 expectedResult: .Draw)119 }120 121 func testRPSLSLizardDraw() {122 createDependency(game: .RPSLS)123 124 matchTest(computer: gameManager?.createLizard(),125 index: MoveEnum.Lizard.rawValue,126 expectedResult: .Draw)127 }128 129 func testRPSLSSpockDraw() {130 createDependency(game: .RPSLS)131 132 matchTest(computer: gameManager?.createSpock(),133 index: MoveEnum.Spock.rawValue,134 expectedResult: .Draw)135 }136 137 func testRPSRockLose() {138 createDependency(game: .RPS)139 140 matchTest(computer: gameManager?.createPaper(),141 index: MoveEnum.Rock.rawValue,142 expectedResult: .Lose)143 }144 145 func testRPSPaperLose() {146 createDependency(game: .RPS)147 148 matchTest(computer: gameManager?.createScissors(),149 index: MoveEnum.Paper.rawValue,150 expectedResult: .Lose)151 }152 153 func testRPSScissorsLose() {154 createDependency(game: .RPS)155 156 matchTest(computer: gameManager?.createRock(),157 index: MoveEnum.Scissors.rawValue,158 expectedResult: .Lose)159 }160 161 func testRPSLSLizardLose() {162 createDependency(game: .RPSLS)163 164 matchTest(computer: gameManager?.createRock(),165 index: MoveEnum.Lizard.rawValue,166 expectedResult: .Lose)167 }168 169 func testRPSLSSpockLose() {170 createDependency(game: .RPSLS)171 172 matchTest(computer: gameManager?.createLizard(),173 index: MoveEnum.Spock.rawValue,174 expectedResult: .Lose)175 }176 177 func testRPSLSPaperVsLizard() {178 createDependency(game: .RPSLS)179 180 matchTest(computer: gameManager?.createLizard(),181 index: MoveEnum.Paper.rawValue,182 expectedResult: .Lose)183 }184 185 func testRPSLSScissorsVsSpock() {186 createDependency(game: .RPSLS)187 188 matchTest(computer: gameManager?.createSpock(),189 index: MoveEnum.Scissors.rawValue,190 expectedResult: .Lose)191 }192 193 func testScoreComputer() {194 createDependency(game: .RPS)195 196 testCase = .ScoreDriven197 gameManager?.mockMove = gameManager?.createPaper()198 199 viewModel?.setMoveAt(IndexPath(row: MoveEnum.Rock.rawValue,200 section: 0))201 202 viewModel?.match()203 }204}205extension GameViewModelTest: BaseViewModelDelegate {206 func didUpdateViewmodel(_ viewModel: BaseViewModel) {207 let result = self.viewModel?.getResult()208 if testCase == .ResultDriven {209 XCTAssert(result == expectedResult, "Should win")210 } else {211 if result == .Lose {212 XCTAssert(gameManager?.score.computer == 1,213 "Computer should score 1 after winning")214 } else {215 XCTFail("Should be lose")216 }217 }218 }219}...
EncodableRule.swift
Source:EncodableRule.swift
...8import Foundation9fileprivate enum EncoderKeys: String {10 case BrowserIdentifier = "browserIdentifier"11 case MatchType = "match.type"12 case MatchTest = "match.test"13}14@objc(RedirectionDataEncodableRule)15public class EncodableRule : NSObject, NSCoding {16 public let rule: Rule17 public init(_ rule: Rule) {18 self.rule = rule19 }20 required public init?(coder aDecoder: NSCoder) {21 guard22 let browserIdentifier = aDecoder.decodeObject(of: NSString.self, forKey: EncoderKeys.BrowserIdentifier.rawValue) as String?,23 let matchTypeValue = aDecoder.decodeObject(of: NSNumber.self, forKey: EncoderKeys.MatchType.rawValue) as? Int,24 let matchType = MatchType(rawValue: matchTypeValue),25 let matchTest = aDecoder.decodeObject(of: NSString.self, forKey: EncoderKeys.MatchTest.rawValue) as String?26 else { return nil }27 self.rule = Rule(browserIdentifier: BundleIdentifier(value: browserIdentifier), match: Match(type: matchType, test: matchTest))28 }29 public func encode(with aCoder: NSCoder) {30 aCoder.encode(rule.browserIdentifier.value as NSString, forKey: EncoderKeys.BrowserIdentifier.rawValue)31 aCoder.encode(rule.match.type.rawValue, forKey: EncoderKeys.MatchType.rawValue)32 aCoder.encode(rule.match.test as NSString, forKey: EncoderKeys.MatchTest.rawValue)33 }34}35extension EncodableRule : NSSecureCoding {36 public static var supportsSecureCoding: Bool { return true }37}
MatchTest
Using AI Code Generation
1import Nimble2import Quick3class MatchTestSpec: QuickSpec {4 override func spec() {5 describe("MatchTest") {6 it("should return true") {7 let matchTest = MatchTest()8 expect(matchTest.isMatch("abc", "abc")).to(beTrue())9 }10 }11 }12}13import Nimble14import Quick15class MatchTestSpec: QuickSpec {16 override func spec() {17 describe("MatchTest") {18 it("should return false") {19 let matchTest = MatchTest()20 expect(matchTest.isMatch("abc", "ab")).to(beFalse())21 }22 }23 }24}25import Nimble26import Quick27class MatchTestSpec: QuickSpec {28 override func spec() {29 describe("MatchTest") {30 it("should return true") {31 let matchTest = MatchTest()32 expect(matchTest.isMatch("abc", "a.c")).to(beTrue())33 }34 }35 }36}37import Nimble38import Quick39class MatchTestSpec: QuickSpec {40 override func spec() {41 describe("MatchTest") {42 it("should return true") {43 let matchTest = MatchTest()44 expect(matchTest.isMatch("abc", "ab*")).to(beTrue())45 }46 }47 }48}49import Nimble50import Quick51class MatchTestSpec: QuickSpec {52 override func spec() {53 describe("MatchTest") {54 it("should return true") {55 let matchTest = MatchTest()56 expect(matchTest.isMatch("abc", ".*")).to(beTrue())57 }58 }59 }60}61import Nimble62import Quick63class MatchTestSpec: QuickSpec {64 override func spec() {65 describe("MatchTest") {66 it("should return true") {67 let matchTest = MatchTest()68 expect(matchTest.isMatch("abc", ".*c")).to(beTrue())69 }70 }71 }72}
MatchTest
Using AI Code Generation
1import Nimble2import Quick3class MatchTest: QuickSpec {4 override func spec() {5 describe("MatchTest") {6 it("matches") {7 expect(1).to(match(1))8 }9 }10 }11}12import Quick13import Nimble14class MatchTest: QuickSpec {15 override func spec() {16 describe("MatchTest") {17 it("matches") {18 expect(1).to(match(1))19 }20 }21 }22}23import Quick24import Nimble25class MatchTest: QuickSpec {26 override func spec() {27 describe("MatchTest") {28 it("matches") {29 expect(1).to(match(1))30 }31 }32 }33}34import Quick35import Nimble36class MatchTest: QuickSpec {37 override func spec() {38 describe("MatchTest") {39 it("matches") {40 expect(1).to(match(1))41 }42 }43 }44}45import Quick46import Nimble47class MatchTest: QuickSpec {48 override func spec() {49 describe("MatchTest") {50 it("matches") {51 expect(1).to(match(1))52 }53 }54 }55}56import Quick57import Nimble58class MatchTest: QuickSpec {59 override func spec() {60 describe("MatchTest") {61 it("matches") {62 expect(1).to(match(1))63 }64 }65 }66}67import Quick68import Nimble69class MatchTest: QuickSpec {70 override func spec() {71 describe("MatchTest") {72 it("matches") {73 expect(1).to(match(1))74 }75 }76 }77}78import Quick79import Nimble80class MatchTest: QuickSpec {81 override func spec() {82 describe("MatchTest") {
MatchTest
Using AI Code Generation
1import Nimble2import Quick3class MatchTest: QuickSpec {4 override func spec() {5 describe("MatchTest") {6 it("should match") {7 expect(1).to(match(1))8 }9 }10 }11}12import Nimble13import Quick14class MatchTest: QuickSpec {15 override func spec() {16 describe("MatchTest") {17 it("should match") {18 expect(1).to(match(1))19 }20 }21 }22}23import Nimble24import Quick25class MatchTest: QuickSpec {26 override func spec() {27 describe("MatchTest") {28 it("should match") {29 expect(1).to(match(1))30 }31 }32 }33}34import Nimble35import Quick36class MatchTest: QuickSpec {37 override func spec() {38 describe("MatchTest") {39 it("should match") {40 expect(1).to(match(1))41 }42 }43 }44}45import Nimble46import Quick47class MatchTest: QuickSpec {48 override func spec() {49 describe("MatchTest") {50 it("should match") {51 expect(1).to(match(1))52 }53 }54 }55}56import Nimble57import Quick58class MatchTest: QuickSpec {59 override func spec() {60 describe("MatchTest") {61 it("should match") {62 expect(1).to(match(1))63 }64 }65 }66}67import Nimble68import Quick69class MatchTest: QuickSpec {70 override func spec() {71 describe("MatchTest") {72 it("should match") {73 expect(1).to(match(1))74 }75 }76 }77}78import Nimble79import Quick
MatchTest
Using AI Code Generation
1import Nimble2import Quick3class MatchTest: QuickSpec {4 override func spec() {5 describe("match") {6 it("matches") {7 expect("abc").to(match("abc"))8 }9 }10 }11}12import Quick13import Nimble14class MatchTest: QuickSpec {15 override func spec() {16 describe("match") {17 it("matches") {18 expect("abc").to(match("abc"))19 }20 }21 }22}23I have the same problem, but it doesn't work for me. I have tried to change the order of the imports, but it didn't work. Then, I have
MatchTest
Using AI Code Generation
1import Nimble2import Quick3import XCTest4class TestClass: QuickSpec {5 override func spec() {6 describe("matchTest") {7 it("test") {8 expect(1).to(matchTest())9 }10 }11 }12}13class MatchTest: MatcherFunc<Int> {14 override func matches(_ actualExpression: Expression<Int>, failureMessage: FailureMessage) -> Bool {15 }16}17import Nimble18import Quick19import XCTest20class TestClass: QuickSpec {21 override func spec() {22 describe("matchTest") {23 it("test") {24 expect(1).to(matchTest())25 }26 }27 }28}29class MatchTest: MatcherFunc<Int> {30 override func matches(_ actualExpression: Expression<Int>, failureMessage: FailureMessage) -> Bool {31 }32}33import Nimble34import Quick35import XCTest36class TestClass: QuickSpec {37 override func spec() {38 describe("matchTest") {39 it("test") {40 expect(1).to(matchTest())41 }42 }43 }44}45class MatchTest: MatcherFunc<Int> {46 override func matches(_ actualExpression: Expression<Int>, failureMessage: FailureMessage) -> Bool {47 }48}49import Nimble50import Quick51import XCTest52class TestClass: QuickSpec {53 override func spec() {54 describe("matchTest") {55 it("test") {56 expect(1).to(matchTest())57 }58 }59 }60}61class MatchTest: MatcherFunc<Int> {62 override func matches(_ actualExpression: Expression<Int>, failureMessage: FailureMessage) -> Bool {63 }64}65import Nimble66import Quick67import XCTest68class TestClass: QuickSpec {69 override func spec() {70 describe("matchTest") {71 it("test") {72 expect(1).to(matchTest())73 }74 }75 }76}77class MatchTest: MatcherFunc<Int> {78 override func matches(_ actualExpression: Expression<Int>, failure
MatchTest
Using AI Code Generation
1import Nimble2import Quick3class MatchTest: QuickSpec {4 override func spec() {5 describe("Match Test") {6 it("should check if the string matches the regex") {7 expect("Hello World").to(match("Hello World"))8 }9 }10 }11}12import Nimble13import Quick14class MatchTest: QuickSpec {15 override func spec() {16 describe("Match Test") {17 it("should check if the string matches the regex") {18 expect("Hello World").to(match("Hello World"))19 }20 }21 }22}23import Nimble24import Quick25class MatchTest: QuickSpec {26 override func spec() {27 describe("Match Test") {28 it("should check if the string matches the regex") {29 expect("Hello World").to(match("Hello World"))30 }31 }32 }33}34import Nimble35import Quick36class MatchTest: QuickSpec {37 override func spec() {38 describe("Match Test") {39 it("should check if the string matches the regex") {40 expect("Hello World").to(match("Hello World"))41 }42 }43 }44}45import Nimble46import Quick47class MatchTest: QuickSpec {48 override func spec() {49 describe("Match Test") {50 it("should check if the string matches the regex") {51 expect("Hello World").to(match("Hello World"))52 }53 }54 }55}56import Nimble57import Quick58class MatchTest: QuickSpec {59 override func spec() {60 describe("Match Test") {61 it("should check if the string matches the regex") {62 expect("Hello World").to(match("Hello World"))63 }64 }65 }66}67import Nimble68import Quick69class MatchTest: QuickSpec {70 override func spec() {71 describe("Match Test") {72 it("should check if the string matches
MatchTest
Using AI Code Generation
1import Nimble2import Quick3class MatchTest: QuickSpec {4 override func spec() {5 describe("Match Test") {6 it("should be able to use match test") {7 expect(str1).to(match(str2))8 }9 }10 }11}12import Nimble13import Quick14class MatchTest: QuickSpec {15 override func spec() {16 describe("Match Test") {17 it("should be able to use match test") {18 expect(str1).to(match(str2))19 }20 }21 }22}23import Nimble24import Quick25class NimbleMatchTest: QuickSpec {26 override func spec() {27 describe("Match Test") {28 it("should be able to use match test") {29 expect(str1).to(match(str2))30 }31 }32 }33}34import Nimble35import Quick36class QuickMatchTest: QuickSpec {37 override func spec() {38 describe("Match Test") {39 it("should be able to use match test") {40 expect(str1).to(match(str2))41 }42 }43 }44}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!