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

RFC: Rethink Annotations #60

Open
10 tasks
Cryrivers opened this issue Sep 9, 2018 · 8 comments
Open
10 tasks

RFC: Rethink Annotations #60

Cryrivers opened this issue Sep 9, 2018 · 8 comments

Comments

@Cryrivers
Copy link
Owner

Cryrivers commented Sep 9, 2018

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
@tanhauhau
Copy link
Collaborator

  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.

@Cryrivers
Copy link
Owner Author

Cryrivers commented Sep 10, 2018

😂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
Copy link
Owner Author

Cryrivers commented Sep 10, 2018

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.

@tanhauhau
Copy link
Collaborator

tanhauhau commented Sep 10, 2018

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?

@Cryrivers
Copy link
Owner Author

Cryrivers commented Sep 10, 2018

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

@Cryrivers
Copy link
Owner Author

Cryrivers commented Sep 10, 2018

we can print out a warning message actually

@tanhauhau
Copy link
Collaborator

tanhauhau commented Sep 11, 2018

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

@Cryrivers
Copy link
Owner Author

Cryrivers commented Sep 11, 2018

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants