> ## Content Index
> Fetch the complete content index at: https://www.workroom-productions.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Exploratory Interfaces alongside  unit tests
- URL: https://www.workroom-productions.com/exploratory-interfaces-alongside-unit-tests/
- Published: 2025-10-07T22:26:57.000Z
- Updated: 2025-10-09T13:58:48.000Z
- Description: Looking inside the code to see what it offers, then playing with it.
- Author: James Lyndsay
- Tags: Exercises, #PlayTime

In this, we'll take some example code – something small-enough that it has unit tests rather than integration tests, and see what it gives us to play with . Then we'll play with it.

We'll take [CadenceKeeper](https://exercises.workroomprds.com/timeSince/) as our subject – but we're not going to play with it directly very much.

Instead, we'll play with [code](https://exercises.workroomprds.com/timeSince/Timer%5Fv2.js) : [Unit tests](https://exercises.workroomprds.com/timeSince/jlChecks.html?spec=Timer%20v2) : [config.js](https://exercises.workroomprds.com/timeSince/config.js) : [Exploratory Interface](https://exercises.workroomprds.com/timeSince/timer%5Fexplorer.html)

## Exercise 1: look at the code

*5 mins*

Take a look at the [code](https://exercises.workroomprds.com/timeSince/Timer%5Fv2.js) – identify its public interface (the ways that other code can interact with it – and the information that other code needs to provide and can expect). Have a swift look at [config.js](https://exercises.workroomprds.com/timeSince/config.js) to see its programatic context and at [CadenceKeeper](https://exercises.workroomprds.com/timeSince/) to see how it's used.

#### using an LLM to do some work

I asked Claude Haiku 3 `Tell me about the public methods that this exposes`, and it replied...

The `Timer_v2` class exposes the following public methods:

1. ****constructor(name, startTime, uniqueId, interval)**: This is the constructor method that initializes a new `Timer_v2` instance. It takes the following parameters:
2. - `name`: A string representing the name of the timer.
  - `startTime`: An optional `Date` object representing the start time of the timer (defaults to the current time).
  - `uniqueId`: An optional unique identifier for the timer (defaults to the current timestamp).
  - `interval`: An optional interval value from the `UPDATE_INTERVAL` object, which determines the update interval for the timer (defaults to `UPDATE_INTERVAL.SECONDS`).
3. ****get elapsedTime()**: This is a getter method that returns the elapsed time in milliseconds since the timer was started.
4. ****setupTick(newInterval)**: This method sets up the timer's tick functionality. It takes an optional `newInterval` parameter to specify a new update interval. If no `newInterval` is provided, it will use the `currentInterval` property.
5. ****setupChangeovers()**: This method sets up the timer's changeovers from seconds to minutes and from minutes to hours.
6. ****stopUpdates()**: This method stops the timer's updates by clearing the interval and timeout IDs.
7. ****static fromObject(obj)**: This is a static method that creates a new `Timer_v2` instance from an object. If the object has an `id` property but no `uniqueId`, the `id` property is used as the `uniqueId`.

These public methods allow you to create, manage, and interact with the `Timer_v2` instances in your application.

## Exercise 2 – have a look at the tests

*5 mins*

Have a look at the [unit tests](https://exercises.workroomprds.com/timeSince/jlChecks.html?spec=Timer%20v2) – is it clear what is being exercised? Not really, but the code of the page might tell you...

#### another LLM shortcut

I asked \`If the following are the unit tests, what public methods might match up with the tests?\`, and got back...

Based on the unit tests provided, the following public methods from the `Timer_v2` class are likely to be covered:

1. ****constructor(name, startTime, uniqueId, interval)**: The constructor is tested in the "Construction" suite, where it checks the creation of timers with default and custom values.
2. ****get elapsedTime()**: The "It should keep track of elapsed time" suite tests the `elapsedTime` getter method, ensuring that it returns the correct elapsed time.
3. ****stopUpdates()**: The "Update Control" suite tests the `stopUpdates()` method, ensuring that it stops the timer's updates by clearing the interval and timeout IDs.
4. ****setupTick(newInterval)**: The "Interval Changes" suite (though currently marked as "xit") tests the behavior of the `setupTick()` method when the timer's age changes, ensuring that the update interval is adjusted accordingly.
5. ****static fromObject(obj)**: The "fromObject" suite tests the static `fromObject()` method, ensuring that it can create a `Timer_v2` instance from a stored object, including handling the legacy `id` property.

Additionally, the "Event Handling" suite tests the timer's response to the `timerReset` event, which likely involves the `setupTick()` and `startTime` properties.

The other public methods, such as `setupChangeovers()`, are not explicitly tested in the provided unit tests, but they may be covered implicitly or in other test suites not shown here.

## Exercise 3 – explore the unit

*10 minutes*

I had an irritating problem that I saw in [CadenceKeeper](https://exercises.workroomprds.com/timeSince/) and couldn't reproduce with the tests. So I asked for an exploratory interface, and played with the code that way... 

Go play with the [Exploratory Interface](https://exercises.workroomprds.com/timeSince/timer%5Fexplorer.html). Think about how it helps, and how it complements confirmatory unit tests and code analysis.

💡

An **exploratory interface* allows me to explore something. The commandline is certainly an exploratory interface, but this is a custom-built UI, so it's a harness and observatory and lets me trigger actions and iterate over things that might be iterable

#### Using an LLM to build an exploratory interface

Surely it is ridiculous to build a complex UI and then throw it away. It certainly **was* ridiculous. 

Not any more. Here's the prompt that got me close to this interface...  

I want an HTML page, using components in `../components` to let me explore `Timer_v2.js.js`. I want it to have sections containing a mockup UI for

- elements that the code interacts with,
- test UI elements  
\*\* to let me trigger all events that it listens to,  
\*\* to interface (input and output) with all functions that it exposes,  
\*\* to listen to and log any event that it may send  
\*\* to show the internal data and state of the object(s) – including any newly-made objects.

I envisage a set of buttons for listened-to events and input areas if those events need a payload, and a set of collapsible sections for each and every exposed function, with any inputs needed for their payload, and the outputs processed to make them readable.

Where an input has default values, I need an alternate interface to pass in specific values.

Offer drop-downs if an input has a limted choice, and also offer an alternate to allow free entry of any data. If an input takes a range, offer an alterntive with a parametric slider between reasonable limits.

Pay attention to the config file `config.js` , using values from that file – and also put a section containing a list of the values used into the interface, allowing them to be changed.

In terms of look and feel:

- Output **data* should be in a monospaced font.
- Sections should be collapsible and re-orderable by dragging.
- Show the data exposed by the objects and functions in real time, updated every 100ms – and add a pause+countdown button to stop that refresh for 5s to allow copy.
  
## Conclusion...

Let's share and talk as we play.