Skip to content

Cover the parts of the library nothing reached - #2360

Merged
enyo merged 1 commit into
mainfrom
test-coverage-gaps
Sep 12, 2026
Merged

Cover the parts of the library nothing reached#2360
enyo merged 1 commit into
mainfrom
test-coverage-gaps

Conversation

@enyo

@enyo enyo commented Sep 12, 2026

Copy link
Copy Markdown
Owner

Stacked on #2359, which added the measurement. This closes the gaps it exposed.

before after
Statements 72.26% 79.84%
Branches 68.70% 77.09%
Functions 80.47% 92.85%
Tests 191 252

emitter.js reaches 100% on all three.

The largest hole was drag and drop

The existing suite calls dropzone.drop() directly, which bypasses the listeners the constructor binds to the element. Every handler — dragstart, dragenter, dragover, dragleave, drop, dragend and the click forwarding, the whole point of the library — ran in no test at all.

They are covered now through real DOM events, including the two subtleties:

  • a drag carrying anything other than files is left alone, so the library does not interfere with other drag-and-drop on the page
  • dropEffect is set to copy unless effectAllowed says otherwise, which is what makes dragging out of Chrome's download bar work, and the read is wrapped because IE 11 threw on it

I checked these have teeth rather than passing vacuously: making containsFiles always return true fails four of them.

Also covered

paste, the transport failures (ontimeout, onerror, progress forwarding — only the success path had tests), displayExistingFile, the fallback form, the removal confirmations, renameFilename, handleFiles and Dropzone.discover.

Three tests pin behaviour that is wrong

Each points at the roadmap entry that will change it, so the fix has to be deliberate rather than accidental:

  • paste does not emit addedfiles, while drop() has since 6.2 and the hidden input always has
  • displayExistingFile does not count towards maxFilesFix maxFiles issue when added files from server #2003, where the documented workaround is why it cannot be fixed in a patch
  • new Dropzone(el, { forceFallback: true }) returns the fallback input, not a Dropzone. fallback() ends with return this.element.appendChild(...), and a constructor returning an object overrides this

A trap in the test suite itself

The emitter's tests sat behind return describe(...) — a CoffeeScript conversion artefact. The return ends the enclosing callback, so anything appended after it is never registered. That is exactly what happened here: the first four tests I added reported as passing while not running at all, and only counting them caught it.

There are eleven more in all.js. Removing every return there leaves the count at 252 either way, so none of them hide anything today — but they are the same trap, and they are gone.

End-to-end

Better than I expected going in: the suite already drives a real drop through a real DataTransfer against the built dropzone-min.js, so drag-and-drop, the standalone bundle and real HTTP were all covered.

The actual gap was failure — the test server only ever answered 200, so no rejected upload could be reached. It can now, and a new spec drives a real 500 through to the message rendered in the preview. That also pins something worth knowing: because the body is application/json with an error key, the user sees the server's own message, not dictResponseError.

Still worth adding later, in rough order of value: a chunked upload end to end (the S3 spec covers multipart, not Dropzone's own chunking), and maxFiles rejection.

What is deliberately still uncovered

dropzone.js sits at 77.42%, and the bulk of the remainder is one block: ExifRestore, roughly a hundred lines of base64 segment manipulation at lines 2026–2179. It is module-private, so testing it means either exporting it — which puts it in the public API for tests alone — or reaching it through createThumbnail with a real JPEG and canvas.

Worth doing, and worth saying where: the roadmap calls #2001, the EXIF rewrite, the highest-risk pull request in the backlog, whose author says they could not test it. That rewrite is exactly when this safety net is needed, so it belongs with it rather than here.

The rest is the jQuery plugin (needs jQuery present at module load), __guard__/__guardMethod__ and the IE 11 branches — all on the 7.0 list for deletion.

@github-actions

github-actions Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 79.42% 880 / 1108
🔵 Statements 79.84% 927 / 1161
🔵 Functions 92.85% 195 / 210
🔵 Branches 77.09% 505 / 655
File CoverageNo changed files found.
Generated in workflow #86 for commit 74931ec by the Vitest Coverage Report Action

@enyo
enyo added this pull request to stack #2364 September 12, 2026 17:56
Base automatically changed from coverage to main September 12, 2026 18:06
Coverage went from 72.26% of statements to 79.84%, and from 80.47% of
functions to 92.85%. 61 tests, in four new files plus the emitter's.

The largest hole was drag and drop. The existing suite calls dropzone.drop()
directly, which skips the listeners the constructor binds, so every handler
on the element -- the whole point of the library -- ran in no test at all.
They are covered now through real DOM events, including the guard that leaves
a drag carrying anything other than files alone, and the dropEffect that
makes dragging out of Chrome's download bar work.

Also covered: paste, the transport failures (ontimeout, onerror and progress
forwarding, previously only the success path had tests), displayExistingFile,
the fallback form, the removal confirmations, renameFilename, handleFiles and
Dropzone.discover. emitter.js reaches 100%.

Three of these pin behaviour that is wrong rather than right, each pointing
at the roadmap entry that will change it: paste still does not emit
addedfiles, displayExistingFile still does not count towards maxFiles (#2003),
and constructing with forceFallback returns the fallback element rather than
a Dropzone, because fallback() ends in a return and a constructor returning
an object overrides this.

The emitter's tests sat behind `return describe(...)`, a CoffeeScript
conversion artefact that ends the enclosing callback, so anything appended
after it was never registered -- which is exactly what happened when the
first four tests here were added and silently did not run. The eleven other
occurrences in all.js hide nothing today, but they are the same trap, and are
removed too. The suite count is unchanged by that, which is the point.

The end-to-end suite already drives a real drop through a real DataTransfer
against the built bundle, so the gap there was failure: the test server only
ever answered 200. It can now reject an upload, and a test drives a real 500
through to the message in the preview.
@enyo
enyo force-pushed the test-coverage-gaps branch from 0f47c4d to 74931ec Compare September 12, 2026 18:06
@enyo
enyo merged commit ced576a into main Sep 12, 2026
3 checks passed
@enyo
enyo deleted the test-coverage-gaps branch September 12, 2026 18:25
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

Successfully merging this pull request may close these issues.

1 participant