瀏覽代碼

Mention the file name in `exceedsSize` error message (#2918)

* Mention the file name in exceedsSize error message

* Fix implementation and tests

* Undo accidental commited changes
Merlijn Vos 3 年之前
父節點
當前提交
f2d30420f3

+ 82 - 72
packages/@uppy/core/src/index.js

@@ -13,6 +13,8 @@ const findIndex = require('@uppy/utils/lib/findIndex')
 const supportsUploadProgress = require('./supportsUploadProgress')
 const { justErrorsLogger, debugLogger } = require('./loggers')
 const Plugin = require('./Plugin')
+const { version } = require('../package.json')
+
 // Exported from here.
 class RestrictionError extends Error {
   constructor (...args) {
@@ -27,7 +29,7 @@ class RestrictionError extends Error {
  * adds/removes files and metadata.
  */
 class Uppy {
-  static VERSION = require('../package.json').version
+  static VERSION = version
 
   /**
    * Instantiate Uppy
@@ -55,7 +57,7 @@ class Uppy {
         // substitution.
         // TODO: In 2.0 `exceedsSize2` should be removed in and `exceedsSize` updated to use substitution.
         exceedsSize2: '%{backwardsCompat} %{size}',
-        exceedsSize: 'This file exceeds maximum allowed size of',
+        exceedsSize: '%{file} exceeds maximum allowed size of',
         inferiorSize: 'This file is smaller than the allowed size of %{size}',
         youCanOnlyUploadFileTypes: 'You can only upload: %{types}',
         noNewAlreadyUploading: 'Cannot add new files: already uploading',
@@ -108,7 +110,7 @@ class Uppy {
         allowedFileTypes: null,
       },
       meta: {},
-      onBeforeFileAdded: (currentFile, files) => currentFile,
+      onBeforeFileAdded: (currentFile) => currentFile,
       onBeforeUpload: (files) => files,
       store: DefaultStore(),
       logger: justErrorsLogger,
@@ -160,11 +162,13 @@ class Uppy {
     this.validateRestrictions = this.validateRestrictions.bind(this)
 
     // ___Why throttle at 500ms?
-    //    - We must throttle at >250ms for superfocus in Dashboard to work well (because animation takes 0.25s, and we want to wait for all animations to be over before refocusing).
-    //    [Practical Check]: if thottle is at 100ms, then if you are uploading a file, and click 'ADD MORE FILES', - focus won't activate in Firefox.
+    //    - We must throttle at >250ms for superfocus in Dashboard to work well
+    //    (because animation takes 0.25s, and we want to wait for all animations to be over before refocusing).
+    //    [Practical Check]: if thottle is at 100ms, then if you are uploading a file,
+    //    and click 'ADD MORE FILES', - focus won't activate in Firefox.
     //    - We must throttle at around >500ms to avoid performance lags.
     //    [Practical Check] Firefox, try to upload a big file for a prolonged period of time. Laptop will start to heat up.
-    this._calculateProgress = throttle(this._calculateProgress.bind(this), 500, { leading: true, trailing: true })
+    this.calculateProgress = throttle(this.calculateProgress.bind(this), 500, { leading: true, trailing: true })
 
     this.updateOnlineStatus = this.updateOnlineStatus.bind(this)
     this.resetProgress = this.resetProgress.bind(this)
@@ -207,7 +211,7 @@ class Uppy {
       recoveredState: null,
     })
 
-    this._storeUnsubscribe = this.store.subscribe((prevState, nextState, patch) => {
+    this.storeUnsubscribe = this.store.subscribe((prevState, nextState, patch) => {
       this.emit('state-update', prevState, nextState, patch)
       this.updateAll(nextState)
     })
@@ -217,7 +221,7 @@ class Uppy {
       window[this.opts.id] = this
     }
 
-    this._addListeners()
+    this.addListeners()
 
     // Re-enable if we’ll need some capabilities on boot, like isMobileDevice
     // this._setCapabilities()
@@ -436,7 +440,7 @@ class Uppy {
    */
   validateRestrictions (file, files) {
     try {
-      this._checkRestrictions(file, files)
+      this.checkRestrictions(file, files)
       return {
         result: true,
       }
@@ -456,7 +460,7 @@ class Uppy {
    * @param {Array} [files] array to check maxNumberOfFiles and maxTotalFileSize
    * @private
    */
-  _checkRestrictions (file, files = this.getFiles()) {
+  checkRestrictions (file, files = this.getFiles()) {
     const { maxFileSize, minFileSize, maxTotalFileSize, maxNumberOfFiles, allowedFileTypes } = this.opts.restrictions
 
     if (maxNumberOfFiles) {
@@ -490,13 +494,14 @@ class Uppy {
     if (maxTotalFileSize && file.size != null) {
       let totalFilesSize = 0
       totalFilesSize += file.size
-      files.forEach((file) => {
-        totalFilesSize += file.size
+      files.forEach((f) => {
+        totalFilesSize += f.size
       })
       if (totalFilesSize > maxTotalFileSize) {
         throw new RestrictionError(this.i18n('exceedsSize2', {
           backwardsCompat: this.i18n('exceedsSize'),
           size: prettierBytes(maxTotalFileSize),
+          file: file.name,
         }))
       }
     }
@@ -507,6 +512,7 @@ class Uppy {
         throw new RestrictionError(this.i18n('exceedsSize2', {
           backwardsCompat: this.i18n('exceedsSize'),
           size: prettierBytes(maxFileSize),
+          file: file.name,
         }))
       }
     }
@@ -526,7 +532,7 @@ class Uppy {
    *
    * @private
    */
-  _checkMinNumberOfFiles (files) {
+  checkMinNumberOfFiles (files) {
     const { minNumberOfFiles } = this.opts.restrictions
     if (Object.keys(files).length < minNumberOfFiles) {
       throw new RestrictionError(`${this.i18n('youHaveToAtLeastSelectX', { smart_count: minNumberOfFiles })}`)
@@ -544,7 +550,7 @@ class Uppy {
    * @param {boolean} [options.throwErr=true] — Errors shouldn’t be thrown, for example, in `upload-error` event
    * @private
    */
-  _showOrLogErrorAndThrow (err, { showInformer = true, file = null, throwErr = true } = {}) {
+  showOrLogErrorAndThrow (err, { showInformer = true, file = null, throwErr = true } = {}) {
     const message = typeof err === 'object' ? err.message : err
     const details = (typeof err === 'object' && err.details) ? err.details : ''
 
@@ -572,11 +578,11 @@ class Uppy {
     }
   }
 
-  _assertNewUploadAllowed (file) {
+  assertNewUploadAllowed (file) {
     const { allowNewUpload } = this.getState()
 
     if (allowNewUpload === false) {
-      this._showOrLogErrorAndThrow(new RestrictionError(this.i18n('noNewAlreadyUploading')), { file })
+      this.showOrLogErrorAndThrow(new RestrictionError(this.i18n('noNewAlreadyUploading')), { file })
     }
   }
 
@@ -587,15 +593,16 @@ class Uppy {
    *
    * The `files` value is passed in because it may be updated by the caller without updating the store.
    */
-  _checkAndCreateFileStateObject (files, file) {
-    const fileType = getFileType(file)
+  checkAndCreateFileStateObject (files, f) {
+    const fileType = getFileType(f)
+    let file = f
     file.type = fileType
 
     const onBeforeFileAddedResult = this.opts.onBeforeFileAdded(file, files)
 
     if (onBeforeFileAddedResult === false) {
       // Don’t show UI info for this error, as it should be done by the developer
-      this._showOrLogErrorAndThrow(new RestrictionError('Cannot add the file because onBeforeFileAdded returned false.'), { showInformer: false, file })
+      this.showOrLogErrorAndThrow(new RestrictionError('Cannot add the file because onBeforeFileAdded returned false.'), { showInformer: false, file })
     }
 
     if (typeof onBeforeFileAddedResult === 'object' && onBeforeFileAddedResult) {
@@ -616,7 +623,7 @@ class Uppy {
     const fileID = generateFileID(file)
 
     if (files[fileID] && !files[fileID].isGhost) {
-      this._showOrLogErrorAndThrow(new RestrictionError(this.i18n('noDuplicates', { fileName })), { file })
+      this.showOrLogErrorAndThrow(new RestrictionError(this.i18n('noDuplicates', { fileName })), { file })
     }
 
     const meta = file.meta || {}
@@ -624,7 +631,7 @@ class Uppy {
     meta.type = fileType
 
     // `null` means the size is unknown.
-    const size = isFinite(file.data.size) ? file.data.size : null
+    const size = Number.isFinite(file.data.size) ? file.data.size : null
     const newFile = {
       source: file.source || '',
       id: fileID,
@@ -651,16 +658,16 @@ class Uppy {
 
     try {
       const filesArray = Object.keys(files).map(i => files[i])
-      this._checkRestrictions(newFile, filesArray)
+      this.checkRestrictions(newFile, filesArray)
     } catch (err) {
-      this._showOrLogErrorAndThrow(err, { file: newFile })
+      this.showOrLogErrorAndThrow(err, { file: newFile })
     }
 
     return newFile
   }
 
   // Schedule an upload if `autoProceed` is enabled.
-  _startIfAutoProceed () {
+  startIfAutoProceed () {
     if (this.opts.autoProceed && !this.scheduledAutoProceed) {
       this.scheduledAutoProceed = setTimeout(() => {
         this.scheduledAutoProceed = null
@@ -682,10 +689,10 @@ class Uppy {
    * @returns {string} id for the added file
    */
   addFile (file) {
-    this._assertNewUploadAllowed(file)
+    this.assertNewUploadAllowed(file)
 
     const { files } = this.getState()
-    let newFile = this._checkAndCreateFileStateObject(files, file)
+    let newFile = this.checkAndCreateFileStateObject(files, file)
 
     // Users are asked to re-select recovered files without data,
     // and to keep the progress, meta and everthing else, we only replace said data
@@ -709,7 +716,7 @@ class Uppy {
     this.emit('files-added', [newFile])
     this.log(`Added file: ${newFile.name}, ${newFile.id}, mime type: ${newFile.type}`)
 
-    this._startIfAutoProceed()
+    this.startIfAutoProceed()
 
     return newFile.id
   }
@@ -722,7 +729,7 @@ class Uppy {
    * Programmatic users should usually still use `addFile()` on individual files.
    */
   addFiles (fileDescriptors) {
-    this._assertNewUploadAllowed()
+    this.assertNewUploadAllowed()
 
     // create a copy of the files object only once
     const files = { ...this.getState().files }
@@ -730,7 +737,7 @@ class Uppy {
     const errors = []
     for (let i = 0; i < fileDescriptors.length; i++) {
       try {
-        let newFile = this._checkAndCreateFileStateObject(files, fileDescriptors[i])
+        let newFile = this.checkAndCreateFileStateObject(files, fileDescriptors[i])
         // Users are asked to re-select recovered files without data,
         // and to keep the progress, meta and everthing else, we only replace said data
         if (files[newFile.id] && files[newFile.id].isGhost) {
@@ -767,7 +774,7 @@ class Uppy {
     }
 
     if (newFiles.length > 0) {
-      this._startIfAutoProceed()
+      this.startIfAutoProceed()
     }
 
     if (errors.length > 0) {
@@ -838,7 +845,7 @@ class Uppy {
     }
 
     this.setState(stateUpdate)
-    this._calculateTotalProgress()
+    this.calculateTotalProgress()
 
     const removedFileIDs = Object.keys(removedFiles)
     removedFileIDs.forEach((fileID) => {
@@ -859,7 +866,7 @@ class Uppy {
   pauseResume (fileID) {
     if (!this.getState().capabilities.resumableUploads
          || this.getFile(fileID).uploadComplete) {
-      return
+      return undefined
     }
 
     const wasPaused = this.getFile(fileID).isPaused || false
@@ -938,10 +945,10 @@ class Uppy {
       })
     }
 
-    const uploadID = this._createUpload(filesToRetry, {
+    const uploadID = this.createUpload(filesToRetry, {
       forceAllowNewUpload: true, // create new upload even if allowNewUpload: false
     })
-    return this._runUpload(uploadID)
+    return this.runUpload(uploadID)
   }
 
   cancelAll () {
@@ -969,10 +976,10 @@ class Uppy {
 
     this.emit('upload-retry', fileID)
 
-    const uploadID = this._createUpload([fileID], {
+    const uploadID = this.createUpload([fileID], {
       forceAllowNewUpload: true, // create new upload even if allowNewUpload: false
     })
-    return this._runUpload(uploadID)
+    return this.runUpload(uploadID)
   }
 
   reset () {
@@ -987,14 +994,14 @@ class Uppy {
     })
   }
 
-  _calculateProgress (file, data) {
+  calculateProgress (file, data) {
     if (!this.getFile(file.id)) {
       this.log(`Not setting progress for a file that has been removed: ${file.id}`)
       return
     }
 
     // bytesTotal may be null or zero; in that case we can't divide by it
-    const canHavePercentage = isFinite(data.bytesTotal) && data.bytesTotal > 0
+    const canHavePercentage = Number.isFinite(data.bytesTotal) && data.bytesTotal > 0
     this.setFileState(file.id, {
       progress: {
         ...this.getFile(file.id).progress,
@@ -1003,15 +1010,15 @@ class Uppy {
         percentage: canHavePercentage
           // TODO(goto-bus-stop) flooring this should probably be the choice of the UI?
           // we get more accurate calculations if we don't round this at all.
-          ? Math.round(data.bytesUploaded / data.bytesTotal * 100)
+          ? Math.round((data.bytesUploaded / data.bytesTotal) * 100)
           : 0,
       },
     })
 
-    this._calculateTotalProgress()
+    this.calculateTotalProgress()
   }
 
-  _calculateTotalProgress () {
+  calculateTotalProgress () {
     // calculate total progress, using the number of files currently uploading,
     // multiplied by 100 and the summ of individual progress of each file
     const files = this.getFiles()
@@ -1036,7 +1043,7 @@ class Uppy {
       const currentProgress = unsizedFiles.reduce((acc, file) => {
         return acc + file.progress.percentage
       }, 0)
-      const totalProgress = Math.round(currentProgress / progressMax * 100)
+      const totalProgress = Math.round((currentProgress / progressMax) * 100)
       this.setState({ totalProgress })
       return
     }
@@ -1052,12 +1059,12 @@ class Uppy {
       uploadedSize += file.progress.bytesUploaded
     })
     unsizedFiles.forEach((file) => {
-      uploadedSize += averageSize * (file.progress.percentage || 0) / 100
+      uploadedSize += (averageSize * (file.progress.percentage || 0)) / 100
     })
 
     let totalProgress = totalSize === 0
       ? 0
-      : Math.round(uploadedSize / totalSize * 100)
+      : Math.round((uploadedSize / totalSize) * 100)
 
     // hot fix, because:
     // uploadedSize ended up larger than totalSize, resulting in 1325% total
@@ -1073,7 +1080,7 @@ class Uppy {
    * Registers listeners for all global actions, like:
    * `error`, `file-removed`, `upload-progress`
    */
-  _addListeners () {
+  addListeners () {
     /**
      * @param {Error} error
      * @param {object} [file]
@@ -1107,11 +1114,11 @@ class Uppy {
           newError.details += ` ${error.details}`
         }
         newError.message = this.i18n('failedToUpload', { file: file.name })
-        this._showOrLogErrorAndThrow(newError, {
+        this.showOrLogErrorAndThrow(newError, {
           throwErr: false,
         })
       } else {
-        this._showOrLogErrorAndThrow(error, {
+        this.showOrLogErrorAndThrow(error, {
           throwErr: false,
         })
       }
@@ -1121,7 +1128,7 @@ class Uppy {
       this.setState({ error: null })
     })
 
-    this.on('upload-started', (file, upload) => {
+    this.on('upload-started', (file) => {
       if (!this.getFile(file.id)) {
         this.log(`Not setting progress for a file that has been removed: ${file.id}`)
         return
@@ -1137,7 +1144,7 @@ class Uppy {
       })
     })
 
-    this.on('upload-progress', this._calculateProgress)
+    this.on('upload-progress', this.calculateProgress)
 
     this.on('upload-success', (file, uploadResp) => {
       if (!this.getFile(file.id)) {
@@ -1161,7 +1168,7 @@ class Uppy {
         isPaused: false,
       })
 
-      this._calculateTotalProgress()
+      this.calculateTotalProgress()
     })
 
     this.on('preprocess-progress', (file, progress) => {
@@ -1220,7 +1227,7 @@ class Uppy {
 
     this.on('restored', () => {
       // Files may have changed--ensure progress is still accurate.
-      this._calculateTotalProgress()
+      this.calculateTotalProgress()
     })
 
     // show informer if offline
@@ -1261,6 +1268,7 @@ class Uppy {
    * @param {object} [opts] object with options to be passed to Plugin
    * @returns {object} self for chaining
    */
+  // eslint-disable-next-line no-shadow
   use (Plugin, opts) {
     if (typeof Plugin !== 'function') {
       const msg = `Expected a plugin class, but got ${Plugin === null ? 'null' : typeof Plugin}.`
@@ -1368,7 +1376,7 @@ class Uppy {
 
     this.reset()
 
-    this._storeUnsubscribe()
+    this.storeUnsubscribe()
 
     this.iteratePlugins((plugin) => {
       this.removePlugin(plugin)
@@ -1447,11 +1455,11 @@ class Uppy {
     this.log(`Core: attempting to restore upload "${uploadID}"`)
 
     if (!this.getState().currentUploads[uploadID]) {
-      this._removeUpload(uploadID)
+      this.removeUpload(uploadID)
       return Promise.reject(new Error('Nonexistent upload'))
     }
 
-    return this._runUpload(uploadID)
+    return this.runUpload(uploadID)
   }
 
   /**
@@ -1460,10 +1468,9 @@ class Uppy {
    * @param {Array<string>} fileIDs File IDs to include in this upload.
    * @returns {string} ID of this upload.
    */
-  _createUpload (fileIDs, opts = {}) {
-    const {
-      forceAllowNewUpload = false, // uppy.retryAll sets this to true — when retrying we want to ignore `allowNewUpload: false`
-    } = opts
+  createUpload (fileIDs, opts = {}) {
+    // uppy.retryAll sets this to true — when retrying we want to ignore `allowNewUpload: false`
+    const { forceAllowNewUpload = false } = opts
 
     const { allowNewUpload, currentUploads } = this.getState()
     if (!allowNewUpload && !forceAllowNewUpload) {
@@ -1493,7 +1500,7 @@ class Uppy {
     return uploadID
   }
 
-  _getUpload (uploadID) {
+  getUpload (uploadID) {
     const { currentUploads } = this.getState()
 
     return currentUploads[uploadID]
@@ -1506,7 +1513,7 @@ class Uppy {
    * @param {object} data Data properties to add to the result object.
    */
   addResultData (uploadID, data) {
-    if (!this._getUpload(uploadID)) {
+    if (!this.getUpload(uploadID)) {
       this.log(`Not setting result for an upload that has been removed: ${uploadID}`)
       return
     }
@@ -1522,7 +1529,7 @@ class Uppy {
    *
    * @param {string} uploadID The ID of the upload.
    */
-  _removeUpload (uploadID) {
+  removeUpload (uploadID) {
     const currentUploads = { ...this.getState().currentUploads }
     delete currentUploads[uploadID]
 
@@ -1536,7 +1543,7 @@ class Uppy {
    *
    * @private
    */
-  _runUpload (uploadID) {
+  runUpload (uploadID) {
     const uploadData = this.getState().currentUploads[uploadID]
     const restoreStep = uploadData.step
 
@@ -1573,8 +1580,9 @@ class Uppy {
 
         // TODO give this the `updatedUpload` object as its only parameter maybe?
         // Otherwise when more metadata may be added to the upload this would keep getting more parameters
+        // eslint-disable-next-line consistent-return
         return fn(updatedUpload.fileIDs, uploadID)
-      }).then((result) => {
+      }).then(() => {
         return null
       })
     })
@@ -1583,7 +1591,7 @@ class Uppy {
     // promise from this method if the upload failed.
     lastStep.catch((err) => {
       this.emit('error', err, uploadID)
-      this._removeUpload(uploadID)
+      this.removeUpload(uploadID)
     })
 
     return lastStep.then(() => {
@@ -1628,8 +1636,9 @@ class Uppy {
       const { result } = currentUpload
       this.emit('complete', result)
 
-      this._removeUpload(uploadID)
+      this.removeUpload(uploadID)
 
+      // eslint-disable-next-line consistent-return
       return result
     }).then((result) => {
       if (result == null) {
@@ -1667,14 +1676,15 @@ class Uppy {
     }
 
     return Promise.resolve()
-      .then(() => this._checkMinNumberOfFiles(files))
+      .then(() => this.checkMinNumberOfFiles(files))
       .catch((err) => {
-        this._showOrLogErrorAndThrow(err)
+        this.showOrLogErrorAndThrow(err)
       })
       .then(() => {
         const { currentUploads } = this.getState()
         // get a list of files that are currently assigned to uploads
-        const currentlyUploadingFiles = Object.keys(currentUploads).reduce((prev, curr) => prev.concat(currentUploads[curr].fileIDs), [])
+        const currentlyUploadingFiles = Object.keys(currentUploads)
+          .reduce((prev, curr) => prev.concat(currentUploads[curr].fileIDs), [])
 
         const waitingFileIDs = []
         Object.keys(files).forEach((fileID) => {
@@ -1685,18 +1695,18 @@ class Uppy {
           }
         })
 
-        const uploadID = this._createUpload(waitingFileIDs)
-        return this._runUpload(uploadID)
+        const uploadID = this.createUpload(waitingFileIDs)
+        return this.runUpload(uploadID)
       })
       .catch((err) => {
-        this._showOrLogErrorAndThrow(err, {
+        this.showOrLogErrorAndThrow(err, {
           showInformer: false,
         })
       })
   }
 }
 
-module.exports = function (opts) {
+module.exports = function core (opts) {
   return new Uppy(opts)
 }
 

+ 41 - 38
packages/@uppy/core/src/index.test.js

@@ -1,3 +1,4 @@
+/* eslint no-console: "off", no-restricted-syntax: "off" */
 const fs = require('fs')
 const path = require('path')
 const prettierBytes = require('@transloadit/prettier-bytes')
@@ -69,15 +70,13 @@ describe('src/Core', () => {
     it('should not be able to add a plugin that has no id', () => {
       const core = Core()
 
-      expect(() =>
-        core.use(InvalidPluginWithoutId)).toThrowErrorMatchingSnapshot()
+      expect(() => core.use(InvalidPluginWithoutId)).toThrowErrorMatchingSnapshot()
     })
 
     it('should not be able to add a plugin that has no type', () => {
       const core = Core()
 
-      expect(() =>
-        core.use(InvalidPluginWithoutType)).toThrowErrorMatchingSnapshot()
+      expect(() => core.use(InvalidPluginWithoutType)).toThrowErrorMatchingSnapshot()
     })
 
     it('should return the plugin that matches the specified name', () => {
@@ -259,7 +258,7 @@ describe('src/Core', () => {
     })
 
     const fileIDs = Object.keys(core.getState().files)
-    const id = core._createUpload(fileIDs)
+    const id = core.createUpload(fileIDs)
 
     expect(core.getState().currentUploads[id]).toBeDefined()
     expect(Object.keys(core.getState().files).length).toEqual(2)
@@ -307,13 +306,13 @@ describe('src/Core', () => {
   describe('upload hooks', () => {
     it('should add data returned from upload hooks to the .upload() result', () => {
       const core = new Core()
-      core.addPreProcessor((fileIDs, uploadID) => {
+      core.addPreProcessor((_, uploadID) => {
         core.addResultData(uploadID, { pre: 'ok' })
       })
-      core.addPostProcessor((fileIDs, uploadID) => {
+      core.addPostProcessor((_, uploadID) => {
         core.addResultData(uploadID, { post: 'ok' })
       })
-      core.addUploader((fileIDs, uploadID) => {
+      core.addUploader((_, uploadID) => {
         core.addResultData(uploadID, { upload: 'ok' })
       })
       return core.upload().then((result) => {
@@ -327,16 +326,16 @@ describe('src/Core', () => {
   describe('preprocessors', () => {
     it('should add a preprocessor', () => {
       const core = new Core()
-      const preprocessor = function () {}
+      const preprocessor = () => {}
       core.addPreProcessor(preprocessor)
       expect(core.preProcessors[0]).toEqual(preprocessor)
     })
 
     it('should remove a preprocessor', () => {
       const core = new Core()
-      const preprocessor1 = function () {}
-      const preprocessor2 = function () {}
-      const preprocessor3 = function () {}
+      const preprocessor1 = () => {}
+      const preprocessor2 = () => {}
+      const preprocessor3 = () => {}
       core.addPreProcessor(preprocessor1)
       core.addPreProcessor(preprocessor2)
       core.addPreProcessor(preprocessor3)
@@ -456,16 +455,16 @@ describe('src/Core', () => {
   describe('postprocessors', () => {
     it('should add a postprocessor', () => {
       const core = new Core()
-      const postprocessor = function () {}
+      const postprocessor = () => {}
       core.addPostProcessor(postprocessor)
       expect(core.postProcessors[0]).toEqual(postprocessor)
     })
 
     it('should remove a postprocessor', () => {
       const core = new Core()
-      const postprocessor1 = function () {}
-      const postprocessor2 = function () {}
-      const postprocessor3 = function () {}
+      const postprocessor1 = () => {}
+      const postprocessor2 = () => {}
+      const postprocessor3 = () => {}
       core.addPostProcessor(postprocessor1)
       core.addPostProcessor(postprocessor2)
       core.addPostProcessor(postprocessor3)
@@ -586,16 +585,16 @@ describe('src/Core', () => {
   describe('uploaders', () => {
     it('should add an uploader', () => {
       const core = new Core()
-      const uploader = function () {}
+      const uploader = () => {}
       core.addUploader(uploader)
       expect(core.uploaders[0]).toEqual(uploader)
     })
 
     it('should remove an uploader', () => {
       const core = new Core()
-      const uploader1 = function () {}
-      const uploader2 = function () {}
-      const uploader3 = function () {}
+      const uploader1 = () => {}
+      const uploader2 = () => {}
+      const uploader3 = () => {}
       core.addUploader(uploader1)
       core.addUploader(uploader2)
       core.addUploader(uploader3)
@@ -733,10 +732,11 @@ describe('src/Core', () => {
 
     it('should not allow a file if onBeforeFileAdded returned false', () => {
       const core = new Core({
-        onBeforeFileAdded: (file, files) => {
+        onBeforeFileAdded: (file) => {
           if (file.source === 'jest') {
             return false
           }
+          return true
         },
       })
       expect(() => {
@@ -851,7 +851,7 @@ describe('src/Core', () => {
   describe('uploading a file', () => {
     it('should return a { successful, failed } pair containing file objects', () => {
       const core = new Core()
-      core.addUploader((fileIDs) => Promise.resolve())
+      core.addUploader(() => Promise.resolve())
 
       core.addFile({ source: 'jest', name: 'foo.jpg', type: 'image/jpeg', data: new Uint8Array() })
       core.addFile({ source: 'jest', name: 'bar.jpg', type: 'image/jpeg', data: new Uint8Array() })
@@ -903,7 +903,7 @@ describe('src/Core', () => {
           fileIDs: ['uppy-file4/jpg-1e-image/jpeg', 'uppy-file5/jpg-1e-image/jpeg', 'uppy-file6/jpg-1e-image/jpeg'],
         },
       }
-      core.addUploader((fileIDs) => Promise.resolve())
+      core.addUploader(() => Promise.resolve())
 
       core.addFile({ source: 'jest', name: 'foo.jpg', type: 'image/jpeg', data: new Uint8Array() })
       core.addFile({ source: 'jest', name: 'bar.jpg', type: 'image/jpeg', data: new Uint8Array() })
@@ -914,8 +914,9 @@ describe('src/Core', () => {
 
     it('should not upload if onBeforeUpload returned false', () => {
       const core = new Core({
+        // eslint-disable-next-line consistent-return
         onBeforeUpload: (files) => {
-          for (var fileId in files) {
+          for (const fileId in files) {
             if (files[fileId].name === '123.foo') {
               return false
             }
@@ -1296,7 +1297,7 @@ describe('src/Core', () => {
         bytesTotal: 17175,
       })
 
-      core._calculateProgress.flush()
+      core.calculateProgress.flush()
 
       expect(core.getFile(fileId).progress).toEqual({
         percentage: 100,
@@ -1331,7 +1332,7 @@ describe('src/Core', () => {
         data: {},
       })
 
-      core._calculateTotalProgress()
+      core.calculateTotalProgress()
 
       const uploadPromise = core.upload()
       await new Promise((resolve) => core.once('upload-started', resolve))
@@ -1404,7 +1405,7 @@ describe('src/Core', () => {
         data: {},
       })
 
-      core._calculateTotalProgress()
+      core.calculateTotalProgress()
 
       // foo.jpg at 35%, bar.jpg at 0%
       expect(core.getState().totalProgress).toBe(18)
@@ -1445,8 +1446,8 @@ describe('src/Core', () => {
         bytesTotal: 17175,
       })
 
-      core._calculateTotalProgress()
-      core._calculateProgress.flush()
+      core.calculateTotalProgress()
+      core.calculateProgress.flush()
 
       expect(core.getState().totalProgress).toEqual(66)
     })
@@ -1483,8 +1484,8 @@ describe('src/Core', () => {
         bytesTotal: 17175,
       })
 
-      core._calculateTotalProgress()
-      core._calculateProgress.flush()
+      core.calculateTotalProgress()
+      core.calculateProgress.flush()
 
       expect(core.getState().totalProgress).toEqual(66)
 
@@ -1618,8 +1619,8 @@ describe('src/Core', () => {
         })
         throw new Error('should have thrown')
       } catch (err) {
-        expect(err).toMatchObject(new Error('This file exceeds maximum allowed size of 1.2 KB'))
-        expect(core.getState().info.message).toEqual('This file exceeds maximum allowed size of 1.2 KB')
+        expect(err).toMatchObject(new Error('foo.jpg exceeds maximum allowed size of 1.2 KB'))
+        expect(core.getState().info.message).toEqual('foo.jpg exceeds maximum allowed size of 1.2 KB')
       }
     })
 
@@ -1666,7 +1667,7 @@ describe('src/Core', () => {
           data: new File([sampleImage], { type: 'image/jpeg' }),
         })
       }).toThrowError(
-        new Error('This file exceeds maximum allowed size of 33 KB')
+        new Error('foo1.jpg exceeds maximum allowed size of 33 KB')
       )
     })
 
@@ -1724,11 +1725,13 @@ describe('src/Core', () => {
         name: 'test.jpg',
         data: new Blob([Buffer.alloc(2 * maxFileSize)]),
       }
-      const errorMessage = `${core.i18n('exceedsSize')} ${prettierBytes(maxFileSize)}`
+      const errorMessage = `${core.i18n('exceedsSize', { file: file.name })} ${prettierBytes(maxFileSize)}`
       try {
         core.on('restriction-failed', restrictionsViolatedEventMock)
         core.addFile(file)
-      } catch (err) {}
+      } catch (err) {
+        // something
+      }
 
       expect(restrictionsViolatedEventMock.mock.calls.length).toEqual(1)
       expect(restrictionsViolatedEventMock.mock.calls[0][0].name).toEqual(file.name)
@@ -1910,7 +1913,7 @@ describe('src/Core', () => {
         data: new File([sampleImage], { type: 'image/jpeg' }),
       })
 
-      core._createUpload(Object.keys(core.getState().files))
+      core.createUpload(Object.keys(core.getState().files))
       const uploadId = Object.keys(core.getState().currentUploads)[0]
       const currentUploadsState = {}
       currentUploadsState[uploadId] = {
@@ -1932,7 +1935,7 @@ describe('src/Core', () => {
         },
       })
 
-      expect(core.i18n('exceedsSize')).toBe('This file exceeds maximum allowed size of')
+      expect(core.i18n('exceedsSize')).toBe('%{file} exceeds maximum allowed size of')
       expect(core.i18n('test')).toBe('beep boop')
     })
   })

+ 1 - 1
packages/@uppy/locales/src/en_US.js

@@ -53,7 +53,7 @@ en_US.strings = {
   enterCorrectUrl: 'Incorrect URL: Please make sure you are entering a direct link to a file',
   enterTextToSearch: 'Enter text to search for images',
   enterUrlToImport: 'Enter URL to import a file',
-  exceedsSize: 'This file exceeds maximum allowed size of',
+  exceedsSize: '%{file} exceeds maximum allowed size of',
   exceedsSize2: '%{backwardsCompat} %{size}',
   failedToFetch: 'Companion failed to fetch this URL, please make sure it’s correct',
   failedToUpload: 'Failed to upload %{file}',

+ 2 - 2
packages/@uppy/locales/src/nl_NL.js

@@ -41,8 +41,8 @@ nl_NL.strings = {
   encoding: 'Coderen...',
   enterCorrectUrl: 'Ongeldige URL: Zorg dat je een directe link naar een bestand invoert',
   enterUrlToImport: 'Voeg URL toe om een bestand te importeren',
-  exceedsSize2: 'Dit bestand overschrijdt de maximaal toegelaten bestandsgrootte van %{size}',
-  exceedsSize: 'Dit bestand overschrijdt de maximaal toegelaten bestandsgrootte van',
+  exceedsSize2: '%{file} overschrijdt de maximaal toegelaten bestandsgrootte van %{size}',
+  exceedsSize: '%{file} overschrijdt de maximaal toegelaten bestandsgrootte van',
   failedToFetch: 'Companion kan deze URL niet laden, controleer of de URL correct is',
   failedToUpload: 'Kon %{file} niet uploaden',
   fileSource: 'Bronbestand: %{name}',