Skip to content

Commit

Permalink
Assignment logging (#3)
Browse files Browse the repository at this point in the history
* implement assignment logger

* generated docs

* 0.0.2
  • Loading branch information
ploomiz authored Jun 27, 2022
1 parent 02e10af commit 61c20aa
Show file tree
Hide file tree
Showing 17 changed files with 300 additions and 44 deletions.
13 changes: 13 additions & 0 deletions docs/js-client-sdk.iassignmentevent.experiment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IAssignmentEvent](./js-client-sdk.iassignmentevent.md) &gt; [experiment](./js-client-sdk.iassignmentevent.experiment.md)

## IAssignmentEvent.experiment property

An Eppo experiment key

<b>Signature:</b>

```typescript
experiment: string;
```
24 changes: 24 additions & 0 deletions docs/js-client-sdk.iassignmentevent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IAssignmentEvent](./js-client-sdk.iassignmentevent.md)

## IAssignmentEvent interface

Holds data about the variation a subject was assigned to.

<b>Signature:</b>

```typescript
export interface IAssignmentEvent
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [experiment](./js-client-sdk.iassignmentevent.experiment.md) | string | An Eppo experiment key |
| [subject](./js-client-sdk.iassignmentevent.subject.md) | string | The entity or user that was assigned to a variation |
| [subjectAttributes](./js-client-sdk.iassignmentevent.subjectattributes.md) | Record&lt;string, any&gt; | |
| [timestamp](./js-client-sdk.iassignmentevent.timestamp.md) | string | The time the subject was exposed to the variation. |
| [variation](./js-client-sdk.iassignmentevent.variation.md) | string | The assigned variation |

13 changes: 13 additions & 0 deletions docs/js-client-sdk.iassignmentevent.subject.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IAssignmentEvent](./js-client-sdk.iassignmentevent.md) &gt; [subject](./js-client-sdk.iassignmentevent.subject.md)

## IAssignmentEvent.subject property

The entity or user that was assigned to a variation

<b>Signature:</b>

```typescript
subject: string;
```
11 changes: 11 additions & 0 deletions docs/js-client-sdk.iassignmentevent.subjectattributes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IAssignmentEvent](./js-client-sdk.iassignmentevent.md) &gt; [subjectAttributes](./js-client-sdk.iassignmentevent.subjectattributes.md)

## IAssignmentEvent.subjectAttributes property

<b>Signature:</b>

```typescript
subjectAttributes: Record<string, any>;
```
13 changes: 13 additions & 0 deletions docs/js-client-sdk.iassignmentevent.timestamp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IAssignmentEvent](./js-client-sdk.iassignmentevent.md) &gt; [timestamp](./js-client-sdk.iassignmentevent.timestamp.md)

## IAssignmentEvent.timestamp property

The time the subject was exposed to the variation.

<b>Signature:</b>

```typescript
timestamp: string;
```
13 changes: 13 additions & 0 deletions docs/js-client-sdk.iassignmentevent.variation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IAssignmentEvent](./js-client-sdk.iassignmentevent.md) &gt; [variation](./js-client-sdk.iassignmentevent.variation.md)

## IAssignmentEvent.variation property

The assigned variation

<b>Signature:</b>

```typescript
variation: string;
```
24 changes: 24 additions & 0 deletions docs/js-client-sdk.iassignmentlogger.logassignment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IAssignmentLogger](./js-client-sdk.iassignmentlogger.md) &gt; [logAssignment](./js-client-sdk.iassignmentlogger.logassignment.md)

## IAssignmentLogger.logAssignment() method

Invoked when a subject is assigned to an experiment variation.

<b>Signature:</b>

```typescript
logAssignment(assignment: IAssignmentEvent): void;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| assignment | [IAssignmentEvent](./js-client-sdk.iassignmentevent.md) | holds the variation an experiment subject was assigned to |

<b>Returns:</b>

void

20 changes: 20 additions & 0 deletions docs/js-client-sdk.iassignmentlogger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IAssignmentLogger](./js-client-sdk.iassignmentlogger.md)

## IAssignmentLogger interface

