diff --git a/Example/Podfile.lock b/Example/Podfile.lock index f3f496c..972bb40 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - markymark (9.2.1) + - markymark (10.1.1) - SwiftLint (0.28.1) DEPENDENCIES: @@ -15,9 +15,9 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - markymark: e7fa1cdb7ad51c21a46cda308ad8ef4511fa49f6 + markymark: 29adb8789fa6b3db97b04b7585d65f13931b5aa5 SwiftLint: 7f5f7de0da74a649b16616cb5246ae323489656e PODFILE CHECKSUM: e6179d5e64bda0057471cea1521ff93bf207a88b -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.0 diff --git a/Example/Tests/Rules/Block/LinkRuleTests.swift b/Example/Tests/Rules/Block/LinkRuleTests.swift deleted file mode 100644 index 75473a5..0000000 --- a/Example/Tests/Rules/Block/LinkRuleTests.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// Created by Maren Osnabrug on 10-05-16. -// Copyright © 2016 M2mobi. All rights reserved. -// - -import XCTest -@testable import markymark - -class LinkRuleTests: XCTestCase { - - var sut: LinkRule! - - override func setUp() { - super.setUp() - sut = LinkRule() - } - - func testRecognizesLines() { - XCTAssertTrue(sut.recognizesLines(["[Alt text](image.png)"])) - XCTAssertFalse((sut.recognizesLines(["![Alt text](image.png)"]))) - } - - func testCreateMarkDownItemWithLinesCreatesCorrectItem() { - //Arrange - let markDownItem = sut.createMarkDownItemWithLines(["[Google](http://www.google.com)"]) - //Act - - //Assert - XCTAssert(markDownItem is LinkMarkDownItem) - } - - func testCreateMarkDownItemContainsCorrectLink() { - //Arrange - let markDownItem = sut.createMarkDownItemWithLines(["[Google](http://www.google.com)"]) - let markDownItem2 = sut.createMarkDownItemWithLines(["[Youtube](http://www.youtube.com)"]) - - //Act - - //Assert - XCTAssertEqual((markDownItem as! LinkMarkDownItem).content, "Google") - XCTAssertEqual((markDownItem as! LinkMarkDownItem).url, "http://www.google.com") - XCTAssertEqual((markDownItem2 as! LinkMarkDownItem).content, "Youtube") - XCTAssertEqual((markDownItem2 as! LinkMarkDownItem).url, "http://www.youtube.com") - - } - - func testGetAllMatches() { - //Arrange - let expectedMatchesRange = NSRange(location: 0, length: 32) - let expectedMatchesRange2 = NSRange(location: 38, length: 32) - //Act - - //Assert - XCTAssertEqual(sut.getAllMatches(["[Google](https://www.google.com)"]), [expectedMatchesRange]) - XCTAssertEqual(sut.getAllMatches(["(https://www.google.com)"]).count, 0) - XCTAssertEqual(sut.getAllMatches(["[Google]"]).count, 0) - XCTAssertEqual(sut.getAllMatches(["![Google](https://www.google.com)"]).count, 0) - XCTAssertEqual(sut.getAllMatches(["[Google](https://www.google.com) test [Google](https://www.google.com)"]), [expectedMatchesRange, expectedMatchesRange2]) - } - -} diff --git a/Example/Tests/Rules/Block/BoldRuleTests.swift b/Example/Tests/Rules/Inline/BoldRuleTests.swift similarity index 100% rename from Example/Tests/Rules/Block/BoldRuleTests.swift rename to Example/Tests/Rules/Inline/BoldRuleTests.swift diff --git a/Example/Tests/Rules/Block/ImageRuleTests.swift b/Example/Tests/Rules/Inline/ImageRuleTests.swift similarity index 100% rename from Example/Tests/Rules/Block/ImageRuleTests.swift rename to Example/Tests/Rules/Inline/ImageRuleTests.swift diff --git a/Example/Tests/Rules/Block/InlineCodeRuleTests.swift b/Example/Tests/Rules/Inline/InlineCodeRuleTests.swift similarity index 100% rename from Example/Tests/Rules/Block/InlineCodeRuleTests.swift rename to Example/Tests/Rules/Inline/InlineCodeRuleTests.swift diff --git a/Example/Tests/Rules/Block/InlineTextRuleTests.swift b/Example/Tests/Rules/Inline/InlineTextRuleTests.swift similarity index 100% rename from Example/Tests/Rules/Block/InlineTextRuleTests.swift rename to Example/Tests/Rules/Inline/InlineTextRuleTests.swift diff --git a/Example/Tests/Rules/Block/ItalicRuleTests.swift b/Example/Tests/Rules/Inline/ItalicRuleTests.swift similarity index 100% rename from Example/Tests/Rules/Block/ItalicRuleTests.swift rename to Example/Tests/Rules/Inline/ItalicRuleTests.swift diff --git a/Example/Tests/Rules/Inline/LinkRuleTests.swift b/Example/Tests/Rules/Inline/LinkRuleTests.swift new file mode 100644 index 0000000..07bc1d0 --- /dev/null +++ b/Example/Tests/Rules/Inline/LinkRuleTests.swift @@ -0,0 +1,144 @@ +// +// Created by Maren Osnabrug on 10-05-16. +// Copyright © 2016 M2mobi. All rights reserved. +// + +import XCTest +@testable import markymark + +class LinkRuleTests: XCTestCase { + + var sut: LinkRule! + + override func setUp() { + super.setUp() + sut = LinkRule() + } + + func testRecognizesLines() { + XCTAssertTrue(sut.recognizesLines(["[Alt text](image.png)"])) + XCTAssertFalse((sut.recognizesLines(["![Alt text](image.png)"]))) + XCTAssertTrue(sut.recognizesLines([#"[Alt text](image.png "some title")"#])) + } + + func test_DoesNotRecognizeLines_When_PrefixedWithExclamationMark() { + XCTAssertFalse((sut.recognizesLines(["![Alt text](image.png)"]))) + XCTAssertFalse((sut.recognizesLines(["! [Alt text](image.png)"]))) + XCTAssertFalse((sut.recognizesLines([#"![Alt text](image.png "some title")"#]))) + } + + func test_GetAllMatchesReturnsZero_When_InvalidInput() { + // Assert + XCTAssert(sut.getAllMatches(["(https://www.google.com)"]).isEmpty) + XCTAssert(sut.getAllMatches(["[Google]"]).isEmpty) + XCTAssert(sut.getAllMatches(["![Google](https://www.google.com)"]).isEmpty) + } + + func testCreateMarkDownItemWithLinesCreatesCorrectItem() { + // Act + let markDownItem = sut.createMarkDownItemWithLines(["[Google](http://www.google.com)"]) + + // Assert + XCTAssert(markDownItem is LinkMarkDownItem) + } + + func testCreateMarkDownItemContainsCorrectLink() { + // Act + let markDownItem = sut.createMarkDownItemWithLines(["[Google](http://www.google.com)"]) + let markDownItem2 = sut.createMarkDownItemWithLines(["[Youtube](http://www.youtube.com)"]) + + // Assert + XCTAssertEqual((markDownItem as! LinkMarkDownItem).content, "Google") + XCTAssertEqual((markDownItem as! LinkMarkDownItem).url, "http://www.google.com") + XCTAssertEqual((markDownItem2 as! LinkMarkDownItem).content, "Youtube") + XCTAssertEqual((markDownItem2 as! LinkMarkDownItem).url, "http://www.youtube.com") + } + + func testGetAllMatches() { + // Arrange + let expectedMatchesRange = NSRange(location: 0, length: 32) + let expectedMatchesRange2 = NSRange(location: 38, length: 32) + + // Act + Assert + XCTAssertEqual(sut.getAllMatches(["[Google]"]).count, 0) + XCTAssertEqual(sut.getAllMatches(["(https://www.google.com)"]).count, 0) + XCTAssertEqual(sut.getAllMatches(["[Google](https://www.google.com)"]), [expectedMatchesRange]) + XCTAssertEqual(sut.getAllMatches(["![Google](https://www.google.com)"]).count, 0) + XCTAssertEqual( + sut.getAllMatches(["[Google](https://www.google.com) test [Google](https://www.google.com)"]), + [expectedMatchesRange, expectedMatchesRange2] + ) + + XCTAssertEqual( + sut.getAllMatches([#"[Google](https://www.google.com) test [Google](https://www.google.com "a11y title")"#]), + [ + NSRange(location: 0, length: 32), + NSRange(location: 38, length: 45) + ] + ) + } + + func test_ParsesItem_When_InputMatches() throws { + // Arrange + let cases: [(String, String, String, UInt)] = [ + ( + #"[Google plain link](https://google.com)"#, + "Google plain link", + "https://google.com", + #line + ), + ( + #"[Google w/ title](http://www.google.com "with custom title")"#, + "Google w/ title", + "http://www.google.com", + #line + ), + ( + #"[Simple link](https://google.nl)"#, + "Simple link", + "https://google.nl", + #line + ), + ( + #"Inside [another link](http://m2mobi.com/) sentence"#, + "another link", + "http://m2mobi.com/", + #line + ), + ( + #"Inside [another link](http://m2mobi.com/ "with custom title") sentence"#, + "another link", + "http://m2mobi.com/", + #line + ), + ( + #"[Underscored link](https://google.nl/?param=a_b_c)"#, + "Underscored link", + "https://google.nl/?param=a_b_c", + #line + ), + ( + #"[Underscored link 2](https://google.nl/?param=a_b_c&d=e)"#, + "Underscored link 2", + "https://google.nl/?param=a_b_c&d=e", + #line + ), + ( + #"[Underscored link 4](https://google.nl/?param=a_b_c&d=e_f_g)"#, + "Underscored link 4", + "https://google.nl/?param=a_b_c&d=e_f_g", + #line + ) + ] + + for (input, content, url, line) in cases { + // Act + let output = sut.createMarkDownItemWithLines([input]) + + // Assert + let linkMarkDownItem = try XCTUnwrap(output as? LinkMarkDownItem) + XCTAssertEqual(linkMarkDownItem.content, content, line: line) + XCTAssertEqual(linkMarkDownItem.url, url, line: line) + } + } +} diff --git a/Example/Tests/Rules/Block/StrikeRuleTests.swift b/Example/Tests/Rules/Inline/StrikeRuleTests.swift similarity index 100% rename from Example/Tests/Rules/Block/StrikeRuleTests.swift rename to Example/Tests/Rules/Inline/StrikeRuleTests.swift diff --git a/Example/markymark.xcodeproj/project.pbxproj b/Example/markymark.xcodeproj/project.pbxproj index 8717a82..3aad183 100644 --- a/Example/markymark.xcodeproj/project.pbxproj +++ b/Example/markymark.xcodeproj/project.pbxproj @@ -112,13 +112,13 @@ 9704F30C7296E4A0EA9A0087 /* Pods-markymark_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-markymark_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-markymark_Example/Pods-markymark_Example.release.xcconfig"; sourceTree = ""; }; 99E80ED3FF06693617B60997 /* Pods-TodayExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TodayExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TodayExtension/Pods-TodayExtension.debug.xcconfig"; sourceTree = ""; }; 9A06FCF01CF72B4D0040251D /* AlphabeticListTypeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlphabeticListTypeTests.swift; sourceTree = ""; }; - 9A8BE0A31CEE0416004593A0 /* BoldRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BoldRuleTests.swift; path = Block/BoldRuleTests.swift; sourceTree = ""; }; - 9A8BE0A41CEE0416004593A0 /* ImageRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageRuleTests.swift; path = Block/ImageRuleTests.swift; sourceTree = ""; }; - 9A8BE0A51CEE0416004593A0 /* InlineCodeRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InlineCodeRuleTests.swift; path = Block/InlineCodeRuleTests.swift; sourceTree = ""; }; - 9A8BE0A61CEE0416004593A0 /* InlineTextRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InlineTextRuleTests.swift; path = Block/InlineTextRuleTests.swift; sourceTree = ""; }; - 9A8BE0A71CEE0416004593A0 /* ItalicRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ItalicRuleTests.swift; path = Block/ItalicRuleTests.swift; sourceTree = ""; }; - 9A8BE0A81CEE0416004593A0 /* LinkRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LinkRuleTests.swift; path = Block/LinkRuleTests.swift; sourceTree = ""; }; - 9A8BE0A91CEE0416004593A0 /* StrikeRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StrikeRuleTests.swift; path = Block/StrikeRuleTests.swift; sourceTree = ""; }; + 9A8BE0A31CEE0416004593A0 /* BoldRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoldRuleTests.swift; sourceTree = ""; }; + 9A8BE0A41CEE0416004593A0 /* ImageRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageRuleTests.swift; sourceTree = ""; }; + 9A8BE0A51CEE0416004593A0 /* InlineCodeRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InlineCodeRuleTests.swift; sourceTree = ""; }; + 9A8BE0A61CEE0416004593A0 /* InlineTextRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InlineTextRuleTests.swift; sourceTree = ""; }; + 9A8BE0A71CEE0416004593A0 /* ItalicRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItalicRuleTests.swift; sourceTree = ""; }; + 9A8BE0A81CEE0416004593A0 /* LinkRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinkRuleTests.swift; sourceTree = ""; }; + 9A8BE0A91CEE0416004593A0 /* StrikeRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StrikeRuleTests.swift; sourceTree = ""; }; 9A8BE0B21CEE044E004593A0 /* BlockQuoteRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockQuoteRuleTests.swift; sourceTree = ""; }; 9A8BE0B31CEE044E004593A0 /* CodeBlockRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeBlockRuleTests.swift; sourceTree = ""; }; 9A8BE0B71CEE0458004593A0 /* HorizontalLineRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HorizontalLineRuleTests.swift; sourceTree = ""; }; @@ -168,6 +168,20 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0C813F5425A4993300F805D0 /* Inline */ = { + isa = PBXGroup; + children = ( + 9A8BE0A31CEE0416004593A0 /* BoldRuleTests.swift */, + 9A8BE0A41CEE0416004593A0 /* ImageRuleTests.swift */, + 9A8BE0A51CEE0416004593A0 /* InlineCodeRuleTests.swift */, + 9A8BE0A61CEE0416004593A0 /* InlineTextRuleTests.swift */, + 9A8BE0A71CEE0416004593A0 /* ItalicRuleTests.swift */, + 9A8BE0A81CEE0416004593A0 /* LinkRuleTests.swift */, + 9A8BE0A91CEE0416004593A0 /* StrikeRuleTests.swift */, + ); + path = Inline; + sourceTree = ""; + }; 607FACC71AFB9204008FA782 = { isa = PBXGroup; children = ( @@ -252,8 +266,8 @@ 629C42251CEB47F900DA57D8 /* Rules */ = { isa = PBXGroup; children = ( - 9A8BE0A21CEE03EB004593A0 /* Inline */, 629C42261CEB47F900DA57D8 /* Block */, + 0C813F5425A4993300F805D0 /* Inline */, ); path = Rules; sourceTree = ""; @@ -315,20 +329,6 @@ name = Pods; sourceTree = ""; }; - 9A8BE0A21CEE03EB004593A0 /* Inline */ = { - isa = PBXGroup; - children = ( - 9A8BE0A31CEE0416004593A0 /* BoldRuleTests.swift */, - 9A8BE0A41CEE0416004593A0 /* ImageRuleTests.swift */, - 9A8BE0A51CEE0416004593A0 /* InlineCodeRuleTests.swift */, - 9A8BE0A61CEE0416004593A0 /* InlineTextRuleTests.swift */, - 9A8BE0A71CEE0416004593A0 /* ItalicRuleTests.swift */, - 9A8BE0A81CEE0416004593A0 /* LinkRuleTests.swift */, - 9A8BE0A91CEE0416004593A0 /* StrikeRuleTests.swift */, - ); - name = Inline; - sourceTree = ""; - }; F927877321F8BB3D00039986 /* Helpers */ = { isa = PBXGroup; children = ( @@ -455,6 +455,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); diff --git a/Example/markymark.xcodeproj/xcshareddata/xcschemes/markymark-Example.xcscheme b/Example/markymark.xcodeproj/xcshareddata/xcschemes/markymark-Example.xcscheme index 9f46512..8fea8cf 100644 --- a/Example/markymark.xcodeproj/xcshareddata/xcschemes/markymark-Example.xcscheme +++ b/Example/markymark.xcodeproj/xcshareddata/xcschemes/markymark-Example.xcscheme @@ -40,8 +40,16 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -54,23 +62,11 @@ - - - - - - - - [RuleRangePair] { - + var filteredRuleRangePairs: [RuleRangePair] = [] - var previousRange: NSRange? for ruleRangePair in ruleRangePairs { - if !ruleRangePair.range.isOverlappingWithRange(previousRange) || previousRange == nil { filteredRuleRangePairs.append(ruleRangePair) + previousRange = ruleRangePair.range } - - previousRange = ruleRangePair.range } return filteredRuleRangePairs diff --git a/markymark/Classes/Rules/Inline/LinkRule.swift b/markymark/Classes/Rules/Inline/LinkRule.swift index fa80cad..d43879a 100644 --- a/markymark/Classes/Rules/Inline/LinkRule.swift +++ b/markymark/Classes/Rules/Inline/LinkRule.swift @@ -9,16 +9,22 @@ open class LinkRule: InlineRegexRule { public init() {} - /// Example: [Google](http://www.google.com) - open var expression = NSRegularExpression.expressionWithPattern("(? MarkDownItem { - - let url: String? = lines.first?.subStringWithExpression(expression, ofGroup: 2) - let content: String? = lines.first?.subStringWithExpression(expression, ofGroup: 1) - - return LinkMarkDownItem(lines: lines, content: content ?? "", url: url ?? "") + let url: String? = lines.first?.subStringWithExpression(expression, ofGroup: 2) + let content: String? = lines.first?.subStringWithExpression(expression, ofGroup: 1) + + return LinkMarkDownItem( + lines: lines, + content: content ?? "", + url: url ?? "" + ) } }