Skip to content

Commit

Permalink
Merge branch 'main' into add-matchers-to-quickpicks
Browse files Browse the repository at this point in the history
  • Loading branch information
mattseddon committed Jul 19, 2023
2 parents 5e97e92 + 97a042d commit 3036fb3
Show file tree
Hide file tree
Showing 16 changed files with 846 additions and 447 deletions.
3 changes: 2 additions & 1 deletion extension/src/cli/dvc/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const DVCLIVE_ONLY_RUNNING_SIGNAL_FILE = join(
)
export const EXP_RWLOCK_FILE = join(TEMP_EXP_DIR, 'rwlock.lock')

export const DEFAULT_NUM_OF_COMMITS_TO_SHOW = 3
export const DEFAULT_CURRENT_BRANCH_COMMITS_TO_SHOW = 3
export const DEFAULT_OTHER_BRANCH_COMMITS_TO_SHOW = 1
export const NUM_OF_COMMITS_TO_INCREASE = 2

export enum Command {
Expand Down
271 changes: 271 additions & 0 deletions extension/src/experiments/model/filterBy/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
import { FilterDefinition, filterExperiment, Operator } from '.'
import { buildMetricOrParamPath } from '../../columns/paths'
import { Experiment, ColumnType } from '../../webview/contract'

describe('filterExperiment', () => {
const paramsFile = 'params.yaml'
const experiments = [
{
Created: '2020-12-29T12:00:01',
id: 1,
params: {
'params.yaml': {
bool: true,
filter: 1,
sort: 1,
text: 'abcdefghijklmnop'
}
}
},
{
Created: '2020-12-30T12:00:01',
id: 2,
params: {
'params.yaml': {
bool: false,
filter: 2,
sort: 1,
text: 'fun'
}
}
},
{
Created: '2021-01-01T00:00:01',
id: 3,
params: {
'params.yaml': {
bool: null,
filter: 3,
sort: 1,
text: 'not missing'
}
}
}
] as unknown as Experiment[]

const filterExperiments = (filters: FilterDefinition[]): Experiment[] =>
experiments
.map(experiment => filterExperiment(filters, experiment))
.filter(Boolean) as Experiment[]

it('should not filter experiments if they do not have the provided value (for queued experiments)', () => {
const unfiltered = filterExperiments([
{
operator: Operator.IS_FALSE,
path: buildMetricOrParamPath(ColumnType.METRICS, 'metrics.json', 'acc'),
value: undefined
}
])

expect(
unfiltered
.map(
experiment => experiment[ColumnType.METRICS]?.['metrics.json']?.acc
)
.filter(Boolean)
).toHaveLength(0)

expect(unfiltered).toStrictEqual(experiments)
})

it('should filter experiments if they do not have the provided value and not missing is used', () => {
const unfiltered = filterExperiments([
{
operator: Operator.NOT_MISSING,
path: buildMetricOrParamPath(ColumnType.METRICS, 'metrics.json', 'acc'),
value: undefined
}
])

expect(unfiltered).toStrictEqual([])
})

it('should not filter the experiments if no filters are provided', () => {
const unfiltered = filterExperiments([])

expect(unfiltered).toStrictEqual(experiments)
})

it('should filter the experiments with a greater than filter', () => {
const unfiltered = filterExperiments([
{
operator: Operator.GREATER_THAN,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'filter'),
value: '2'
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([3])
})

it('should filter experiments by an equals filter', () => {
const unfiltered = filterExperiments([
{
operator: Operator.EQUAL,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'filter'),
value: '2'
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([2])
})

it('should filter experiments by a not equals filter', () => {
const unfiltered = filterExperiments([
{
operator: Operator.NOT_EQUAL,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'filter'),
value: '2'
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([1, 3])
})

it('should filter experiments by multiple filters', () => {
const unfiltered = filterExperiments([
{
operator: Operator.GREATER_THAN,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'filter'),
value: '0'
},
{
operator: Operator.LESS_THAN_OR_EQUAL,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'filter'),
value: '2'
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([1, 2])
})

it('should filter experiments by multiple filters on multiple params', () => {
const unfiltered = filterExperiments([
{
operator: Operator.GREATER_THAN_OR_EQUAL,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'filter'),
value: '0'
},
{
operator: Operator.LESS_THAN,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'filter'),
value: '10'
},
{
operator: Operator.EQUAL,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'sort'),
value: '10'
}
])

expect(unfiltered).toStrictEqual([])
})

it('should filter experiments using string contains', () => {
const unfiltered = filterExperiments([
{
operator: Operator.CONTAINS,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'text'),
value: 'def'
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([1])
})

it('should filter experiments if given a numeric column to filter with string contains', () => {
const unfiltered = filterExperiments([
{
operator: Operator.CONTAINS,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'filter'),
value: '1'
}
])

expect(unfiltered).toStrictEqual([])
})

it('should filter experiments when given a numeric column to filter with string does not contain', () => {
const unfiltered = filterExperiments([
{
operator: Operator.NOT_CONTAINS,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'filter'),
value: '1'
}
])

expect(unfiltered).toStrictEqual(experiments)
})

it('should filter experiments using string does not contain', () => {
const unfiltered = filterExperiments([
{
operator: Operator.NOT_CONTAINS,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'text'),
value: 'def'
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([2, 3])
})

it('should split the experiments using boolean is true', () => {
const unfiltered = filterExperiments([
{
operator: Operator.IS_TRUE,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'bool'),
value: undefined
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([1])
})

it('should split the experiments using boolean is false', () => {
const unfiltered = filterExperiments([
{
operator: Operator.IS_FALSE,
path: buildMetricOrParamPath(ColumnType.PARAMS, paramsFile, 'bool'),
value: undefined
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([2])
})

it('should split the experiments using after Created date', () => {
const unfiltered = filterExperiments([
{
operator: Operator.AFTER_DATE,
path: 'Created',
value: '2020-12-31T15:40:00'
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([3])
})

it('should split the experiments using before Created date', () => {
const unfiltered = filterExperiments([
{
operator: Operator.BEFORE_DATE,
path: 'Created',
value: '2020-12-31T15:40:00'
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([1, 2])
})

it('should split the experiments using on Created date', () => {
const unfiltered = filterExperiments([
{
operator: Operator.ON_DATE,
path: 'Created',
value: '2020-12-31T15:40:00'
}
])

expect(unfiltered.map(experiment => experiment.id)).toStrictEqual([])
})
})
12 changes: 8 additions & 4 deletions extension/src/experiments/model/filterBy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import { definedAndNonEmpty } from '../../../util/array'
import { splitColumnPath } from '../../columns/paths'

export enum Operator {
EQUAL = '==',
EQUAL = '=',
GREATER_THAN = '>',
GREATER_THAN_OR_EQUAL = '>=',
LESS_THAN = '<',
LESS_THAN_OR_EQUAL = '<=',
NOT_EQUAL = '!=',
NOT_EQUAL = '≠',

NOT_MISSING = '≠Ø',

CONTAINS = '∈',
NOT_CONTAINS = '!∈',
NOT_CONTAINS = '',

IS_TRUE = '⊤',
IS_FALSE = '⊥',
Expand Down Expand Up @@ -56,9 +58,11 @@ const evaluate = <T extends string | number | boolean>(
filterValue: T
): boolean => {
if (valueToEvaluate === undefined) {
return true
return operator !== Operator.NOT_MISSING
}
switch (operator) {
case Operator.NOT_MISSING:
return true
case Operator.GREATER_THAN:
return valueToEvaluate > filterValue
case Operator.LESS_THAN:
Expand Down
12 changes: 11 additions & 1 deletion extension/src/experiments/model/filterBy/quickPick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ export const OPERATORS = [
types: ['number', 'string'],
value: Operator.NOT_EQUAL
},
{
description: 'Not Missing',
label: Operator.NOT_MISSING,
types: ['string', 'boolean', 'number'],
value: Operator.NOT_MISSING
},
{
description: 'Is true',
label: Operator.IS_TRUE,
Expand Down Expand Up @@ -130,7 +136,11 @@ export const pickFilterToAdd = async (
return
}

if ([Operator.IS_TRUE, Operator.IS_FALSE].includes(operator)) {
if (
[Operator.IS_TRUE, Operator.IS_FALSE, Operator.NOT_MISSING].includes(
operator
)
) {
return {
operator,
path: picked.path,
Expand Down
10 changes: 5 additions & 5 deletions extension/src/experiments/model/filterBy/tree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ describe('ExperimentsFilterByTree', () => {
const filters = await experimentsFilterByTree.getChildren()
expect(filters).toStrictEqual([
{
description: '== 90000',
description: '= 90000',
dvcRoot: 'demo',
id: buildMetricOrParamPath(
ColumnType.PARAMS,
'params.yaml',
'param==90000'
'param=90000'
),
label: buildMetricOrParamPath(ColumnType.PARAMS, 'params.yaml', 'param')
}
Expand Down Expand Up @@ -119,7 +119,7 @@ describe('ExperimentsFilterByTree', () => {
it("should return the dvcRoot's filters if one is provided", async () => {
const mockedFilters = [
{
operator: '==',
operator: '=',
path: buildMetricOrParamPath(ColumnType.PARAMS, 'params.yml', 'param'),
value: 90000
},
Expand All @@ -146,12 +146,12 @@ describe('ExperimentsFilterByTree', () => {

expect(filters).toStrictEqual([
{
description: '== 90000',
description: '= 90000',
dvcRoot: 'demo',
id: buildMetricOrParamPath(
ColumnType.PARAMS,
'params.yml',
'param==90000'
'param=90000'
),
label: buildMetricOrParamPath(ColumnType.PARAMS, 'params.yml', 'param')
},
Expand Down
Loading

0 comments on commit 3036fb3

Please sign in to comment.