Skip to content

Commit

Permalink
Accept builder in constructor of ChuckerInterceptor
Browse files Browse the repository at this point in the history
This type of builder will ensure that library is binary compatible even if we add more default fields.
  • Loading branch information
MiSikora committed Oct 24, 2020
1 parent 5e7d733 commit 6d4a8b4
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 95 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Expand Up @@ -19,9 +19,9 @@ Please add your entries according to this format.
* Fixed memory leak in MainActivity [#465].
* Fixed build failure for projects with new `kotlin-parcelize` plugin [#480].

### Deprecated
### Removed

* `ChuckerInterceptor` constructor is now deprecated. Unless `Context` is the only parameter that you pass into the constructor you should migrate to builder.
* Removed parametrized `ChuckerInterceptor` constructor in favour of builder pattern. Constructor that accepts only `Context` is still available.

## Version 3.3.0 *(2020-09-30)*

Expand Down
Expand Up @@ -9,14 +9,15 @@ import kotlin.jvm.Throws
/**
* No-op implementation.
*/
public class ChuckerInterceptor @JvmOverloads constructor(
context: Context,
collector: Any? = null,
maxContentLength: Any? = null,
headersToRedact: Any? = null,
alwaysReadResponseBody: Any? = null,
public class ChuckerInterceptor private constructor(
builder: Builder,
) : Interceptor {

/**
* No-op implementation.
*/
public constructor(context: Context) : this(Builder(context))

public fun redactHeaders(vararg names: String): ChuckerInterceptor {
return this
}
Expand All @@ -41,6 +42,6 @@ public class ChuckerInterceptor @JvmOverloads constructor(

public fun alwaysReadResponseBody(enable: Boolean): Builder = this

public fun build(): ChuckerInterceptor = ChuckerInterceptor(context)
public fun build(): ChuckerInterceptor = ChuckerInterceptor(this)
}
}
Expand Up @@ -28,73 +28,29 @@ import kotlin.jvm.Throws
/**
* An OkHttp Interceptor which persists and displays HTTP activity
* in your application for later inspection.
*
* @param context An Android [Context]
* @param collector A [ChuckerCollector] to customize data retention
* @param maxContentLength The maximum length for request and response content
* before their truncation. Warning: setting this value too high may cause unexpected
* results.
* @param cacheDirectoryProvider Provider of [File] where Chucker will save temporary responses
* before processing them.
* @param alwaysReadResponseBody If set to `true` Chucker will read full content of response
* bodies even in case of parsing errors or closing the response body without reading it.
* @param headersToRedact a [Set] of headers you want to redact. They will be replaced
* with a `**` in the Chucker UI.
*/
public class ChuckerInterceptor internal constructor(
private val context: Context,
private val collector: ChuckerCollector = ChuckerCollector(context),
private val maxContentLength: Long = 250000L,
private val cacheDirectoryProvider: CacheDirectoryProvider,
private val alwaysReadResponseBody: Boolean = false,
headersToRedact: Set<String> = emptySet(),
public class ChuckerInterceptor private constructor(
builder: Builder,
) : Interceptor {

/**
* An OkHttp Interceptor which persists and displays HTTP activity
* in your application for later inspection.
*
* This constructor is a shorthand for `ChuckerInterceptor.Builder(context).build()`.
*
* @param context An Android [Context]
* @param collector A [ChuckerCollector] to customize data retention
* @param maxContentLength The maximum length for request and response content
* before their truncation. Warning: setting this value too high may cause unexpected
* results.
* @param alwaysReadResponseBody If set to `true` Chucker will read full content of response
* bodies even in case of parsing errors or closing the response body without reading it.
* @param headersToRedact a [Set] of headers you want to redact. They will be replaced
* with a `**` in the Chucker UI.
* @see ChuckerInterceptor.Builder
*/
@JvmOverloads
@Deprecated(
message = "" +
"Customisation of ChuckerInterceptor should be replaced with a builder pattern " +
"unless you pass only Context.",
replaceWith = ReplaceWith(
"ChuckerInterceptor.Builder(context)\n" +
".collector(collector)\n" +
".maxContentLength(maxContentLength)\n" +
".redactHeaders(headersToRedact)\n" +
".alwaysReadResponseBody(alwaysReadResponseBody)\n" +
".build()"
)
)
public constructor(
context: Context,
collector: ChuckerCollector = ChuckerCollector(context),
maxContentLength: Long = 250000L,
headersToRedact: Set<String> = emptySet(),
alwaysReadResponseBody: Boolean = false,
) : this(
context = context,
collector = collector,
maxContentLength = maxContentLength,
cacheDirectoryProvider = { context.cacheDir },
alwaysReadResponseBody = alwaysReadResponseBody,
headersToRedact = headersToRedact,
)

private val io: IOUtils = IOUtils(context)
private val headersToRedact: MutableSet<String> = headersToRedact.toMutableSet()
public constructor(context: Context) : this(Builder(context))

private val context = builder.context
private val collector = builder.collector ?: ChuckerCollector(context)
private val maxContentLength = builder.maxContentLength
private val cacheDirectoryProvider = builder.cacheDirectoryProvider ?: CacheDirectoryProvider { context.filesDir }
private val alwaysReadResponseBody = builder.alwaysReadResponseBody
private val io = IOUtils(builder.context)
private val headersToRedact = builder.headersToRedact.toMutableSet()

/** Adds [headerName] into [headersToRedact] */
public fun redactHeader(vararg headerName: String) {
Expand Down Expand Up @@ -308,12 +264,12 @@ public class ChuckerInterceptor internal constructor(
*
* @param context An Android [Context].
*/
public class Builder(private var context: Context) {
private var collector: ChuckerCollector? = null
private var maxContentLength = MAX_CONTENT_LENGTH
private var cacheDirectoryProvider: CacheDirectoryProvider? = null
private var alwaysReadResponseBody = false
private var headersToRedact = emptySet<String>()
public class Builder(internal var context: Context) {
internal var collector: ChuckerCollector? = null
internal var maxContentLength = MAX_CONTENT_LENGTH
internal var cacheDirectoryProvider: CacheDirectoryProvider? = null
internal var alwaysReadResponseBody = false
internal var headersToRedact = emptySet<String>()

/**
* Sets the [ChuckerCollector] to customize data retention.
Expand Down Expand Up @@ -358,17 +314,18 @@ public class ChuckerInterceptor internal constructor(
this.alwaysReadResponseBody = enable
}

/**
* Sets provider of a directory where Chucker will save temporary responses
* before processing them.
*/
internal fun cacheDirectorProvider(provider: CacheDirectoryProvider): Builder = apply {

This comment has been minimized.

Copy link
@cortinico

cortinico Nov 3, 2020

Member

Can you add a @VisibleForTesting or a note in the KDoc on why this is internal and not public?

this.cacheDirectoryProvider = provider
}

/**
* Creates a new [ChuckerInterceptor] instance with values defined in this builder.
*/
public fun build(): ChuckerInterceptor = ChuckerInterceptor(
context = context,
collector = collector ?: ChuckerCollector(context),
maxContentLength = maxContentLength,
cacheDirectoryProvider = cacheDirectoryProvider ?: CacheDirectoryProvider { context.filesDir },
alwaysReadResponseBody = alwaysReadResponseBody,
headersToRedact = headersToRedact,
)
public fun build(): ChuckerInterceptor = ChuckerInterceptor(this)
}

private companion object {
Expand Down
Expand Up @@ -33,14 +33,13 @@ internal class ChuckerInterceptorDelegate(
}
}

private val chucker = ChuckerInterceptor(
context = mockContext,
collector = mockCollector,
maxContentLength = maxContentLength,
headersToRedact = headersToRedact,
cacheDirectoryProvider = cacheDirectoryProvider,
alwaysReadResponseBody = alwaysReadResponseBody,
)
private val chucker = ChuckerInterceptor.Builder(context = mockContext)
.collector(mockCollector)
.maxContentLength(maxContentLength)
.redactHeaders(headersToRedact)
.alwaysReadResponseBody(alwaysReadResponseBody)
.cacheDirectorProvider(cacheDirectoryProvider)
.build()

internal fun expectTransaction(): HttpTransaction {
if (transactions.isEmpty()) {
Expand Down
Expand Up @@ -31,12 +31,11 @@ class HttpBinClient(
retentionPeriod = RetentionManager.Period.ONE_HOUR
)

private val chuckerInterceptor = ChuckerInterceptor(
context = context,
collector = collector,
maxContentLength = 250000L,
headersToRedact = emptySet<String>()
)
private val chuckerInterceptor = ChuckerInterceptor.Builder(context)
.collector(collector)
.maxContentLength(250000L)
.redactHeaders(emptySet())
.build()

private val httpClient =
OkHttpClient.Builder()
Expand Down

0 comments on commit 6d4a8b4

Please sign in to comment.