Commit 49089fa6 authored by Luciano Pacheco's avatar Luciano Pacheco Committed by Chromium LUCI CQ

Files app: Generate JS module for //u/f/f/b/j/duplicate_finder.js

JS modules for:
- //ui/file_manager/file_manager/background/js/
  - duplicate_finder.js
  - duplicate_finder_unitetst.js
- //u/file_manager/externs/background/duplicate_finder.js

Because Closure doesn't deal well importing the same namespace from
different files, I started splitting the "importer" namespace so each
file will have its own namespace.  Files in the "externs" directory will
have the suffix "Interface" on their namespace.  I'll use this logic for
all files related to "importer" namespace.

Bug: 1133186
Change-Id: I10240cb6d3083daf4bbc53773c391feb9d66c693
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2596473
Commit-Queue: Luciano Pacheco <lucmult@chromium.org>
Reviewed-by: default avatarJeremie Boulic <jboulic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837997}
parent 60fedd2e
......@@ -58,7 +58,7 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DriveSyncHandlerTest) {
}
IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DuplicateFinderTest) {
RunTestURL("background/js/duplicate_finder_unittest_gen.html");
RunTestURL("background/js/duplicate_finder_unittest.m_gen.html");
}
IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ExifParser) {
......
......@@ -43,6 +43,18 @@ js_library("drive_sync_handler.m") {
extra_deps = [ ":modulize" ]
}
js_library("duplicate_finder.m") {
sources = [
"$root_gen_dir/ui/file_manager/externs/background/duplicate_finder.m.js",
]
deps = [
":import_history.m",
"//ui/file_manager/file_manager/common/js:importer_common.m",
]
extra_deps = [ ":modulize" ]
}
js_library("crostini.m") {
sources = [ "$root_gen_dir/ui/file_manager/externs/background/crostini.m.js" ]
deps = [ "..:volume_manager.m" ]
......@@ -101,6 +113,7 @@ js_modulizer("modulize") {
"background_base.js",
"crostini.js",
"drive_sync_handler.js",
"duplicate_finder.js",
"file_operation_manager.js",
"import_history.js",
"media_scanner.js",
......
......@@ -2,21 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// #import {importer} from '../../file_manager/common/js/importer_common.m.js';
// #import {importerHistoryInterfaces} from './import_history.m.js';
// Namespace
// eslint-disable-next-line no-var
var importer = importer || {};
/* #export */ const duplicateFinderInterfaces = {};
/**
* Declare DispositionChecker class.
* @interface
*/
importer.DispositionChecker = class {
duplicateFinderInterfaces.DispositionChecker = class {
/**
* Factory for a function that returns a file entry's content disposition.
*
* @param {!importerHistoryInterfaces.HistoryLoader} historyLoader
*
* @return {!importer.DispositionChecker.CheckerFunction}
* @return {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction}
*/
static createChecker(historyLoader) {}
};
......@@ -28,4 +30,4 @@ importer.DispositionChecker = class {
* @typedef {function(!FileEntry, !importer.Destination, !importer.ScanMode):
* !Promise<!importer.Disposition>}
*/
importer.DispositionChecker.CheckerFunction;
duplicateFinderInterfaces.DispositionChecker.CheckerFunction;
......@@ -21,7 +21,8 @@ importer.MediaImportHandler = class extends importer.ImportRunner {
/**
* @param {!ProgressCenter} progressCenter
* @param {!importerHistoryInterfaces.HistoryLoader} historyLoader
* @param {!importer.DispositionChecker.CheckerFunction} dispositionChecker
* @param {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction}
* dispositionChecker
* @param {!DriveSyncHandler} driveSyncHandler
*/
constructor(
......@@ -45,7 +46,8 @@ importer.MediaImportHandler.ImportTask = class {
* @param {!mediaScannerInterfaces.ScanResult} scanResult
* @param {!Promise<!DirectoryEntry>} directoryPromise
* @param {!importer.Destination} destination The logical destination.
* @param {!importer.DispositionChecker.CheckerFunction} dispositionChecker
* @param {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction}
* dispositionChecker
*/
constructor(
taskId, historyLoader, scanResult, directoryPromise, destination,
......
......@@ -78,6 +78,7 @@ js_type_check("closure_compile_jsmodules") {
":background_base.m",
":crostini.m",
":drive_sync_handler.m",
":duplicate_finder.m",
":entry_location_impl.m",
":file_operation_util.m",
":import_history.m",
......@@ -389,14 +390,36 @@ js_library("duplicate_finder") {
externs_list = [ "//ui/file_manager/externs/background/duplicate_finder.js" ]
}
js_unittest("duplicate_finder_unittest") {
js_library("duplicate_finder.m") {
sources = [ "$root_gen_dir/ui/file_manager/file_manager/background/js/duplicate_finder.m.js" ]
deps = [
":duplicate_finder",
":mock_volume_manager",
":test_import_history",
"//ui/file_manager/base/js:mock_chrome",
"//ui/file_manager/file_manager/common/js:mock_entry",
"//ui/file_manager/file_manager/common/js:test_importer_common",
":import_history.m",
":volume_manager_factory.m",
"//ui/file_manager/base/js:volume_manager_types.m",
"//ui/file_manager/externs:volume_manager.m",
"//ui/file_manager/externs/background:duplicate_finder.m",
"//ui/file_manager/externs/background:import_history.m",
"//ui/file_manager/file_manager/common/js:importer_common.m",
"//ui/file_manager/file_manager/common/js:lru_cache.m",
"//ui/file_manager/file_manager/common/js:metrics.m",
]
extra_deps = [ ":modulize" ]
}
js_unittest("duplicate_finder_unittest.m") {
deps = [
":duplicate_finder.m",
":mock_volume_manager.m",
":test_import_history.m",
"//chrome/test/data/webui:chai_assert",
"//ui/file_manager/base/js:mock_chrome.m",
"//ui/file_manager/base/js:test_error_reporting.m",
"//ui/file_manager/base/js:volume_manager_types.m",
"//ui/file_manager/externs:volume_info.m",
"//ui/file_manager/externs/background:duplicate_finder.m",
"//ui/file_manager/file_manager/common/js:importer_common.m",
"//ui/file_manager/file_manager/common/js:mock_entry.m",
]
}
......@@ -985,6 +1008,7 @@ js_test_gen_html("js_test_gen_html_modules") {
deps = [
":crostini_unittest.m",
":drive_sync_handler_unittest.m",
":duplicate_finder_unittest.m",
":import_history_unittest.m",
":media_scanner_unittest.m",
":metadata_proxy_unittest.m",
......@@ -1005,7 +1029,6 @@ js_test_gen_html("js_test_gen_html_modules") {
js_test_gen_html("js_test_gen_html") {
deps = [
":device_handler_unittest",
":duplicate_finder_unittest",
":file_operation_handler_unittest",
":file_operation_manager_unittest",
":media_import_handler_unittest",
......@@ -1041,6 +1064,7 @@ js_modulizer("modulize") {
"drive_sync_handler.js",
"media_scanner.js",
"mock_media_scanner.js",
"duplicate_finder.js",
]
namespace_rewrites = cr_namespace_rewrites
......
......@@ -56,10 +56,11 @@ class FileBrowserBackgroundImpl extends BackgroundBaseImpl {
this.driveSyncHandler = new DriveSyncHandlerImpl(this.progressCenter);
/**
* @type {!importer.DispositionChecker.CheckerFunction}
* @type {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction}
*/
this.dispositionChecker_ =
importer.DispositionCheckerImpl.createChecker(this.historyLoader);
duplicateFinder.DispositionCheckerImpl.createChecker(
this.historyLoader);
/**
* Provides support for scanning media devices as part of Cloud Import.
......
......@@ -2,14 +2,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Namespace
window.importer = window.importer || {};
/**
* @fileoverview
* @suppress {uselessCode} Temporary suppress because of the line exporting.
*/
// clang-format off
// #import {VolumeManagerCommon} from '../../../base/js/volume_manager_types.m.js';
// #import {VolumeManager} from '../../../externs/volume_manager.m.js';
// #import {importerHistoryInterfaces} from '../../../externs/background/import_history.m.js';
// #import {duplicateFinderInterfaces} from '../../../externs/background/duplicate_finder.m.js';
// #import {volumeManagerFactory} from './volume_manager_factory.m.js';
// #import {metrics} from '../../common/js/metrics.m.js';
// #import {importerHistory} from './import_history.m.js';
// #import {LRUCache} from '../../common/js/lru_cache.m.js';
// #import {importer} from '../../common/js/importer_common.m.js';
// clang-format on
// eslint-disable-next-line no-var
var duplicateFinder = {};
/**
* A duplicate finder for Google Drive.
*
*/
importer.DriveDuplicateFinder = class DriveDuplicateFinder {
duplicateFinder.DriveDuplicateFinder = class {
constructor() {
/** @private {Promise<string>} */
this.driveIdPromise_ = null;
......@@ -18,8 +36,8 @@ importer.DriveDuplicateFinder = class DriveDuplicateFinder {
* An bounded cache of most recently calculated file content hashcodes.
* @private {!LRUCache<!Promise<string>>}
*/
this.hashCache_ =
new LRUCache(importer.DriveDuplicateFinder.MAX_CACHED_HASHCODES_);
this.hashCache_ = new LRUCache(
duplicateFinder.DriveDuplicateFinder.MAX_CACHED_HASHCODES_);
}
/**
......@@ -54,22 +72,22 @@ importer.DriveDuplicateFinder = class DriveDuplicateFinder {
}
const hashPromise = new Promise(
/** @this {importer.DriveDuplicateFinder} */
/** @this {duplicateFinder.DriveDuplicateFinder} */
(resolve, reject) => {
const startTime = new Date().getTime();
chrome.fileManagerPrivate.computeChecksum(
entry,
/**
* @param {string|undefined} result The content hash.
* @this {importer.DriveDuplicateFinder}
* @this {duplicateFinder.DriveDuplicateFinder}
*/
result => {
const elapsedTime = new Date().getTime() - startTime;
// Send the timing to GA only if it is sorta exceptionally
// long. A one second, CPU intensive operation, is pretty
// long.
if (elapsedTime >=
importer.DriveDuplicateFinder.HASH_EVENT_THRESHOLD_) {
if (elapsedTime >= duplicateFinder.DriveDuplicateFinder
.HASH_EVENT_THRESHOLD_) {
console.info(
'Content hash computation took ' + elapsedTime +
' ms.');
......@@ -131,7 +149,7 @@ importer.DriveDuplicateFinder = class DriveDuplicateFinder {
*/
searchFilesByHash_(hash, volumeId) {
return new Promise(
/** @this {importer.DriveDuplicateFinder} */
/** @this {duplicateFinder.DriveDuplicateFinder} */
(resolve, reject) => {
const startTime = new Date().getTime();
chrome.fileManagerPrivate.searchFilesByHashes(
......@@ -142,8 +160,8 @@ importer.DriveDuplicateFinder = class DriveDuplicateFinder {
urls => {
const elapsedTime = new Date().getTime() - startTime;
// Send the timing to GA only if it is sorta exceptionally long.
if (elapsedTime >=
importer.DriveDuplicateFinder.SEARCH_EVENT_THRESHOLD_) {
if (elapsedTime >= duplicateFinder.DriveDuplicateFinder
.SEARCH_EVENT_THRESHOLD_) {
metrics.recordTime(
'DriveDuplicateFinder.LongSearchByHash', elapsedTime);
}
......@@ -158,13 +176,13 @@ importer.DriveDuplicateFinder = class DriveDuplicateFinder {
};
/** @private @const {number} */
importer.DriveDuplicateFinder.HASH_EVENT_THRESHOLD_ = 5000;
duplicateFinder.DriveDuplicateFinder.HASH_EVENT_THRESHOLD_ = 5000;
/** @private @const {number} */
importer.DriveDuplicateFinder.SEARCH_EVENT_THRESHOLD_ = 1000;
duplicateFinder.DriveDuplicateFinder.SEARCH_EVENT_THRESHOLD_ = 1000;
/** @private @const {number} */
importer.DriveDuplicateFinder.MAX_CACHED_HASHCODES_ = 10000;
duplicateFinder.DriveDuplicateFinder.MAX_CACHED_HASHCODES_ = 10000;
/**
......@@ -173,18 +191,18 @@ importer.DriveDuplicateFinder.MAX_CACHED_HASHCODES_ = 10000;
* primary source for duplicate checking (with the exception
* of in-scan deduplication, where duplicate results that
* are within the scan are ignored).
* @implements {importer.DispositionChecker}
* @implements {duplicateFinderInterfaces.DispositionChecker}
*/
importer.DispositionCheckerImpl = class {
duplicateFinder.DispositionCheckerImpl = class {
/**
* @param {!importerHistoryInterfaces.HistoryLoader} historyLoader
* @param {!importer.DriveDuplicateFinder} contentMatcher
* @param {!duplicateFinder.DriveDuplicateFinder} contentMatcher
*/
constructor(historyLoader, contentMatcher) {
/** @private {!importerHistoryInterfaces.HistoryLoader} */
this.historyLoader_ = historyLoader;
/** @private {!importer.DriveDuplicateFinder} */
/** @private {!duplicateFinder.DriveDuplicateFinder} */
this.contentMatcher_ = contentMatcher;
}
......@@ -200,7 +218,7 @@ importer.DispositionCheckerImpl = class {
}
return new Promise(
/** @this {importer.DispositionChecker} */
/** @this {duplicateFinderInterfaces.DispositionChecker} */
(resolve, reject) => {
this.hasHistoryDuplicate_(entry, destination)
.then(
......@@ -264,11 +282,14 @@ importer.DispositionCheckerImpl = class {
*
* @param {!importerHistoryInterfaces.HistoryLoader} historyLoader
*
* @return {!importer.DispositionChecker.CheckerFunction}
* @return {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction}
*/
static createChecker(historyLoader) {
const checker = new importer.DispositionCheckerImpl(
historyLoader, new importer.DriveDuplicateFinder());
const checker = new duplicateFinder.DispositionCheckerImpl(
historyLoader, new duplicateFinder.DriveDuplicateFinder());
return checker.getDisposition.bind(checker);
}
};
// eslint-disable-next-line semi,no-extra-semi
/* #export */ {duplicateFinder};
......@@ -2,8 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/** @type {!importer.DriveDuplicateFinder} */
let duplicateFinder;
import {assertEquals, assertFalse, assertTrue} from 'chrome://test/chai_assert.js';
import {installMockChrome, MockCommandLinePrivate} from '../../../base/js/mock_chrome.m.js';
import {reportPromise} from '../../../base/js/test_error_reporting.m.js';
import {VolumeManagerCommon} from '../../../base/js/volume_manager_types.m.js';
import {duplicateFinderInterfaces} from '../../../externs/background/duplicate_finder.m.js';
import {VolumeInfo} from '../../../externs/volume_info.m.js';
import {importer} from '../../common/js/importer_common.m.js';
import {MockFileSystem} from '../../common/js/mock_entry.m.js';
import {duplicateFinder} from './duplicate_finder.m.js';
import {MockVolumeManager} from './mock_volume_manager.m.js';
import {importerTestHistory} from './test_import_history.m.js';
/** @type {!duplicateFinder.DriveDuplicateFinder} */
let duplicateFinderTest;
/** @type {VolumeInfo} */
let drive;
......@@ -26,14 +40,14 @@ let fileSystem;
/** @type {!importerTestHistory.TestImportHistory} */
let testHistory;
/** @type {importer.DispositionChecker.CheckerFunction} */
/** @type {duplicateFinderInterfaces.DispositionChecker.CheckerFunction} */
let getDisposition;
window.metrics = {
recordTime: function() {},
};
function setUp() {
export function setUp() {
window.loadTimeData.getString = id => id;
const mockChrome = {
fileManagerPrivate: {
......@@ -75,25 +89,26 @@ function setUp() {
MockVolumeManager.installMockSingleton(volumeManager);
testHistory = new importerTestHistory.TestImportHistory();
duplicateFinder = new importer.DriveDuplicateFinder();
getDisposition = importer.DispositionCheckerImpl.createChecker(testHistory);
duplicateFinderTest = new duplicateFinder.DriveDuplicateFinder();
getDisposition =
duplicateFinder.DispositionCheckerImpl.createChecker(testHistory);
}
// Verifies the correct result when a duplicate exists.
function testCheckDuplicateTrue(callback) {
export function testCheckDuplicateTrue(callback) {
const filePaths = ['/foo.txt'];
const fileHashes = ['abc123'];
const files = setupHashes(filePaths, fileHashes);
reportPromise(
duplicateFinder.isDuplicate(files[0]).then(isDuplicate => {
duplicateFinderTest.isDuplicate(files[0]).then(isDuplicate => {
assertTrue(isDuplicate);
}),
callback);
}
// Verifies the correct result when a duplicate doesn't exist.
function testCheckDuplicateFalse(callback) {
export function testCheckDuplicateFalse(callback) {
const filePaths = ['/foo.txt'];
const fileHashes = ['abc123'];
const files = setupHashes(filePaths, fileHashes);
......@@ -104,13 +119,13 @@ function testCheckDuplicateFalse(callback) {
const newFile = /** @type {!FileEntry} */ (fileSystem.entries[newFilePath]);
reportPromise(
duplicateFinder.isDuplicate(newFile).then(isDuplicate => {
duplicateFinderTest.isDuplicate(newFile).then(isDuplicate => {
assertFalse(isDuplicate);
}),
callback);
}
function testDispositionChecker_ContentDupe(callback) {
export function testDispositionChecker_ContentDupe(callback) {
const filePaths = ['/foo.txt'];
const fileHashes = ['abc123'];
const files = setupHashes(filePaths, fileHashes);
......@@ -125,7 +140,7 @@ function testDispositionChecker_ContentDupe(callback) {
callback);
}
function testDispositionChecker_HistoryDupe(callback) {
export function testDispositionChecker_HistoryDupe(callback) {
const filePaths = ['/foo.txt'];
const fileHashes = ['abc123'];
const files = setupHashes(filePaths, fileHashes);
......@@ -142,7 +157,7 @@ function testDispositionChecker_HistoryDupe(callback) {
callback);
}
function testDispositionChecker_Original(callback) {
export function testDispositionChecker_Original(callback) {
const filePaths = ['/foo.txt'];
const fileHashes = ['abc123'];
const files = setupHashes(filePaths, fileHashes);
......
......@@ -19,7 +19,8 @@ importer.MediaImportHandlerImpl = class {
/**
* @param {!ProgressCenter} progressCenter
* @param {!importerHistoryInterfaces.HistoryLoader} historyLoader
* @param {!importer.DispositionChecker.CheckerFunction} dispositionChecker
* @param {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction}
* dispositionChecker
* @param {!DriveSyncHandler} driveSyncHandler
*/
constructor(
......@@ -44,7 +45,9 @@ importer.MediaImportHandlerImpl = class {
/** @private {number} */
this.nextTaskId_ = 0;
/** @private {!importer.DispositionChecker.CheckerFunction} */
/**
* @private {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction}
*/
this.getDisposition_ = dispositionChecker;
/**
......@@ -208,7 +211,8 @@ importer.MediaImportHandler.ImportTaskImpl =
* @param {!mediaScannerInterfaces.ScanResult} scanResult
* @param {!Promise<!DirectoryEntry>} directoryPromise
* @param {!importer.Destination} destination The logical destination.
* @param {!importer.DispositionChecker.CheckerFunction} dispositionChecker
* @param {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction}
* dispositionChecker
*/
constructor(
taskId, historyLoader, scanResult, directoryPromise, destination,
......@@ -254,7 +258,9 @@ importer.MediaImportHandler.ImportTaskImpl =
/** @private {number} */
this.errorCount_ = 0;
/** @private {!importer.DispositionChecker.CheckerFunction} */
/**
* @private {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction}
*/
this.getDisposition_ = dispositionChecker;
/**
......
......@@ -13,7 +13,7 @@ let mediaImporter;
/** @type {!importerTestHistory.TestImportHistory} */
let importHistory;
/** @type {!importer.DispositionChecker.CheckerFunction} */
/** @type {!duplicateFinderInterfaces.DispositionChecker.CheckerFunction} */
let dispositionChecker;
/** @type {!MockCopyTo} */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment