Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support documenting http responses, property list values, parameters, etc. with spaces in the name #1017

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions Sources/SwiftDocC/Utility/MarkupExtensions/ListItemExtractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -284,37 +284,38 @@ private struct ExtractedTag {
case httpBodyParameters

init?(_ string: String) {
let components = string.components(separatedBy: .whitespaces).filter { !$0.isEmpty }
let separatorIndex = string.firstIndex(where: \.isWhitespace) ?? string.endIndex
let secondComponent = String(string[separatorIndex...].drop(while: \.isWhitespace))

switch components.first?.lowercased() {
switch string[..<separatorIndex].lowercased() {
case "returns":
self = .returns
case "throws":
self = .throws
case "parameter" where components.count == 2:
self = .parameter(String(components.last!))
case "parameter" where !secondComponent.isEmpty:
self = .parameter(secondComponent)
case "parameters":
self = .parameters
case "dictionarykey" where components.count == 2:
self = .dictionaryKey(String(components.last!))
case "dictionarykey" where !secondComponent.isEmpty:
self = .dictionaryKey(secondComponent)
case "dictionarykeys":
self = .dictionaryKeys
case "possiblevalue" where components.count == 2:
self = .possibleValue(String(components.last!))
case "possiblevalue" where !secondComponent.isEmpty:
self = .possibleValue(secondComponent)
case "possiblevalues":
self = .possibleValues
case "httpbody":
self = .httpBody
case "httpresponse" where components.count == 2:
self = .httpResponse(String(components.last!))
case "httpresponse" where !secondComponent.isEmpty:
self = .httpResponse(secondComponent)
case "httpresponses":
self = .httpResponses
case "httpparameter" where components.count == 2:
self = .httpParameter(String(components.last!))
case "httpparameter" where !secondComponent.isEmpty:
self = .httpParameter(secondComponent)
case "httpparameters":
self = .httpParameters
case "httpbodyparameter" where components.count == 2:
self = .httpBodyParameter(String(components.last!))
case "httpbodyparameter" where !secondComponent.isEmpty:
self = .httpBodyParameter(secondComponent)
case "httpbodyparameters":
self = .httpBodyParameters
default:
Expand Down
59 changes: 59 additions & 0 deletions Tests/SwiftDocCTests/Utility/ListItemExtractorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,65 @@ import Markdown

class ListItemExtractorTests: XCTestCase {

func testSupportsSpacesInTaggedElementNames() throws {
let testSource = URL(fileURLWithPath: "/path/to/test-source-\(ProcessInfo.processInfo.globallyUniqueString)")
func extractedTags(_ markup: String) -> TaggedListItemExtractor {
let document = Document(parsing: markup, source: testSource, options: .parseSymbolLinks)

var extractor = TaggedListItemExtractor()
_ = extractor.visit(document)
return extractor
}

for whitespace in [" ", " ", "\t"] {
let parameters = extractedTags("""
- Parameter\(whitespace)some parameter with spaces: Some description of this parameter.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It looks like we're missing some tests for when there's nothing after the list item tag (e.g. just - Parameter: Some description of this parameter., would it be worth adding some?

Copy link
Contributor Author

@d-ronnqvist d-ronnqvist Sep 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tests like that on lines 70-74:

XCTAssert(extractedTags("- Parameter: Missing parameter name.").parameters.isEmpty)
XCTAssert(extractedTags("- Parameter  : Missing parameter name.").parameters.isEmpty)

XCTAssert(extractedTags("- DictionaryKey: Missing key name.").parameters.isEmpty)
XCTAssert(extractedTags("- PossibleValue: Missing value name.").parameters.isEmpty)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although now, that I read those tests I see that I'm verifying the wrong lists for the last two tests.

Copy link
Contributor Author

@d-ronnqvist d-ronnqvist Sep 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although now, that I read those tests I see that I'm verifying the wrong lists for the last two tests.

Fixed in 093ed59

XCTAssert(extractedTags("- Parameter: Missing parameter name.").parameters.isEmpty)
XCTAssert(extractedTags("- Parameter  : Missing parameter name.").parameters.isEmpty)

XCTAssert(extractedTags("- DictionaryKey: Missing key name.").dictionaryKeys.isEmpty)
XCTAssert(extractedTags("- PossibleValue: Missing value name.").possiblePropertyListValues.isEmpty)

""").parameters
XCTAssertEqual(parameters.count, 1)
let parameter = try XCTUnwrap(parameters.first)
XCTAssertEqual(parameter.name, "some parameter with spaces")
XCTAssertEqual(parameter.contents.map { $0.format() }, ["Some description of this parameter."])
XCTAssertEqual(parameter.nameRange?.source?.path, testSource.path)
XCTAssertEqual(parameter.range?.source?.path, testSource.path)
}

let parameters = extractedTags("""
- Parameters:
- some parameter with spaces: Some description of this parameter.
""").parameters
XCTAssertEqual(parameters.count, 1)
let parameter = try XCTUnwrap(parameters.first)
XCTAssertEqual(parameter.name, "some parameter with spaces")
XCTAssertEqual(parameter.contents.map { $0.format() }, ["Some description of this parameter."])
XCTAssertEqual(parameter.nameRange?.source?.path, testSource.path)
XCTAssertEqual(parameter.range?.source?.path, testSource.path)

let dictionaryKeys = extractedTags("""
- DictionaryKeys:
- some key with spaces: Some description of this key.
""").dictionaryKeys
XCTAssertEqual(dictionaryKeys.count, 1)
let dictionaryKey = try XCTUnwrap(dictionaryKeys.first)
XCTAssertEqual(dictionaryKey.name, "some key with spaces")
XCTAssertEqual(dictionaryKey.contents.map { $0.format() }, ["Some description of this key."])

let possibleValues = extractedTags("""
- PossibleValue some value with spaces: Some description of this value.
""").possiblePropertyListValues
XCTAssertEqual(possibleValues.count, 1)
let possibleValue = try XCTUnwrap(possibleValues.first)
XCTAssertEqual(possibleValue.value, "some value with spaces")
XCTAssertEqual(possibleValue.contents.map { $0.format() }, ["Some description of this value."])
XCTAssertEqual(possibleValue.nameRange?.source?.path, testSource.path)
XCTAssertEqual(possibleValue.range?.source?.path, testSource.path)

XCTAssert(extractedTags("- Parameter: Missing parameter name.").parameters.isEmpty)
XCTAssert(extractedTags("- Parameter : Missing parameter name.").parameters.isEmpty)

XCTAssert(extractedTags("- DictionaryKey: Missing key name.").dictionaryKeys.isEmpty)
XCTAssert(extractedTags("- PossibleValue: Missing value name.").possiblePropertyListValues.isEmpty)
}

func testExtractingTags() throws {
try assertExtractsRichContentFor(
tagName: "Returns",
Expand Down