Implement this interface log variation assignments to your data warehouse.

<b>Signature:</b>

```typescript
export interface IAssignmentLogger
```

## Methods

| Method | Description |
| --- | --- |
| [logAssignment(assignment)](./js-client-sdk.iassignmentlogger.logassignment.md) | Invoked when a subject is assigned to an experiment variation. |

13 changes: 13 additions & 0 deletions docs/js-client-sdk.iclientconfig.assignmentlogger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@eppo/js-client-sdk](./js-client-sdk.md) &gt; [IClientConfig](./js-client-sdk.iclientconfig.md) &gt; [assignmentLogger](./js-client-sdk.iclientconfig.assignmentlogger.md)

## IClientConfig.assignmentLogger property

Pass a logging implementation to send variation assignments to your data warehouse.

<b>Signature:</b>

```typescript
assignmentLogger?: IAssignmentLogger;
```
1 change: 1 addition & 0 deletions docs/js-client-sdk.iclientconfig.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ export interface IClientConfig
| Property | Type | Description |
| --- | --- | --- |
| [apiKey](./js-client-sdk.iclientconfig.apikey.md) | string | Eppo API key |
| [assignmentLogger?](./js-client-sdk.iclientconfig.assignmentlogger.md) | [IAssignmentLogger](./js-client-sdk.iassignmentlogger.md) | <i>(Optional)</i> Pass a logging implementation to send variation assignments to your data warehouse. |
| [baseUrl?](./js-client-sdk.iclientconfig.baseurl.md) | string | <i>(Optional)</i> Base URL of the Eppo API. Clients should use the default setting in most cases. |

2 changes: 2 additions & 0 deletions docs/js-client-sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

| Interface | Description |
| --- | --- |
| [IAssignmentEvent](./js-client-sdk.iassignmentevent.md) | Holds data about the variation a subject was assigned to. |
| [IAssignmentLogger](./js-client-sdk.iassignmentlogger.md) | Implement this interface log variation assignments to your data warehouse. |
| [IClientConfig](./js-client-sdk.iclientconfig.md) | Configuration used for initializing the Eppo client |
| [IEppoClient](./js-client-sdk.ieppoclient.md) | Client for assigning experiment variations. |

16 changes: 16 additions & 0 deletions js-client-sdk.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,25 @@
// @public
export function getInstance(): IEppoClient;

// @public
export interface IAssignmentEvent {
experiment: string;
subject: string;
// (undocumented)
subjectAttributes: Record<string, any>;
timestamp: string;
variation: string;
}

// @public
export interface IAssignmentLogger {
logAssignment(assignment: IAssignmentEvent): void;
}

