onButtonClicked() {
return RxView.clicks(mButton);
diff --git a/settings.gradle b/settings.gradle
index 8588ceb2..f0bb3c73 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1,2 @@
-include ':thirtyinch', ':plugin', ':sample', ':rx', ':test', ':plugin-test', ':rx2'
+include ':thirtyinch', ':plugin', ':sample', ':rx', ':test', ':plugin-test', ':rx2',
+ ':logginginterceptor'
diff --git a/thirtyinch/src/main/java/net/grandcentrix/thirtyinch/TiLog.java b/thirtyinch/src/main/java/net/grandcentrix/thirtyinch/TiLog.java
index 1dbf9c89..702ed911 100644
--- a/thirtyinch/src/main/java/net/grandcentrix/thirtyinch/TiLog.java
+++ b/thirtyinch/src/main/java/net/grandcentrix/thirtyinch/TiLog.java
@@ -54,8 +54,28 @@ public void log(final int level, final String tag, final String msg) {
}
};
+ /**
+ * no-op version, doesn't log
+ */
+ public static Logger NOOP = new Logger() {
+ @Override
+ public void log(final int level, final String tag, final String msg) {
+ // no-op
+ }
+ };
+
private static Logger logger;
+ /**
+ * forward log to {@link TiLog} for logging
+ */
+ public static Logger TI_LOG = new Logger() {
+ @Override
+ public void log(final int level, final String tag, final String msg) {
+ TiLog.log(level, tag, msg);
+ }
+ };
+
public static void d(final String tag, final String msg) {
if (logger != null) {
logger.log(Log.DEBUG, tag, msg);
@@ -74,6 +94,12 @@ public static void i(final String tag, final String msg) {
}
}
+ public static void log(final int level, final String tag, final String msg) {
+ if (logger != null) {
+ logger.log(level, tag, msg);
+ }
+ }
+
/**
* set a custom logger, {@code null} to disable logging
*
@@ -99,6 +125,10 @@ public static void i(final String tag, final String msg) {
*
*/
public static void setLogger(@Nullable final Logger logger) {
+ if (logger == TI_LOG) {
+ throw new IllegalArgumentException(
+ "Recursion warning: You can't use TI_LOG as Logger for TiLog");
+ }
TiLog.logger = logger;
}
diff --git a/thirtyinch/src/test/java/net/grandcentrix/thirtyinch/TiLogTest.java b/thirtyinch/src/test/java/net/grandcentrix/thirtyinch/TiLogTest.java
new file mode 100644
index 00000000..db4cb514
--- /dev/null
+++ b/thirtyinch/src/test/java/net/grandcentrix/thirtyinch/TiLogTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 grandcentrix GmbH
+ * 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.
+ */
+
+package net.grandcentrix.thirtyinch;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import android.util.Log;
+
+import static junit.framework.Assert.fail;
+import static org.assertj.core.api.Java6Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class TiLogTest {
+
+ @Test
+ public void dontCrashForNullLogger() throws Exception {
+ TiLog.setLogger(null);
+ TiLog.v("tag", "msg");
+ TiLog.i("tag", "msg");
+ TiLog.d("tag", "msg");
+ TiLog.e("tag", "msg");
+ TiLog.w("tag", "msg");
+ TiLog.log(Log.VERBOSE, "tag", "msg");
+ }
+
+ @Test
+ public void logDToLogger() throws Exception {
+ final TiLog.Logger logger = mock(TiLog.Logger.class);
+ TiLog.setLogger(logger);
+ final ArgumentCaptor levelCaptor = ArgumentCaptor.forClass(Integer.class);
+ final ArgumentCaptor tagCaptor = ArgumentCaptor.forClass(String.class);
+ final ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(String.class);
+
+ TiLog.d("tag", "msg");
+ verify(logger).log(levelCaptor.capture(), tagCaptor.capture(), msgCaptor.capture());
+
+ assertThat(levelCaptor.getValue()).isEqualTo(Log.DEBUG);
+ assertThat(tagCaptor.getValue()).isEqualTo("tag");
+ assertThat(msgCaptor.getValue()).isEqualTo("msg");
+ }
+
+ @Test
+ public void logEToLogger() throws Exception {
+ final TiLog.Logger logger = mock(TiLog.Logger.class);
+ TiLog.setLogger(logger);
+ final ArgumentCaptor levelCaptor = ArgumentCaptor.forClass(Integer.class);
+ final ArgumentCaptor tagCaptor = ArgumentCaptor.forClass(String.class);
+ final ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(String.class);
+
+ TiLog.e("tag", "msg");
+ verify(logger).log(levelCaptor.capture(), tagCaptor.capture(), msgCaptor.capture());
+
+ assertThat(levelCaptor.getValue()).isEqualTo(Log.ERROR);
+ assertThat(tagCaptor.getValue()).isEqualTo("tag");
+ assertThat(msgCaptor.getValue()).isEqualTo("msg");
+ }
+
+ @Test
+ public void logIToLogger() throws Exception {
+ final TiLog.Logger logger = mock(TiLog.Logger.class);
+ TiLog.setLogger(logger);
+ final ArgumentCaptor levelCaptor = ArgumentCaptor.forClass(Integer.class);
+ final ArgumentCaptor tagCaptor = ArgumentCaptor.forClass(String.class);
+ final ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(String.class);
+
+ TiLog.i("tag", "msg");
+ verify(logger).log(levelCaptor.capture(), tagCaptor.capture(), msgCaptor.capture());
+
+ assertThat(levelCaptor.getValue()).isEqualTo(Log.INFO);
+ assertThat(tagCaptor.getValue()).isEqualTo("tag");
+ assertThat(msgCaptor.getValue()).isEqualTo("msg");
+ }
+
+ @Test
+ public void logVToLogger() throws Exception {
+ final TiLog.Logger logger = mock(TiLog.Logger.class);
+ TiLog.setLogger(logger);
+ final ArgumentCaptor levelCaptor = ArgumentCaptor.forClass(Integer.class);
+ final ArgumentCaptor tagCaptor = ArgumentCaptor.forClass(String.class);
+ final ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(String.class);
+
+ TiLog.v("tag", "msg");
+ verify(logger).log(levelCaptor.capture(), tagCaptor.capture(), msgCaptor.capture());
+
+ assertThat(levelCaptor.getValue()).isEqualTo(Log.VERBOSE);
+ assertThat(tagCaptor.getValue()).isEqualTo("tag");
+ assertThat(msgCaptor.getValue()).isEqualTo("msg");
+ }
+
+ @Test
+ public void logWToLogger() throws Exception {
+ final TiLog.Logger logger = mock(TiLog.Logger.class);
+ TiLog.setLogger(logger);
+ final ArgumentCaptor levelCaptor = ArgumentCaptor.forClass(Integer.class);
+ final ArgumentCaptor tagCaptor = ArgumentCaptor.forClass(String.class);
+ final ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(String.class);
+
+ TiLog.w("tag", "msg");
+ verify(logger).log(levelCaptor.capture(), tagCaptor.capture(), msgCaptor.capture());
+
+ assertThat(levelCaptor.getValue()).isEqualTo(Log.WARN);
+ assertThat(tagCaptor.getValue()).isEqualTo("tag");
+ assertThat(msgCaptor.getValue()).isEqualTo("msg");
+ }
+
+ @Test
+ public void loglogDToLogger() throws Exception {
+ final TiLog.Logger logger = mock(TiLog.Logger.class);
+ TiLog.setLogger(logger);
+ final ArgumentCaptor levelCaptor = ArgumentCaptor.forClass(Integer.class);
+ final ArgumentCaptor tagCaptor = ArgumentCaptor.forClass(String.class);
+ final ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(String.class);
+
+ TiLog.log(Log.DEBUG, "tag", "msg");
+ verify(logger).log(levelCaptor.capture(), tagCaptor.capture(), msgCaptor.capture());
+
+ assertThat(levelCaptor.getValue()).isEqualTo(Log.DEBUG);
+ assertThat(tagCaptor.getValue()).isEqualTo("tag");
+ assertThat(msgCaptor.getValue()).isEqualTo("msg");
+ }
+
+ @Test
+ public void loglogVToLogger() throws Exception {
+ final TiLog.Logger logger = mock(TiLog.Logger.class);
+ TiLog.setLogger(logger);
+ final ArgumentCaptor levelCaptor = ArgumentCaptor.forClass(Integer.class);
+ final ArgumentCaptor tagCaptor = ArgumentCaptor.forClass(String.class);
+ final ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(String.class);
+
+ TiLog.log(Log.VERBOSE, "tag", "msg");
+ verify(logger).log(levelCaptor.capture(), tagCaptor.capture(), msgCaptor.capture());
+
+ assertThat(levelCaptor.getValue()).isEqualTo(Log.VERBOSE);
+ assertThat(tagCaptor.getValue()).isEqualTo("tag");
+ assertThat(msgCaptor.getValue()).isEqualTo("msg");
+ }
+
+ @Test
+ public void preventSettingRecursiveLogger() throws Exception {
+ try {
+ TiLog.setLogger(TiLog.TI_LOG);
+ fail("did not throw");
+ } catch (Exception e) {
+ assertThat(e).hasMessageContaining("Recursion");
+ }
+ }
+}
\ No newline at end of file