-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Test CreateFolderOperation without server #3624
base: master
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3624 +/- ##
============================================
- Coverage 18.71% 6.04% -12.67%
+ Complexity 3 1 -2
============================================
Files 392 315 -77
Lines 34273 30780 -3493
Branches 5011 4419 -592
============================================
- Hits 6414 1862 -4552
- Misses 26863 28640 +1777
+ Partials 996 278 -718
|
Looks good code-wise on an cellphone. |
Right, like with FileDataStorageManagerInterface, we could have Log_OCInterface… |
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.
Injecting Logger as a dependency is an elegant solution, but at a cost of convenience and there is apparently no appetite for this.
That is understandable - printf() is so nice to use.
Given the constraints, I'd extract logger implementation into a class (LogFileWriter
, LogNullWriter
, LogArrayWriter
, etc, etc), and delegate all calls in Log_OC to specific runtime version.
You can swap runtime version with a static setter at any time, let's say in test harness setup.
Pseudocode. I skipped thread safety for the sake of illustration. Also, pls note that you can either inject a specific logger instance to anything and/or use a static, convenient Log_OC
interface.
interface LoggerInterface {
void d(...)
etc, etc
}
class FileLogger implements LoggerInterface {
// move existing file-based logger logic from Log_OC here
}
class NullLogger implements LoggerInterface {
// do nothing :)
}
class MemoryLogger implements LoggerInterface {
// write logs to ListArray
}
/**
* BTW, Does it still need _OC suffix?
*/
public class Log_OC {
private static LoggerInterface sLogger;
/**
* You can probably move this to a separate class, and use package-scope to remove
* init() from public Log_OC API.
*/
public static void init(LoggerInterface logger) {
sLogger = logger;
}
/**
* Another variant is package-scoped. Let's imagine that this API
* is available via some LoggerControl or LoggerManager API that
* is in the same pkg
*/
static void init(LoggerInterface logger) {
sLogger = logger;
}
public static void d(Object object, String message) {
sLogger.d(object, message);
}
...
}
/**
* You can get fancy with that and make yourself
* a nice settings panel to fiddle with logger at runtime.
*/
class LoggerManager {
public static init(LoggerInterface ....);
public static setLogLevel(...);
public static setSomeOtherFancyLogOption(...)
}
@@ -76,6 +76,14 @@ protected RemoteOperationResult run(OwnCloudClient client) { | |||
return result; | |||
} | |||
|
|||
public CreateFolderRemoteOperation createCreateFolderRemoteOperation(String mRemotePath, boolean mCreateFullPath) { |
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.
Those m prefixes are probably a left-overs after either refactoring or automated generation? It can be trimmed with Shift-F6 in no time.
|
||
@Override | ||
public boolean fileExists(long id) { | ||
throw new IllegalArgumentException("to implement"); |
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.
How about UnsupportedOperationException
?
As this seems to be the right way, thanks @ezaquarii, I'll do three PRs:
So this clean and easy to review. |
So @ezaquarii and @tobiasKaminsky I'd like to start the interface naming discussion :D |
Example
|
It's not a bad practice to optimize for most frequent expected use case:
It boils down to choosing between 2 industry wide conventions that happen to work:
Each one of them has some corner aesthetic issues, philosophical foundations, fans and haters. I have my opinion of course, but it's not important as long as:
I believe Android picked And if some day you find yourself on the wrong side of the flame war: |
Well, in that case I vote for variant 2 proposed by @ezaquarii since that should fit the most frequent case (just my opinion, no proof) and as stated would also be the typical Android naming schema pick. |
Is it going to be merged? Still WIP? |
Yes, I just need to find a bit more time… :-) |
76dd4e2
to
41fe0bf
Compare
41fe0bf
to
3a7ce0d
Compare
Unit test failed: https://www.kaminsky.me/nc-dev/android-integrationTests/9180 |
3a7ce0d
to
88626e6
Compare
Unit test failed: https://www.kaminsky.me/nc-dev/android-integrationTests/9575 |
88626e6
to
85b6b2c
Compare
b0f93b6
to
d0ea6ee
Compare
Codacy329Lint
SpotBugs (new)
SpotBugs (master)
SpotBugs increased! |
Signed-off-by: tobiasKaminsky <[email protected]>
Signed-off-by: tobiasKaminsky <[email protected]>
Signed-off-by: tobiasKaminsky <[email protected]>
Signed-off-by: tobiasKaminsky <[email protected]>
Signed-off-by: tobiasKaminsky <[email protected]>
Signed-off-by: tobiasKaminsky <[email protected]>
d0ea6ee
to
fb969cc
Compare
Here is an overview of what got changed by this pull request: Issues
======
+ Solved 27
- Added 11
Complexity increasing per file
==============================
- src/main/java/com/owncloud/android/datamodel/FileDataStorageManagerImpl.java 21
See the complete overview on Codacy |
for (Account account : accountManager.getAccounts()) { | ||
final FileDataStorageManager storageManager = new FileDataStorageManager(account, contentResolver); | ||
final FileDataStorageManager storageManager = new FileDataStorageManagerImpl(account, getContext()); |
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.
Issue found: Avoid instantiating new objects inside loops
public void copyLocalFile(OCFile file, String targetPath) { | ||
|
||
if (file != null && file.fileExists() && !OCFile.ROOT_PATH.equals(file.getFileName())) { | ||
String localPath = FileStorageUtils.getDefaultSavePathFor(account.name, file); |
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.
Issue found: Avoid instantiating new objects inside loops
); | ||
} catch (RemoteException e) { | ||
Log_OC.e(TAG, e.getMessage(), e); | ||
return ret; |
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.
@@ -92,8 +93,7 @@ protected Result onRunJob(@NonNull Params params) { | |||
Account[] accounts = userAccountManager.getAccounts(); | |||
|
|||
for (Account account : accounts) { | |||
FileDataStorageManager storageManager = new FileDataStorageManager(account, | |||
getContext().getContentResolver()); | |||
FileDataStorageManager storageManager = new FileDataStorageManagerImpl(account, getContext()); |
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.
Issue found: Avoid instantiating new objects inside loops
* | ||
* Copyright (C) 2012 Bartek Przybylski | ||
* Copyright (C) 2015 ownCloud Inc. | ||
* |
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.
Issue found: Avoid really long classes.
cv.put( | ||
ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, | ||
file.getModificationTimestampAtLastSyncForData() | ||
); |
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.
Issue found: Avoid instantiating new objects inside loops
ContentValues cv = new ContentValues(); | ||
fileId[0] = String.valueOf(cursor.getLong(cursor.getColumnIndex(ProviderTableMeta._ID))); | ||
String oldFileStoragePath = | ||
cursor.getString(cursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)); |
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.
result_uri = getContentProviderClient().insert(ProviderTableMeta.CONTENT_URI_SHARE, cv); | ||
} catch (RemoteException e) { | ||
Log_OC.e(TAG, FAILED_TO_INSERT_MSG + e.getMessage(), e); | ||
} |
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.
Issue found: Avoid instantiating new objects inside loops
/** | ||
* Retrieves an stored {@link OCShare} given its id. | ||
* | ||
* @param id Identifier. |
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.
Issue found: Avoid instantiating new objects inside loops
|
||
} | ||
if (child.getRemotePath().equals(file.getRemotePath())) { | ||
cv.put(ProviderTableMeta.FILE_PARENT, targetParent.getFileId()); |
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.
Issue found: Avoid instantiating new objects inside loops
} | ||
cursor.close(); | ||
|
||
/// 3. apply updates in batch |
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.
APK file: https://www.kaminsky.me/nc-dev/android-artifacts/12232.apk |
Codacy340Lint
SpotBugs (new)
SpotBugs (master)
SpotBugs increased! |
We have CreateFolderRemoteOperation which is in library and is (or should be) tested there.
Goal of this PR is to test CreateFolderOperation without really using CreateFolderRemoteOperation or any other RemoteOperation, so that this is all Unit Testing.
It is meant to be a start, where we can discuss.
Some consideration:
@ezaquarii maybe you have some input in this.
Signed-off-by: tobiasKaminsky [email protected]