vapor / leaf-kit

🍃 An expressive, performant, and extensible templating language built for Swift.
https://docs.vapor.codes/4.0/leaf/getting-started
MIT License
47 stars 38 forks source link

`requireBody()` and `requireNoBody()` not working as expected #123

Closed ptoffy closed 1 week ago

ptoffy commented 1 year ago

Describe the bug

Whilst creating a custom UnsafeUnescapedLeafTag, context.requireNoBody() always throws even if no body is provided, while context.requireBody() never throws even when no body is provided, rather returning an empty [Syntax].

While looking through the tests I noticed these methods are not tested anywhere and I think simply checking for the array being empty in addition to checking for it being != nil could solve the issue. The other option would be searching where the body of the tag is passed in and setting it to nil if it's an empty array

To Reproduce

  1. Create a simple project just using Leaf 4

  2. Create

    struct BodyRequiringTag: UnsafeUnescapedLeafTag {
    func render(_ ctx: LeafContext) throws -> LeafData {
        _ = try ctx.requireBody()
    
        return .string("Hello there")
    }
    }

    and

    struct NoBodyRequiringTag: UnsafeUnescapedLeafTag {
    func render(_ ctx: LeafContext) throws -> LeafData {
        try ctx.requireNoBody()
    
        return .string("General Kenobi")
    }
    }
  3. Add the tags to the test project

    app.leaf.tags["bodytag"] = BodyRequiringTag()
    app.leaf.tags["nobodytag"] = NoBodyRequiringTag()
  4. Adding the first tag to the project

    #bodytag:#endbodytag

    or

    #bodytag()

    This returns Hello there, which is just the return type of the tag, while it should be returning {error: true, reason: "Missing body"

  5. Adding the other tag

    #nobodytag

    This returns {error: true, reason: "Extraneous body"} The only way to make this error go away is to set the template as

    #nobodytag:#endnobodytag

    Which is, I think, not that intuitive

Environment

ptoffy commented 1 week ago

Closed by #133