manta-style icon indicating copy to clipboard operation
manta-style copied to clipboard

RFC: Rethink Annotations

Open Cryrivers opened this issue 7 years ago • 8 comments

tl;dr: this probably a Milestone for 2.0, for 1.0 we will still keep the current mechanism and specification, but re-design the API to be forward-compatible.

This issue is about normalizing JSDoc annotation and powerful Handlebars annotation. And we aim to achieve following goals:

  • [ ] Parse and execute Handlebar annotation under the hood, convert JSDoc annotation into handlebars annotation. For example:
/**
 * @iterate hello
 * @iterate world
 * @example a
 * @example b
 */

converts to (in practice, AnnotationNode would be constructed directly, without involving handlebars conversion):

/**
 * @mantastyle
 * {{iterate 'hello' 'world'}}
 * {{example 'a' 'b'}}
 */
  • [ ] Other than JSDoc, users can opt-in undocumented and powerful handlebars annotation by having @mantastyle in their comment. So a parsed annotation always starts with AnnotationNode[]

This could also unify JSDoc annotation and handlebar annotation, and also make previous annotationUtils compatible with new implementation.

  • [ ] Re-implement annotation generation logic by evaluating Handlebars under-the-hood, and the evaluation can be either lazy or eager as well. Subgoals would be:
    • [ ] Change signature of mock plugins from Annotation[] => any to AnnotationExpression => AnnotationNode.
    • [ ] Evaluation is lazy by default, (there should be a way to eagerly evaluate sub-expressions)
    • [ ] The evaluation order should respect to the evaluation order of type nodes. For example:
/**
* @mantastyle
* {{faker 'internet.UserName'}}
* {{length (range min=5 max=10)}}
*/
type Test = string[];

As deriveLiteral in ArrayType runs first, then in StringType. So {{length}} runs first, then {{faker}} (probably runs multiple times depending on {{length}}, accordingly.

  • [ ] Build in some annotation plugins by default
    • [ ] {{key [string]}} to manipulate keys of object
    • [ ] {{length [number]}} to manipulate length of array
    • [ ] {{range min= max= precision=}} to generate a random number given range

Cryrivers avatar Sep 09 '18 05:09 Cryrivers

  1. what happens with
/**
 * @iterate hello
 * @iterate world
 * @example a
 * @example b
 * @mantastyle {{ xxx }}
 */

there's 3 different annotation, and they are conflicting with each other, what should be the mock data?

  1. Since we are talking about rethink the annotation system, how does the {{length [number]}} works? how does it make the array to have length [number] ? the only think i can think of now is to return array metadata, back to the ArrayType.

tanhauhau avatar Sep 09 '18 13:09 tanhauhau

😂yeah, this issue looks very challenging to me. i've been creating and remove branches for several times...

  1. i think it would be translated to
{{iterate 'hello' 'world'}} {{example 'a' 'b'}} {{xxx}}

latter takes precedence over former expression (with respect to type evaluation order)

  1. this is the tricky part, i was thinking we can have plugin callback for deriveLiteral to generate some metadata. the type of it is different from type to type. For example, metadata has length if it is deriveLiteral in ArrayType, etc.

Cryrivers avatar Sep 10 '18 15:09 Cryrivers

or to simplify the problem and API, we can just return metadata in ArrayType callback. as the element type has its own plugin to run.

Cryrivers avatar Sep 10 '18 15:09 Cryrivers

So in this contrived example, iterate would never be called, because example is having the same behaviour (provide mock data), and having a higher precedence than iterate?

tanhauhau avatar Sep 10 '18 15:09 tanhauhau

i think so, as for iterate and example, i wouldn't expect to use them like this.

Cryrivers avatar Sep 10 '18 15:09 Cryrivers

we can print out a warning message actually

Cryrivers avatar Sep 10 '18 15:09 Cryrivers

if we are going to give error, how are we going to detect this?

tanhauhau avatar Sep 11 '18 13:09 tanhauhau

to check if 2 plugins apply to the same time. For example, iterate and example both apply to StringType, so not both can work. (consider non-composable case, in JSDoc syntax)

Cryrivers avatar Sep 11 '18 16:09 Cryrivers