// @public
export interface IClientConfig {
apiKey: string;
assignmentLogger?: IAssignmentLogger;
baseUrl?: string;
}

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eppo/js-client-sdk",
"version": "0.0.1",
"version": "0.0.2",
"description": "Eppo SDK for client-side JavaScript applications",
"main": "dist/index.js",
"files": [
Expand All @@ -16,7 +16,7 @@
"typecheck": "tsc",
"test": "yarn test:unit",
"test:unit": "NODE_ENV=test jest '.*\\.spec\\.ts'",
"docs": "api-extractor run --local --verbose && api-documenter markdown -i ./temp -o ./docs"
"docs": "tsc && api-extractor run --local --verbose && api-documenter markdown -i ./temp -o ./docs"
},
"repository": {
"type": "git",
Expand Down
41 changes: 41 additions & 0 deletions src/assignment-logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Holds data about the variation a subject was assigned to.
* @public
*/
export interface IAssignmentEvent {
/**
* An Eppo experiment key
*/
experiment: string;

/**
* The assigned variation
*/
variation: string;

/**
* The entity or user that was assigned to a variation
*/
subject: string;

/**
* The time the subject was exposed to the variation.
*/
timestamp: string;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
subjectAttributes: Record<string, any>;
}

/**
* Implement this interface log variation assignments to your data warehouse.
* @public
*/
export interface IAssignmentLogger {
/**
* Invoked when a subject is assigned to an experiment variation.
* @param assignment holds the variation an experiment subject was assigned to
* @public
*/
logAssignment(assignment: IAssignmentEvent): void;
}
105 changes: 66 additions & 39 deletions src/eppo-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import mock from 'xhr-mock';

import { IAssignmentTestCase, readAssignmentTestData } from '../test/testHelpers';

import { IAssignmentLogger } from './assignment-logger';
import EppoClient from './eppo-client';
import { IExperimentConfiguration } from './experiment/experiment-configuration';
import ExperimentConfigurationRequestor from './experiment/experiment-configuration-requestor';
Expand Down Expand Up @@ -41,6 +42,30 @@ describe('EppoClient E2E test', () => {
mock.teardown();
});

const mockVariations = [
{
name: 'control',
shardRange: {
start: 0,
end: 33,
},
},
{
name: 'variant-1',
shardRange: {
start: 34,
end: 66,
},
},
{
name: 'variant-2',
shardRange: {
start: 67,
end: 100,
},
},
];

describe('getAssignment', () => {
it.each(readAssignmentTestData())(
'test variation assignment splits',
Expand Down Expand Up @@ -73,29 +98,7 @@ describe('EppoClient E2E test', () => {
percentExposure: 1,
enabled: true,
subjectShards: 100,
variations: [
{
name: 'control',
shardRange: {
start: 0,
end: 33,
},
},
{
name: 'variant-1',
shardRange: {
start: 34,
end: 66,
},
},
{
name: 'variant-2',
shardRange: {
start: 67,
end: 100,
},
},
],
variations: mockVariations,
overrides: {
a90ea45116d251a43da56e03d3dd7275: 'variant-2',
},
Expand All @@ -105,6 +108,45 @@ describe('EppoClient E2E test', () => {
expect(assignment).toEqual('variant-2');
});

it('logs variation assignment', () => {
const mockConfigRequestor = td.object<ExperimentConfigurationRequestor>();
const mockLogger = td.object<IAssignmentLogger>();
const experiment = 'experiment_5';
td.when(mockConfigRequestor.getConfiguration(experiment)).thenReturn({
name: experiment,
percentExposure: 1,
enabled: true,
subjectShards: 100,
variations: mockVariations,
overrides: {},
});
const subjectAttributes = { foo: 3 };
const client = new EppoClient(mockConfigRequestor, mockLogger);
const assignment = client.getAssignment('subject-1', experiment, subjectAttributes);
expect(assignment).toEqual('control');
expect(td.explain(mockLogger.logAssignment).callCount).toEqual(1);
expect(td.explain(mockLogger.logAssignment).calls[0].args[0].subject).toEqual('subject-1');
});

it('handles logging exception', () => {
const mockConfigRequestor = td.object<ExperimentConfigurationRequestor>();
const mockLogger = td.object<IAssignmentLogger>();
const experiment = 'experiment_5';
td.when(mockLogger.logAssignment(td.matchers.anything())).thenThrow(new Error('logging error'));
td.when(mockConfigRequestor.getConfiguration(experiment)).thenReturn({
name: experiment,
percentExposure: 1,
enabled: true,
subjectShards: 100,
variations: mockVariations,
overrides: {},
});
const subjectAttributes = { foo: 3 };
const client = new EppoClient(mockConfigRequestor, mockLogger);
const assignment = client.getAssignment('subject-1', experiment, subjectAttributes);
expect(assignment).toEqual('control');
});

it('only returns variation if subject matches rules', () => {
const mockConfigRequestor = td.object<ExperimentConfigurationRequestor>();
const experiment = 'experiment_5';
Expand All @@ -113,22 +155,7 @@ describe('EppoClient E2E test', () => {
percentExposure: 1,
enabled: true,
subjectShards: 100,
variations: [
{
name: 'control',
shardRange: {
start: 0,
end: 50,
},
},
{
name: 'treatment',
shardRange: {
start: 50,
end: 100,
},
},
],
variations: mockVariations,
overrides: {},
rules: [
{
Expand Down
Loading

0 comments on commit 61c20aa

Please sign in to comment.