-
-
Notifications
You must be signed in to change notification settings - Fork 16
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
Design and apply a proper interface and structure #18
Conversation
Wow, great work! So now the analyzers just take an So if I want to test an analyzer I could and should avoid to test the transformation from the raw Output to the formatted json output. I definitely prefer the example test without the runner since every processor should be tested on their own, and then I could have one test that exercises the runner/processor composition. I'm not sure if the something like (not actually working, just to express the idea)
Another benefit I see of this structure is that if should be easier to change the control flow from exception based to something else: it is well defined and clear that providing another base implementation of I wonder if a default parser should be provided by the base analyzer but I guess we will see when we have more than two. |
Correct. That was my intention. ✔️
Yes, that is what I envision for the
javascript-analyzer/src/interface.d.ts Lines 23 to 28 in a6b4d9a
It does indeed! It's called javascript-analyzer/src/comments/shared.ts Lines 3 to 5 in a6b4d9a
Actually, what you wrote works 😅 🚀
Yeah, not an issue for right now indeed; it's on my backlog of things to consider 👏 |
Using the new interface, I've rewritten the batch-runner and statistics scripts. Yes, it's much easier to write now; so I've moved them to typescript as well. Statisticsyarn build && bin/stats.sh -c two-fer This now uses the same bin/stats.sh -c two-fer other/fixtures/dir
Raw output{
"invalid": 0,
"valid": 485,
"total": 485,
"unique": 358
} Parsing statisticsThis is the number of unique Abstract Syntax Trees after stripping commentary,
Batch runner (two-fer)yarn build && bin/batch.sh -c two-fer Raw{
"toolRuntime": "537ms",
"refer_to_mentor": {
"count": 103,
"comments": {
"unique": [
"The string template looks incorrect. Expected a template with 3 components."
],
"unique_templates": [
"The string template looks incorrect. Expected a template with 3 components."
]
},
"runtimes": {
"total": 29805802591,
"average": 289376724,
"median": 311634200
}
},
"disapprove_with_comment": {
"count": 373,
"comments": {
"unique": [
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof name to 'you' to avoid this conditional.",
"In _JavaScript_, always prefer [strict (identity and non-identity) equality](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity)\nsuch as `===` and `!==` over the forms that use implicit type coercion,\nsuch as [`==`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality)\nand [`!=`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Inequality),\nunless you explicitly want to coerce the type of one of the two operands.\n\nThere are definitely cases where you'll want to use non-strict equality, but\nthat's not the case in this exercise.",
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof X to 'you' to avoid this conditional.",
"Instead of relying on name being \"undefined\" when\nno value is passed in, you could set the default value of 'name' to\n'you'.",
"No method called `twoFer`. The tests won't pass without it.",
"No [export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) called `twoFer`.\nThe tests won't pass without it.\n\nDid you forget adding: `export twoFer`?",
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof n to 'you' to avoid this conditional.",
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof oneFer to 'you' to avoid this conditional.",
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof x to 'you' to avoid this conditional.",
"Your function `twoFer` does not have a parameter.\nThe tests won't pass without it.",
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof value to 'you' to avoid this conditional.",
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof person to 'you' to avoid this conditional.",
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof who to 'you' to avoid this conditional.",
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof userName to 'you' to avoid this conditional.",
"Instead of relying on who being \"undefined\" when\nno value is passed
in, you could set the default value of 'who' to\n'you'.",
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof someName to 'you' to avoid this conditional."
],
"unique_templates": [
"You currently use a conditional to branch in case there is no value passed into\n`twoFer`. Instead you could set the [default value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)\nof %<parameter>s to 'you' to avoid this conditional.",
"In _JavaScript_, always prefer [strict (identity and non-identity) equality](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity)\nsuch as `===` and `!==` over the forms that use implicit type coercion,\nsuch as [`==`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality)\nand [`!=`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Inequality),\nunless you explicitly want to coerce the type of one of the two operands.\n\nThere are definitely cases where you'll want to use non-strict equality, but\nthat's not the case in this exercise.",
"Instead of relying on %<maybe_undefined_expression>s being \"undefined\" when\nno value is passed in, you could set the default value of '%<parameter>s' to\n'you'.",
"No method called `%<method_name>s`. The tests won't pass without it.",
"No [export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) called `%<export_name>s`.\nThe tests won't pass without it.\n\nDid you forget adding: `export %<export_name>s`?",
"Your function `%<function_name>s` does not have a parameter.\nThe tests won't pass without it."
]
},
"runtimes": {
"total": 106715240198,
"average": 286099839,
"median": 296772301
}
},
"approve_as_optimal": {
"count": 7,
"comments": {
"unique": [],
"unique_templates": []
},
"runtimes": {
"total": 1867306301,
"average": 266758043,
"median": 295006101
}
}
} Statistics
|
I will merge this over the weekend if there are no strong objections. I want to make sure this is ready sooner rather than later. cc @depsir @tejasbubane cc-ing you as I always value your thoughts. |
0933d53
to
bd0ef7b
Compare
* Create CODE_OF_CONDUCT (originally @SleeplessByte exercism/javascript-analyzer#5) * Add dockerfile for automated mentoring support (originally @depsir exercism/javascript-analyzer#12) * Initial smoke for usage of jest (originally: @SleeplessByte exercism/javascript-analyzer#17) * Apply design and proper interface and structure (originally: @SleeplessByte exercism/javascript-analyzer#18) * Fixes issues in the README.md (originally: @zeckdude exercism/javascript-analyzer#19)
* Create CODE_OF_CONDUCT (originally @SleeplessByte exercism/javascript-analyzer#5) * Add dockerfile for automated mentoring support (originally @depsir exercism/javascript-analyzer#12) * Initial smoke for usage of jest (originally: @SleeplessByte exercism/javascript-analyzer#17) * Apply design and proper interface and structure (originally: @SleeplessByte exercism/javascript-analyzer#18) * Fixes issues in the README.md (originally: @zeckdude exercism/javascript-analyzer#19)
As discussed in #16 this makes a few changes to separate all logic and make it easier to test the units, reason about the flow and implement new behaviour:
Input
: any source of input, implementations areFileInput
,DirectoryInput
andInlineInput
. They can provide 0 to many source files to be parsedOutput
: an analysis output in the raw format, hastoProcessable
in order to turn it into something the official interface expects (a json formatted file)OutputProcessor
: like a chain, calls the previous processor and can make changes, implementations are:LogOutput
,FileOutput
and a noopPassThroughOutput
. I'd like this to be more like a middleware in the future.Analyzer
: only hasrun(input: Input): Promise<Output>
Runner
: only hascall(analyzer: Analyzer, input: Input, options: Readonly<ExecutionOptions>): Promise<Output>
The runner is just a simple way to take the
ExecutionOptions
and apply certainOutputProcessors
or not, it's not longer vital to use at all.Each
Analyzer
can act on an AST by parsing theInput
they get via a parser. Each analyzer can define their own parser and options, but we provide sane defaults. The default parser uses@typescript-eslint/typescript-estree
. The base implementation of theAnalyzer
no longer knows about parsing at all.The new code simplifies a lot. Consider the new base execution:
The default input is given by the command line:
This also means that the default test is much easier:
The runner can be replaced:
Additionally the
bin/batch(-runner)
andbin/stat(istic)s
scripts have been rewritten utilising the new structure.