From 7ba738304b4203419f60dc71a7c3ba69148b1df5 Mon Sep 17 00:00:00 2001 From: Ljubisa Stankovic Date: Sun, 19 Jun 2016 11:51:22 +0200 Subject: [PATCH] Remove Android dependency from LoggerPrinter (#76) * Remove Android dependency from LoggerPrinter In order to have Logger in Android unit tests, Logger classes should not depend on Android internals, otherwise exception "Method ... not mocked." will be thrown. For more info: https://goo.gl/Cl0xu3 In this commit, instead of introducing more dependecy from other some 3rd party lib (Appache etc) to do the same task, code is copppied from relevant Android methods to reduce change impact. * Remove support annotation from Helper class. * Fix errors reported by CI * Add private contructor in util class. * Update licence copyright --- .../com/orhanobut/logger/AndroidLogTool.java | 2 +- .../java/com/orhanobut/logger/Helper.java | 103 ++++++++++++++++++ .../com/orhanobut/logger/LoggerPrinter.java | 13 +-- 3 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 logger/src/main/java/com/orhanobut/logger/Helper.java diff --git a/logger/src/main/java/com/orhanobut/logger/AndroidLogTool.java b/logger/src/main/java/com/orhanobut/logger/AndroidLogTool.java index 605a6ed9..3e960b0e 100644 --- a/logger/src/main/java/com/orhanobut/logger/AndroidLogTool.java +++ b/logger/src/main/java/com/orhanobut/logger/AndroidLogTool.java @@ -2,7 +2,7 @@ import android.util.Log; -public class AndroidLogTool implements LogTool { +class AndroidLogTool implements LogTool { @Override public void d(String tag, String message) { Log.d(tag, message); } diff --git a/logger/src/main/java/com/orhanobut/logger/Helper.java b/logger/src/main/java/com/orhanobut/logger/Helper.java new file mode 100644 index 00000000..ed999bef --- /dev/null +++ b/logger/src/main/java/com/orhanobut/logger/Helper.java @@ -0,0 +1,103 @@ +/* + * Copyright 2015 Orhan Obut + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This software contains code derived from the following Android classes: + * android.util.Log, android.text.TextUtils. + */ +package com.orhanobut.logger; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.UnknownHostException; + +/** + * Helper util class to be used instead of Android methods to avoid direct dependency and enable + * unit testing on Android projects. + */ +final class Helper { + + private Helper() { + // Hidden constructor. + } + + /** + * Returns true if the string is null or 0-length. + * + * @param str the string to be examined + * @return true if str is null or zero length + */ + static boolean isEmpty(CharSequence str) { + return str == null || str.length() == 0; + } + + /** + * Returns true if a and b are equal, including if they are both null. + *

Note: In platform versions 1.1 and earlier, this method only worked well if + * both the arguments were instances of String.

+ * + * @param a first CharSequence to check + * @param b second CharSequence to check + * @return true if a and b are equal + * + * NOTE: Logic slightly change due to strict policy on CI - + * "Inner assignments should be avoided" + */ + static boolean equals(CharSequence a, CharSequence b) { + if (a == b) return true; + if (a != null && b != null) { + int length = a.length(); + if (length == b.length()) { + if (a instanceof String && b instanceof String) { + return a.equals(b); + } else { + for (int i = 0; i < length; i++) { + if (a.charAt(i) != b.charAt(i)) return false; + } + return true; + } + } + } + return false; + } + + /** + * Copied from "android.util.Log.getStackTraceString()" in order to avoid usage of Android stack + * in unit tests. + * + * @return Stack trace in form of String + */ + static String getStackTraceString(Throwable tr) { + if (tr == null) { + return ""; + } + + // This is to reduce the amount of log spew that apps do in the non-error + // condition of the network being unavailable. + Throwable t = tr; + while (t != null) { + if (t instanceof UnknownHostException) { + return ""; + } + t = t.getCause(); + } + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + tr.printStackTrace(pw); + pw.flush(); + return sw.toString(); + } + +} diff --git a/logger/src/main/java/com/orhanobut/logger/LoggerPrinter.java b/logger/src/main/java/com/orhanobut/logger/LoggerPrinter.java index b0ec8238..493be396 100644 --- a/logger/src/main/java/com/orhanobut/logger/LoggerPrinter.java +++ b/logger/src/main/java/com/orhanobut/logger/LoggerPrinter.java @@ -1,8 +1,5 @@ package com.orhanobut.logger; -import android.text.TextUtils; -import android.util.Log; - import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -117,7 +114,7 @@ final class LoggerPrinter implements Printer { @Override public void e(Throwable throwable, String message, Object... args) { if (throwable != null && message != null) { - message += " : " + Log.getStackTraceString(throwable); + message += " : " + Helper.getStackTraceString(throwable); } if (throwable != null && message == null) { message = throwable.toString(); @@ -150,7 +147,7 @@ final class LoggerPrinter implements Printer { * @param json the json content */ @Override public void json(String json) { - if (TextUtils.isEmpty(json)) { + if (Helper.isEmpty(json)) { d("Empty/Null json content"); return; } @@ -178,7 +175,7 @@ final class LoggerPrinter implements Printer { * @param xml the xml content */ @Override public void xml(String xml) { - if (TextUtils.isEmpty(xml)) { + if (Helper.isEmpty(xml)) { d("Empty/Null xml content"); return; } @@ -210,7 +207,7 @@ private synchronized void log(int logType, String msg, Object... args) { String message = createMessage(msg, args); int methodCount = getMethodCount(); - if (TextUtils.isEmpty(message)) { + if (Helper.isEmpty(message)) { message = "Empty/NULL log message"; } @@ -327,7 +324,7 @@ private String getSimpleClassName(String name) { } private String formatTag(String tag) { - if (!TextUtils.isEmpty(tag) && !TextUtils.equals(this.tag, tag)) { + if (!Helper.isEmpty(tag) && !Helper.equals(this.tag, tag)) { return this.tag + "-" + tag; } return this.tag;