<commit_before>package io.clappr.player.plugin.control

import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import io.clappr.player.BuildConfig
import io.clappr.player.base.*
import io.clappr.player.components.Container
import io.clappr.player.components.Core
import io.clappr.player.plugin.Loader
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.shadows.ShadowApplication
import kotlin.test.assertTrue
import io.clappr.player.components.Playback
import io.clappr.player.components.PlaybackSupportInterface
import io.clappr.player.shadows.ClapprShadowView
import org.robolectric.internal.ShadowExtractor
import kotlin.test.assertEquals
import kotlin.test.assertFalse

@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [23], shadows = [ClapprShadowView::class])
class SeekbarPluginTest {

    private lateinit var core: Core
    private lateinit var container: Container

    private lateinit var seekbarPlugin: SeekbarPlugin

    @Before
    fun setup() {
        BaseObject.context = ShadowApplication.getInstance().applicationContext

        container = Container(Loader(), Options())
        core = Core(Loader(), Options())
        container.playback = FakePlayback()

        seekbarPlugin = SeekbarPlugin(core)

        core.activeContainer = container
    }

    @Test
    fun shouldSetViewTouchListenerWhenRender() {
        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_UP)
        assertTrue(didTouchSeekbar)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenRenderIsCalledAndPlaybackIsIdle() {
        assertViewVisibilityOnRender(Playback.MediaType.VOD, Playback.State.IDLE, View.GONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenRenderIsCalledAndPlaybackIsNone() {
        assertViewVisibilityOnRender(Playback.MediaType.VOD, Playback.State.NONE, View.GONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenRenderIsCalledAndVideoIsLive() {
        assertViewVisibilityOnRender(Playback.MediaType.LIVE, Playback.State.PLAYING, View.GONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenRenderIsCalledAndVideoIsUnknown() {
        assertViewVisibilityOnRender(Playback.MediaType.UNKNOWN, Playback.State.PLAYING, View.GONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToVisibleWhenRenderIsCalledAndVideoIsVOD() {
        seekbarPlugin.view.visibility = View.GONE
        assertViewVisibilityOnRender(Playback.MediaType.VOD, Playback.State.PLAYING, View.VISIBLE)
    }

    @Test
    fun shouldTriggerDidUpdateInteractingEventWhenTouchDownEventHappens() {
        var didUpdateInteractingCalled = false

        core.listenTo(core, InternalEvent.DID_UPDATE_INTERACTING.value,
                Callback.wrap { didUpdateInteractingCalled = true })

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_DOWN)

        assertTrue(didTouchSeekbar)
        assertTrue(didUpdateInteractingCalled)
    }

    @Test
    fun shouldStartDragWhenTouchActionDownHappens() {
        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_DOWN)

        assertTrue(didTouchSeekbar)
        assertTrue(seekbarPlugin.dragging)
    }

    @Test
    fun shouldStartDragWhenTouchActionMoveHappens() {
        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_MOVE)

        assertTrue(didTouchSeekbar)
        assertTrue(seekbarPlugin.dragging)
    }

    @Test
    fun shouldStopDragWhenTouchActionUpHappens() {
        seekbarPlugin.dragging = true

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_UP)

        assertTrue(didTouchSeekbar)
        assertFalse(seekbarPlugin.dragging)
    }

    @Test
    fun shouldStopDragWhenTouchActionCancelHappens() {
        seekbarPlugin.dragging = true

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_CANCEL)

        assertTrue(didTouchSeekbar)
        assertFalse(seekbarPlugin.dragging)
    }

    @Test
    fun shouldHideSeekbarWhenDidCompleteEventHappens() {
        assertEquals(View.VISIBLE, seekbarPlugin.view.visibility)

        core.activePlayback?.trigger(Event.DID_COMPLETE.value)

        assertEquals(View.GONE, seekbarPlugin.view.visibility)
    }

    @Test
    fun shouldUpdatePositionBarViewAndScrubberViewWhenTouchActionDownHappens() {
        val expectedPositionBarWidth = 50
        val expectedScrubberViewX = 46.0f

        setupViewWidth(500, 8)

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_DOWN, 50F)

        assertTrue(didTouchSeekbar)
        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    @Test
    fun shouldUpdatePositionBarViewAndScrubberViewWhenTouchActionMoveHappens() {
        val expectedPositionBarWidth = 100
        val expectedScrubberViewX = 96.0f

        setupViewWidth(500, 8)

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_MOVE, 100F)

        assertTrue(didTouchSeekbar)
        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenUserTouchSeekbarAndPlaybackIsIdle() {
        assertViewVisibilityWhenTouchEventHappens(View.GONE, Playback.MediaType.VOD, Playback.State.IDLE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenUserTouchSeekbarAndPlaybackIsNone() {
        assertViewVisibilityWhenTouchEventHappens(View.GONE, Playback.MediaType.VOD, Playback.State.NONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenUserTouchSeekbarAndVideoIsLive() {
        assertViewVisibilityWhenTouchEventHappens(View.GONE, Playback.MediaType.LIVE, Playback.State.PLAYING)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenUserTouchSeekbarAndVideoIsUnknown() {
        assertViewVisibilityWhenTouchEventHappens(View.GONE, Playback.MediaType.UNKNOWN, Playback.State.PLAYING)
    }

    @Test
    fun shouldUpdateViewVisibilityToVisibleWhenUserTouchSeekbarAndVideoIsVOD() {
        assertViewVisibilityWhenTouchEventHappens(View.VISIBLE, Playback.MediaType.VOD, Playback.State.PLAYING, View.GONE)
    }

    @Test
    fun shouldRemoveTouchListenerWhenViewIsDestroyed() {
        val motionEvent = MotionEvent.obtain(
                0, 0, MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0)

        seekbarPlugin.render()
        assertTrue(seekbarPlugin.view.dispatchTouchEvent(motionEvent))

        seekbarPlugin.destroy()
        assertFalse(seekbarPlugin.view.dispatchTouchEvent(motionEvent))
    }

    @Test
    fun shouldUpdateBufferedBarWhenEventHappens() {
        val expectedBufferedBarWidth = 250
        val expectedPercentage = 50.0
        val bundle = Bundle().apply { putDouble("percentage", expectedPercentage) }

        setupViewWidth(500, 8)

        core.activePlayback?.trigger(Event.BUFFER_UPDATE.value, bundle)

        assertEquals(expectedBufferedBarWidth, seekbarPlugin.bufferedBar.layoutParams.width)
    }

    @Test
    fun shouldUpdateBufferedBarWithoutBundleWhenEventHappens() {
        val expectedBufferedBarWidth = 0

        setupViewWidth(500, 8)
        seekbarPlugin.bufferedBar.layoutParams.apply { width = 100 }

        core.activePlayback?.trigger(Event.BUFFER_UPDATE.value)

        assertEquals(expectedBufferedBarWidth, seekbarPlugin.bufferedBar.layoutParams.width)
    }

    @Test
    fun shouldSeekWhenStopDrag() {
        val expectedSeekTime = 60

        setupViewWidth(500, 8)
        setupFakePlayback(duration = 120.0, position = 10.0)

        performTouchActionOnSeekbar(MotionEvent.ACTION_UP, 250.0f)

        assertEquals(expectedSeekTime, (container.playback as FakePlayback).seekTime)
    }

    @Test
    fun shouldNotSeekWhenUserStopDragInTheOldPosition() {
        val expectedSeekTime = 0

        setupViewWidth(500, 8)
        setupFakePlayback(duration = 120.0, position = 60.0)

        performTouchActionOnSeekbar(MotionEvent.ACTION_UP, 250.0f)

        assertEquals(expectedSeekTime, (container.playback as FakePlayback).seekTime)
    }

    @Test
    fun shouldUpdateViewsWhenUpdatePositionEventHappens() {
        val expectedPositionBarWidth = 250
        val expectedScrubberViewX = 246.0f

        val expectedPercentage = 50.0
        val bundle = Bundle().apply { putDouble("percentage", expectedPercentage) }

        setupViewWidth(500, 8)

        core.activePlayback?.trigger(Event.POSITION_UPDATE.value, bundle)

        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    @Test
    fun shouldUpdateViewsWithoutBundleWhenUpdatePositionEventHappens() {
        val expectedPositionBarWidth = 0
        val expectedScrubberViewX = 0f

        setupViewWidth(500, 8)

        seekbarPlugin.positionBar.layoutParams.width = 100
        seekbarPlugin.scrubberView.x = 100f

        core.activePlayback?.trigger(Event.POSITION_UPDATE.value)

        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    @Test
    fun shouldNotUpdateViewsWhenUpdatePositionEventHappensButUserIsDragging() {
        val expectedPositionBarWidth = 0
        val expectedScrubberViewX = 0f

        val expectedPercentage = 50.0
        val bundle = Bundle().apply { putDouble("percentage", expectedPercentage) }

        setupViewWidth(500, 8)

        seekbarPlugin.dragging = true
        core.activePlayback?.trigger(Event.POSITION_UPDATE.value, bundle)

        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    private fun assertViewVisibilityWhenTouchEventHappens(expectedViewVisibility: Int,
                                                          mediaType: Playback.MediaType,
                                                          playbackState: Playback.State,
                                                          currentViewVisibility : Int = View.VISIBLE) {
        val motionEvent = MotionEvent.obtain(
                0, 0, MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0)

        seekbarPlugin.render()
        seekbarPlugin.view.visibility = currentViewVisibility<commit_msg>test(init_destroy_plugin): add tests to check playback listeners events<commit_after>package io.clappr.player.plugin.control

import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import io.clappr.player.BuildConfig
import io.clappr.player.base.*
import io.clappr.player.components.Container
import io.clappr.player.components.Core
import io.clappr.player.plugin.Loader
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.shadows.ShadowApplication
import kotlin.test.assertTrue
import io.clappr.player.components.Playback
import io.clappr.player.components.PlaybackSupportInterface
import io.clappr.player.shadows.ClapprShadowView
import org.robolectric.internal.ShadowExtractor
import kotlin.test.assertEquals
import kotlin.test.assertFalse

@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [23], shadows = [ClapprShadowView::class])
class SeekbarPluginTest {

    private lateinit var core: Core
    private lateinit var container: Container

    private lateinit var seekbarPlugin: SeekbarPlugin

    @Before
    fun setup() {
        BaseObject.context = ShadowApplication.getInstance().applicationContext

        container = Container(Loader(), Options())
        core = Core(Loader(), Options())

        seekbarPlugin = SeekbarPlugin(core)

        core.activeContainer = container

        container.playback = FakePlayback()
    }

    @Test
    fun shouldSetViewTouchListenerWhenRender() {
        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_UP)
        assertTrue(didTouchSeekbar)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenRenderIsCalledAndPlaybackIsIdle() {
        assertViewVisibilityOnRender(Playback.MediaType.VOD, Playback.State.IDLE, View.GONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenRenderIsCalledAndPlaybackIsNone() {
        assertViewVisibilityOnRender(Playback.MediaType.VOD, Playback.State.NONE, View.GONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenRenderIsCalledAndVideoIsLive() {
        assertViewVisibilityOnRender(Playback.MediaType.LIVE, Playback.State.PLAYING, View.GONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenRenderIsCalledAndVideoIsUnknown() {
        assertViewVisibilityOnRender(Playback.MediaType.UNKNOWN, Playback.State.PLAYING, View.GONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToVisibleWhenRenderIsCalledAndVideoIsVOD() {
        seekbarPlugin.view.visibility = View.GONE
        assertViewVisibilityOnRender(Playback.MediaType.VOD, Playback.State.PLAYING, View.VISIBLE)
    }

    @Test
    fun shouldTriggerDidUpdateInteractingEventWhenTouchDownEventHappens() {
        var didUpdateInteractingCalled = false

        core.listenTo(core, InternalEvent.DID_UPDATE_INTERACTING.value,
                Callback.wrap { didUpdateInteractingCalled = true })

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_DOWN)

        assertTrue(didTouchSeekbar)
        assertTrue(didUpdateInteractingCalled)
    }

    @Test
    fun shouldStartDragWhenTouchActionDownHappens() {
        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_DOWN)

        assertTrue(didTouchSeekbar)
        assertTrue(seekbarPlugin.dragging)
    }

    @Test
    fun shouldStartDragWhenTouchActionMoveHappens() {
        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_MOVE)

        assertTrue(didTouchSeekbar)
        assertTrue(seekbarPlugin.dragging)
    }

    @Test
    fun shouldStopDragWhenTouchActionUpHappens() {
        seekbarPlugin.dragging = true

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_UP)

        assertTrue(didTouchSeekbar)
        assertFalse(seekbarPlugin.dragging)
    }

    @Test
    fun shouldStopDragWhenTouchActionCancelHappens() {
        seekbarPlugin.dragging = true

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_CANCEL)

        assertTrue(didTouchSeekbar)
        assertFalse(seekbarPlugin.dragging)
    }

    @Test
    fun shouldHideSeekbarWhenDidCompleteEventHappens() {
        assertEquals(View.VISIBLE, seekbarPlugin.view.visibility)

        core.activePlayback?.trigger(Event.DID_COMPLETE.value)

        assertEquals(View.GONE, seekbarPlugin.view.visibility)
    }

    @Test
    fun shouldUpdatePositionBarViewAndScrubberViewWhenTouchActionDownHappens() {
        val expectedPositionBarWidth = 50
        val expectedScrubberViewX = 46.0f

        setupViewWidth(500, 8)

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_DOWN, 50F)

        assertTrue(didTouchSeekbar)
        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    @Test
    fun shouldUpdatePositionBarViewAndScrubberViewWhenTouchActionMoveHappens() {
        val expectedPositionBarWidth = 100
        val expectedScrubberViewX = 96.0f

        setupViewWidth(500, 8)

        val didTouchSeekbar = performTouchActionOnSeekbar(MotionEvent.ACTION_MOVE, 100F)

        assertTrue(didTouchSeekbar)
        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenUserTouchSeekbarAndPlaybackIsIdle() {
        assertViewVisibilityWhenTouchEventHappens(View.GONE, Playback.MediaType.VOD, Playback.State.IDLE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenUserTouchSeekbarAndPlaybackIsNone() {
        assertViewVisibilityWhenTouchEventHappens(View.GONE, Playback.MediaType.VOD, Playback.State.NONE)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenUserTouchSeekbarAndVideoIsLive() {
        assertViewVisibilityWhenTouchEventHappens(View.GONE, Playback.MediaType.LIVE, Playback.State.PLAYING)
    }

    @Test
    fun shouldUpdateViewVisibilityToGoneWhenUserTouchSeekbarAndVideoIsUnknown() {
        assertViewVisibilityWhenTouchEventHappens(View.GONE, Playback.MediaType.UNKNOWN, Playback.State.PLAYING)
    }

    @Test
    fun shouldUpdateViewVisibilityToVisibleWhenUserTouchSeekbarAndVideoIsVOD() {
        assertViewVisibilityWhenTouchEventHappens(View.VISIBLE, Playback.MediaType.VOD, Playback.State.PLAYING, View.GONE)
    }

    @Test
    fun shouldRemoveTouchListenerWhenViewIsDestroyed() {
        val motionEvent = MotionEvent.obtain(
                0, 0, MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0)

        seekbarPlugin.render()
        assertTrue(seekbarPlugin.view.dispatchTouchEvent(motionEvent))

        seekbarPlugin.destroy()
        assertFalse(seekbarPlugin.view.dispatchTouchEvent(motionEvent))
    }

    @Test
    fun shouldUpdateBufferedBarWhenEventHappens() {
        val expectedBufferedBarWidth = 250
        val expectedPercentage = 50.0
        val bundle = Bundle().apply { putDouble("percentage", expectedPercentage) }

        setupViewWidth(500, 8)

        core.activePlayback?.trigger(Event.BUFFER_UPDATE.value, bundle)

        assertEquals(expectedBufferedBarWidth, seekbarPlugin.bufferedBar.layoutParams.width)
    }

    @Test
    fun shouldUpdateBufferedBarWithoutBundleWhenEventHappens() {
        val expectedBufferedBarWidth = 0

        setupViewWidth(500, 8)
        seekbarPlugin.bufferedBar.layoutParams.apply { width = 100 }

        core.activePlayback?.trigger(Event.BUFFER_UPDATE.value)

        assertEquals(expectedBufferedBarWidth, seekbarPlugin.bufferedBar.layoutParams.width)
    }

    @Test
    fun shouldSeekWhenStopDrag() {
        val expectedSeekTime = 60

        setupViewWidth(500, 8)
        setupFakePlayback(duration = 120.0, position = 10.0)

        performTouchActionOnSeekbar(MotionEvent.ACTION_UP, 250.0f)

        assertEquals(expectedSeekTime, (container.playback as FakePlayback).seekTime)
    }

    @Test
    fun shouldNotSeekWhenUserStopDragInTheOldPosition() {
        val expectedSeekTime = 0

        setupViewWidth(500, 8)
        setupFakePlayback(duration = 120.0, position = 60.0)

        performTouchActionOnSeekbar(MotionEvent.ACTION_UP, 250.0f)

        assertEquals(expectedSeekTime, (container.playback as FakePlayback).seekTime)
    }

    @Test
    fun shouldUpdateViewsWhenUpdatePositionEventHappens() {
        val expectedPositionBarWidth = 250
        val expectedScrubberViewX = 246.0f

        val expectedPercentage = 50.0
        val bundle = Bundle().apply { putDouble("percentage", expectedPercentage) }

        setupViewWidth(500, 8)

        core.activePlayback?.trigger(Event.POSITION_UPDATE.value, bundle)

        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    @Test
    fun shouldUpdateViewsWithoutBundleWhenUpdatePositionEventHappens() {
        val expectedPositionBarWidth = 0
        val expectedScrubberViewX = 0f

        setupViewWidth(500, 8)

        seekbarPlugin.positionBar.layoutParams.width = 100
        seekbarPlugin.scrubberView.x = 100f

        core.activePlayback?.trigger(Event.POSITION_UPDATE.value)

        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    @Test
    fun shouldNotUpdateViewsWhenUpdatePositionEventHappensButUserIsDragging() {
        val expectedPositionBarWidth = 0
        val expectedScrubberViewX = 0f

        val expectedPercentage = 50.0
        val bundle = Bundle().apply { putDouble("percentage", expectedPercentage) }

        setupViewWidth(500, 8)

        seekbarPlugin.dragging = true
        core.activePlayback?.trigger(Event.POSITION_UPDATE.value, bundle)

        assertEquals(expectedPositionBarWidth, seekbarPlugin.positionBar.layoutParams.width)
        assertEquals(expectedScrubberViewX, seekbarPlugin.scrubberView.x)
    }

    @Test
    fun shouldHaveListenersWhenInit() {
        assertTrue(seekbarPlugin.playbackListenerIds.size > 0, "Seekbar should have playback listeners initialized")
    }

    @Test
    fun shouldRemoveAllListenersOnDestroy() {
        seekbarPlugin.destroy()
        assertTrue(seekbarPlugin.playbackListenerIds.size == 0, "Seekbar should have playback listeners initialized")
    }

    @Test
    fun shouldSetupPlaybackListenersWhenDidChangePlaybackEventIsCalled() {
        seekbarPlugin.playbackListenerIds.clear()
        core.trigger(InternalEvent.DID_CHANGE_ACTIVE_PLAYBACK.value)
        assertTrue(seekbarPlugin.playbackListenerIds.size > 0)
    }

    private fun assertViewVisibilityWhenTouchEventHappens(expectedViewVisibility: Int,
                                                          mediaType: Playback.MediaType,
                                                          playbackState: Playback.State,
                                                          currentViewVisibility : Int = View.VISIBLE) {
        val motionEvent = MotionEvent.obtain(
                0, 0, MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0)

        seekbarPlugin.render()
        seekbarPlugin.view.visibility = currentViewVisibility
{'fraction_non_alphanumeric': 0.07162309368191722, 'fraction_numerical': 0.011574074074074073, 'mean_word_length': 3.570213648620618, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1091237', 'n_tokens_mistral': 6568, 'n_tokens_neox': 6180, 'n_words': 908}