diff --git a/ElementX/Sources/Other/HTMLParsing/HTMLFixtures.swift b/ElementX/Sources/Other/HTMLParsing/HTMLFixtures.swift index 29699fdd0..d79e20207 100644 --- a/ElementX/Sources/Other/HTMLParsing/HTMLFixtures.swift +++ b/ElementX/Sources/Other/HTMLParsing/HTMLFixtures.swift @@ -12,7 +12,8 @@ enum HTMLFixtures: String, CaseIterable { case matrixIdentifiers case links case textFormatting - case blockQuotes + case groupedBlockQuotes + case separatedBlockQuotes case codeBlocks case unorderedList case orderedList @@ -49,7 +50,7 @@ enum HTMLFixtures: String, CaseIterable { """ case .links: """ - Links too:
Matrix rules! 🤘, matrix.org, www.matrix.org, http://matrix.org + Links too:
Matrix rules! 🤘, beta.org, www.gamma.org, http://delta.org """ case .textFormatting: """ @@ -59,7 +60,13 @@ enum HTMLFixtures: String, CaseIterable {
Thumbs if you liked it, sub if you loved it! """ - case .blockQuotes: + case .groupedBlockQuotes: + """ +
First blockquote with a link in it
+
Second blockquote with a link in it
+
Third blockquote with a link in it
+ """ + case .separatedBlockQuotes: """
First blockquote with a link in it
Second blockquote with a link in it
@@ -67,7 +74,8 @@ enum HTMLFixtures: String, CaseIterable { """ case .codeBlocks: """ -
A preformatted code blockstruct ContentView: View {
+            
A preformatted code block
+            struct ContentView: View {
                 var body: some View {
                     VStack {
                         Text("Knock, knock!")
diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-en-GB-0.png
index cd65f38dc..436779503 100644
--- a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-en-GB-0.png
+++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-en-GB-0.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:4ec1eee24450c078e2d930204eb6c4bd5f5a48c1d472926ad25dd061389d7c45
-size 1144610
+oid sha256:0373e531749b8097a73c8b50b7168ddf840032517089451541f241666dd372ee
+size 1087431
diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-en-GB-1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-en-GB-1.png
index a4fade271..9e90111d2 100644
--- a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-en-GB-1.png
+++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-en-GB-1.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:4d6c10079176b2c9d5d4155e0d917a25191723ce8b0c3c1c23a4b2ceed15f3fb
-size 1116696
+oid sha256:1b2d5c8c8845a2afa32446d6776d6e08ab46b43f302f34cacc8c9ed052cc8d75
+size 1060198
diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-pseudo-0.png
index cd65f38dc..436779503 100644
--- a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-pseudo-0.png
+++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-pseudo-0.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:4ec1eee24450c078e2d930204eb6c4bd5f5a48c1d472926ad25dd061389d7c45
-size 1144610
+oid sha256:0373e531749b8097a73c8b50b7168ddf840032517089451541f241666dd372ee
+size 1087431
diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-pseudo-1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-pseudo-1.png
index a4fade271..9e90111d2 100644
--- a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-pseudo-1.png
+++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPad-pseudo-1.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:4d6c10079176b2c9d5d4155e0d917a25191723ce8b0c3c1c23a4b2ceed15f3fb
-size 1116696
+oid sha256:1b2d5c8c8845a2afa32446d6776d6e08ab46b43f302f34cacc8c9ed052cc8d75
+size 1060198
diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-en-GB-0.png
index 957cc5822..bc60fc013 100644
--- a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-en-GB-0.png
+++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-en-GB-0.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:aeee2464439a366386e0ededbd5ebde7c330a9a90c26964dc9a63e56563dc7f5
-size 1323827
+oid sha256:5f5d73086343f275db3867387967984ce2f3cb00ba5b60a94fcb3ff57a99b8ce
+size 1241249
diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-en-GB-1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-en-GB-1.png
index 673ce0f53..ee97a61cd 100644
--- a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-en-GB-1.png
+++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-en-GB-1.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e84edbb38495d3c2d323ee5dcd37896c9b286bec6377980625d35e861e5dbd19
-size 1307233
+oid sha256:0db9ca076d445687ec5d8c222590a415747b88954bfcf46058733b7e64b868df
+size 1224907
diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-pseudo-0.png
index 957cc5822..bc60fc013 100644
--- a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-pseudo-0.png
+++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-pseudo-0.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:aeee2464439a366386e0ededbd5ebde7c330a9a90c26964dc9a63e56563dc7f5
-size 1323827
+oid sha256:5f5d73086343f275db3867387967984ce2f3cb00ba5b60a94fcb3ff57a99b8ce
+size 1241249
diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-pseudo-1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-pseudo-1.png
index 673ce0f53..ee97a61cd 100644
--- a/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-pseudo-1.png
+++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/formattedBodyText.iPhone-16-pseudo-1.png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e84edbb38495d3c2d323ee5dcd37896c9b286bec6377980625d35e861e5dbd19
-size 1307233
+oid sha256:0db9ca076d445687ec5d8c222590a415747b88954bfcf46058733b7e64b868df
+size 1224907
diff --git a/UnitTests/Sources/AttributedStringBuilderV1Tests.swift b/UnitTests/Sources/AttributedStringBuilderV1Tests.swift
index d1ef93bed..90f56bea6 100644
--- a/UnitTests/Sources/AttributedStringBuilderV1Tests.swift
+++ b/UnitTests/Sources/AttributedStringBuilderV1Tests.swift
@@ -228,8 +228,6 @@ class AttributedStringBuilderV1Tests: XCTestCase {
         checkLinkIn(attributedString: attributedStringBuilder.fromHTML(string), expectedLink: expectedLink.absoluteString, expectedRuns: 3)
         checkLinkIn(attributedString: attributedStringBuilder.fromPlain(string), expectedLink: expectedLink.absoluteString, expectedRuns: 3)
     }
-    
-    // `Plain link in codeblock: https://www.matrix.org`, Link tag in codeblock: link, plain link: https://www.matrix.org, link tag: link
         
     func testDefaultFont() {
         let htmlString = "Test string "
diff --git a/UnitTests/Sources/AttributedStringBuilderV2Tests.swift b/UnitTests/Sources/AttributedStringBuilderV2Tests.swift
index 7068bc35c..18b239f75 100644
--- a/UnitTests/Sources/AttributedStringBuilderV2Tests.swift
+++ b/UnitTests/Sources/AttributedStringBuilderV2Tests.swift
@@ -18,44 +18,21 @@ class AttributedStringBuilderV2Tests: XCTestCase {
     }
     
     func testRenderHTMLStringWithHeaders() {
-        let h1HTMLString = "

Large Heading

" - let h2HTMLString = "

Smaller Heading

" - let h3HTMLString = "

Acceptable Heading

" - - guard let h1AttributedString = attributedStringBuilder.fromHTML(h1HTMLString), - let h2AttributedString = attributedStringBuilder.fromHTML(h2HTMLString), - let h3AttributedString = attributedStringBuilder.fromHTML(h3HTMLString) else { + guard let attributedString = attributedStringBuilder.fromHTML(HTMLFixtures.headers.rawValue) else { XCTFail("Could not build the attributed string") return } - XCTAssertEqual(String(h1AttributedString.characters), "Large Heading") - XCTAssertEqual(String(h2AttributedString.characters), "Smaller Heading") - XCTAssertEqual(String(h3AttributedString.characters), "Acceptable Heading") + XCTAssertEqual(String(attributedString.characters), "H1 Header\nH2 Header\nH3 Header\nH4 Header\nH5 Header\nH6 Header") - XCTAssert(h1AttributedString.runs.count == 1) - XCTAssert(h2AttributedString.runs.count == 1) - XCTAssert(h3AttributedString.runs.count == 1) - - guard let h1Font = h1AttributedString.runs.first?.uiKit.font, - let h2Font = h2AttributedString.runs.first?.uiKit.font, - let h3Font = h3AttributedString.runs.first?.uiKit.font else { - XCTFail("Could not extract a font from the strings.") - return - } - - XCTAssertEqual(h1Font, h2Font) - XCTAssertEqual(h2Font, h3Font) - - XCTAssert(h1Font.pointSize > UIFont.preferredFont(forTextStyle: .body).pointSize) - - XCTAssert(h1Font.pointSize <= maxHeaderPointSize) + XCTAssertEqual(attributedString.runs.count, 11) // newlines hold no attributes + + let pointSizes = attributedString.runs.compactMap(\.uiKit.font?.pointSize) + XCTAssertEqual(pointSizes, [24, 22, 20, 18, 16, 14]) } func testRenderHTMLStringWithPreCode() { - let htmlString = "
1\n2\n3\n4\n
" - - guard let attributedString = attributedStringBuilder.fromHTML(htmlString) else { + guard let attributedString = attributedStringBuilder.fromHTML(HTMLFixtures.codeBlocks.rawValue) else { XCTFail("Could not build the attributed string") return } @@ -69,24 +46,20 @@ class AttributedStringBuilderV2Tests: XCTestCase { return } - XCTAssertEqual(regex.numberOfMatches(in: string, options: [], range: .init(location: 0, length: string.count)), 3) + XCTAssertEqual(regex.numberOfMatches(in: string, options: [], range: .init(location: 0, length: string.count)), 13) } func testRenderHTMLStringWithLink() { - let htmlString = "This text contains a link." - - guard let attributedString = attributedStringBuilder.fromHTML(htmlString) else { + guard let attributedString = attributedStringBuilder.fromHTML(HTMLFixtures.links.rawValue) else { XCTFail("Could not build the attributed string") return } - XCTAssertEqual(String(attributedString.characters), "This text contains a link.") - - XCTAssertEqual(attributedString.runs.count, 3) + XCTAssertEqual(String(attributedString.characters), "Links too:\nMatrix rules! 🤘, beta.org, www.gamma.org, http://delta.org") let link = attributedString.runs.first { $0.link != nil }?.link - XCTAssertEqual(link?.host, "www.matrix.org") + XCTAssertEqual(link?.host, "www.alpha.org") } func testRenderPlainStringWithLink() { @@ -159,20 +132,7 @@ class AttributedStringBuilderV2Tests: XCTestCase { XCTAssertEqual(h1AttributedString.runs.count, 1) XCTAssertEqual(h2AttributedString.runs.count, 1) XCTAssertEqual(h3AttributedString.runs.count, 1) - - guard let h1Font = h1AttributedString.runs.first?.uiKit.font, - let h2Font = h2AttributedString.runs.first?.uiKit.font, - let h3Font = h3AttributedString.runs.first?.uiKit.font else { - XCTFail("Could not extract a font from the strings.") - return - } - - XCTAssertEqual(h1Font, h2Font) - XCTAssertEqual(h2Font, h3Font) - - XCTAssert(h1Font.pointSize > UIFont.preferredFont(forTextStyle: .body).pointSize) - XCTAssert(h1Font.pointSize <= maxHeaderPointSize) - + XCTAssertEqual(h1AttributedString.runs.first?.link?.host, "matrix.org") XCTAssertEqual(h2AttributedString.runs.first?.link?.host, "matrix.org") XCTAssertEqual(h3AttributedString.runs.first?.link?.host, "matrix.org") @@ -229,24 +189,7 @@ class AttributedStringBuilderV2Tests: XCTestCase { checkLinkIn(attributedString: attributedStringBuilder.fromHTML(string), expectedLink: expectedLink.absoluteString, expectedRuns: 3) checkLinkIn(attributedString: attributedStringBuilder.fromPlain(string), expectedLink: expectedLink.absoluteString, expectedRuns: 3) } - - // `Plain link in codeblock: https://www.matrix.org`, Link tag in codeblock: link, plain link: https://www.matrix.org, link tag: link - func testDefaultFont() { - let htmlString = "Test string " - - guard let attributedString = attributedStringBuilder.fromHTML(htmlString) else { - XCTFail("Could not build the attributed string") - return - } - - XCTAssertEqual(attributedString.runs.count, 3) - - for run in attributedString.runs { - XCTAssertEqual(run.uiKit.font?.familyName, UIFont.preferredFont(forTextStyle: .body).familyName) - } - } - func testDefaultForegroundColor() { let htmlString = "Test string link link" @@ -378,20 +321,14 @@ class AttributedStringBuilderV2Tests: XCTestCase { } func testMultipleGroupedBlockquotes() { - let htmlString = """ -
First blockquote with a link in it
-
Second blockquote with a link in it
-
Third blockquote with a link in it
- """ - - guard let attributedString = attributedStringBuilder.fromHTML(htmlString) else { + guard let attributedString = attributedStringBuilder.fromHTML(HTMLFixtures.groupedBlockQuotes.rawValue) else { XCTFail("Could not build the attributed string") return } - XCTAssertEqual(attributedString.runs.count, 7) + XCTAssertEqual(attributedString.runs.count, 11) - XCTAssertEqual(attributedString.formattedComponents.count, 1) + XCTAssertEqual(attributedString.formattedComponents.count, 5) var numberOfBlockquotes = 0 for run in attributedString.runs where run.elementX.blockquote ?? false && run.link != nil { @@ -402,25 +339,16 @@ class AttributedStringBuilderV2Tests: XCTestCase { } func testMultipleSeparatedBlockquotes() { - let htmlString = """ - First -
blockquote with a link in it
- Second -
blockquote with a link in it
- Third -
blockquote with a link in it
- """ - - guard let attributedString = attributedStringBuilder.fromHTML(htmlString) else { + guard let attributedString = attributedStringBuilder.fromHTML(HTMLFixtures.separatedBlockQuotes.rawValue) else { XCTFail("Could not build the attributed string") return } - XCTAssertEqual(attributedString.runs.count, 12) + XCTAssertEqual(attributedString.runs.count, 11) let coalescedComponents = attributedString.formattedComponents - XCTAssertEqual(coalescedComponents.count, 6) + XCTAssertEqual(coalescedComponents.count, 5) var numberOfBlockquotes = 0 for run in attributedString.runs where run.elementX.blockquote ?? false && run.link != nil { @@ -580,43 +508,25 @@ class AttributedStringBuilderV2Tests: XCTestCase { checkAttachment(attributedString: attributedStringFromPlain2, expectedRuns: 1) } - func testURLsAreIgnoredInCode() { - var htmlString = "
test https://matrix.org test
" - var attributedStringFromHTML = attributedStringBuilder.fromHTML(htmlString) - XCTAssert(attributedStringFromHTML?.runs.count == 1) - XCTAssertNil(attributedStringFromHTML?.link) - - htmlString = "
matrix.org
" - attributedStringFromHTML = attributedStringBuilder.fromHTML(htmlString) - XCTAssert(attributedStringFromHTML?.runs.count == 1) - XCTAssertNil(attributedStringFromHTML?.link) - } - - func testHyperlinksAreIgnoredInCode() { - let htmlString = "
test matrix test
" - let attributedStringFromHTML = attributedStringBuilder.fromHTML(htmlString) - XCTAssertNil(attributedStringFromHTML?.link) - } - func testUserMentionIsIgnoredInCode() { let htmlString = "
test https://matrix.org/#/@test:matrix.org test
" - let attributedStringFromHTML = attributedStringBuilder.fromHTML(htmlString) - XCTAssert(attributedStringFromHTML?.runs.count == 1) - XCTAssertNil(attributedStringFromHTML?.attachment) + let attributedString = attributedStringBuilder.fromHTML(htmlString) + XCTAssertEqual(attributedString?.runs.count, 3) + XCTAssertNil(attributedString?.attachment) } func testPlainTextUserMentionIsIgnoredInCode() { let htmlString = "
Hey @some.user.ceriu:matrix.org
" - let attributedStringFromHTML = attributedStringBuilder.fromHTML(htmlString) - XCTAssert(attributedStringFromHTML?.runs.count == 1) - XCTAssertNil(attributedStringFromHTML?.attachment) + let attributedString = attributedStringBuilder.fromHTML(htmlString) + XCTAssertEqual(attributedString?.runs.count, 2) + XCTAssertNil(attributedString?.attachment) } func testAllUsersIsIgnoredInCode() { let htmlString = "
test @room test
" - let attributedStringFromHTML = attributedStringBuilder.fromHTML(htmlString) - XCTAssert(attributedStringFromHTML?.runs.count == 1) - XCTAssertNil(attributedStringFromHTML?.attachment) + let attributedString = attributedStringBuilder.fromHTML(htmlString) + XCTAssertEqual(attributedString?.runs.count, 3) + XCTAssertNil(attributedString?.attachment) } func testMultipleMentions() { @@ -729,6 +639,7 @@ class AttributedStringBuilderV2Tests: XCTestCase { XCTFail("Couldn't find the link") return } + XCTAssertTrue(link.requiresConfirmation) XCTAssertEqual(link.confirmationParameters?.internalURL.absoluteString, "https://matrix.org") XCTAssertEqual(link.confirmationParameters?.displayString, "https://element.io")