-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fix and regenerate invalid block fixtures #2056
Conversation
8d4942b
to
55e85d3
Compare
I think we might as well handle this in this PR, too: some of the fixtures modified in this PR should serve as our intentionally-invalid examples. |
// ANSI codes are supported. In these environments we provide a nicely | ||
// colored error message for invalid parse. | ||
// | ||
// TODO: Teach browsers to ANSI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... or teach chalk
to output HTML. ANSI escape sequences are quite convoluted, and it seems like what we really want is an intermediate representation that can be outputted in either form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... or teach
chalk
to output HTML. ANSI escape sequences are quite convoluted, and it seems like what we really want is an intermediate representation that can be outputted in either form.
I did run across this: https://www.npmjs.com/package/ansi_up
I'd also toyed with ideas for converting ANSI automatically to CSS-styled console.log
depending on the environment.
blocks/api/parser.js
Outdated
// eslint-disable-next-line no-console | ||
console.warn( message ); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this code block could be structured better to achieve the following goals:
- Serve as a foundation for an eventual UI that explains the differences to the user.
- Specifically test the logic for generating the difference messages.
We probably do want this code in the production build eventually, so these changes would end up removing most of the environment-specific conditionals. What would remain would be something like this:
if ( 'test' === process.env.NODE_ENV ) {
// Maybe we can even remove this, in favor of
// `expect( console.warn ).toHaveBeenCalledWith( ... )`
// in the tests below.
throw new Error( message );
} else if ( 'production' !== process.env.NODE_ENV ) {
console.warn( message );
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The NODE_ENV
condition wasn't so much for testing the parser as much as it was to ensure the fixtures testing would actually log the failure if the parse was invalid (console.warn
is not sufficient).
Instead, in cdde9c4 I've changed it so that the error is thrown in all cases. It is handled by a try
/ catch
in createBlockWithFallback
which assigns the error into the block. With a reintroduction of the invalid blocks, the fixtures testing determines whether the parse should have failed and otherwise surfaces the error to Jest.
I went back and forth on this a bit, trying to decide if throwing an error was the right path. It's otherwise difficult to detect the failure in fixtures testing... except with overriding console.error
, which felt a bit hacky. I think they're legitimate errors and should be treated as such.
The downside is that because the error is handled, it is no longer logged to the console in the browser. But because the error is now stored into the block, I think we have some better opportunities to surface the message through the UI, rather than through the console (even in the "Invalid Block" dialog).
To simplify the formatting, I've removed the chalk.isEnabled
split and just use chalk in all cases. It degrades gracefully to identity
when not enabled.
blocks/api/test/parser.js
Outdated
expect( isValidBlock( | ||
'Apples', | ||
getBlockType( 'core/test-block' ), | ||
{ fruit: 'Bananas' } | ||
) ).toBe( false ); | ||
|
||
process.env.NODE_ENV = env; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather see this structured as follows:
expect( () => isValidBlock( ... ) ).toThrow( ... );
or, better still:
expect( isvalidBlock( ... ) ).toBe( false );
expect( console.warn ).toHaveBeenCalledWith( ... );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per above #2056 (comment), this now tests that isValidBlock
throws.
db23ec0
to
cdde9c4
Compare
The previous invalid versions of the blocks were restored and tested as intentionally invalid as of cdde9c4. |
2ab47c7
to
6f5c56b
Compare
'Apples', | ||
getBlockType( 'core/test-block' ), | ||
{ fruit: 'Bananas' } | ||
) ).toBe( false ); | ||
) ).toThrow(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we test a specific error message here, or save this for later when we're ready to expose this info to the UI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is a pain to test with the ANSI escapes, unless we were to disable that for testing, or just test the pattern.
when we're ready to expose this info to the UI?
Which I'm starting to wonder, do we want the error message exposed in the UI anywhere? Currently we're only generating and throwing the error in development modes, which means it's not something generally accessible in the UI (in distributed plugin anyways).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, I think what should be shown in the UI is more like a text-mode diff and a prompt to confirm that the changes are acceptable.
Chalk still works when not enabled, but doesn't add any styles. This was avoided previously because messaging looked poor on per-character diff. We later changed to per-line diff with prefix, which looks reasonable in no-style environments. Further, prefixing retains readability for console.error, so drop thrown error.
6f5c56b
to
2f5a485
Compare
* Serialize the parsed block objects and verify the output (HTML + | ||
* block delimiters). | ||
*/ | ||
|
||
// `serialize` doesn't have a trailing newline, but the fixture | ||
// files should. | ||
const serializedActual = serialize( blocksActual ) + '\n'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside: I thought we got rid of this at some point?
if ( ! isExpectedValid ) { | ||
return; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for an invalid parse result, we should still verify that the block is initialized and serialized as expected (currently, no change).
blocks/test/full-content.js
Outdated
@@ -95,13 +95,23 @@ describe( 'full post content fixture', () => { | |||
|
|||
fileBasenames.forEach( f => { | |||
it( f, () => { | |||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have three styles of multi-line comments:
- WordPress standard
/*
- Calypso standard
//
- This
/**
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the WordPress standard was written before JSDoc came into wide usage.
I don't really have a preference here, do you? I just wrote them that way so they would visually look like separate sections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mine is //
, but I also didn't realize 'til recently that this was at odds with the core convention 😬 I'd say I have a preference against this style, only because it is easy to confuse with (and encounter errors as) JSDoc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went with /*
to preserve the "visual separator" aspect of these comments.
blocks/test/full-content.js
Outdated
const content = readFixtureFile( f + '.html' ); | ||
if ( content === null ) { | ||
throw new Error( | ||
'Missing fixture file: ' + f + '.html' | ||
); | ||
} | ||
|
||
const blocksActual = parse( content ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This declaration should stay below with the rest of the "list of block objects" stuff. I've added comments to better delineate this code into logical steps. In a separate PR, we could try adding new it()
test cases for each of tehse steps.
Codecov Report
@@ Coverage Diff @@
## master #2056 +/- ##
==========================================
+ Coverage 23.07% 23.46% +0.38%
==========================================
Files 141 141
Lines 4403 4424 +21
Branches 746 746
==========================================
+ Hits 1016 1038 +22
Misses 2856 2856
+ Partials 531 530 -1
Continue to review full report at Codecov.
|
311a2eb
to
269cac5
Compare
This pull request will need some further thought, particularly around validation errors, which might ought to be split to its own pull request. Notably with #2210, we no longer use beautification to validate post content, so simply logging the "actual" and "expected" contents might not be the most useful to illustrate the true difference that was captured. A couple considerations:
But as mentioned at #2056 (comment), there's also some open questions about the sorts of errors and messaging we want to be able to display in the UI, not just development-mode I might see about piecing apart this pull request into separate ones, as the original goal (title) has certainly drifted. |
I'd propose that in this PR we keep the fixture file changes and undo the changes to the parser API. I can help out with that over the next couple of days. |
Related: #1929 (comment)
This pull request seeks to resolve markup errors present in block fixtures to ensure that all fixtures are valid. As described in #1929 (comment), we'll want some intentionally-invalid examples as well, but those are not included in the changes here.
The changes also add some nice conveniences to better compare a failed parse between its actual and expected representation. For example:
This works only in Node environments currently, due to differences in log coloring between Node and browsers. This is something I'd like to consider improving, however separately.
There were a number of failed tests in
api/test/parser.js
after introducing these changes that I am surprised were ever working, since the dummy block implementations were clearly flawed. Those have been resolved here.Testing instructions:
Verify that tests pass when regenerating fixtures from scratch:
Ensure there are no regressions with revised pullquote and gallery attribute defaults (moved to default attributes for consistency between
edit
andsave
usage).