add derived classes for basicFilter and filterColumnTaregt to support column with keys

This commit is contained in:
Noa Nutkevitch 2016-12-17 23:36:05 -08:00
Родитель 3257ea7c67
Коммит 1914191df5
4 изменённых файлов: 122 добавлений и 24 удалений

Просмотреть файл

@ -124,7 +124,10 @@ export interface IBaseFilterTarget {
export interface IFilterColumnTarget extends IBaseFilterTarget {
column: string;
keys?: string[];
}
export interface IFilterKeyColumnsTarget extends IFilterColumnTarget {
keys: string[];
}
export interface IFilterHierarchyTarget extends IBaseFilterTarget {
@ -145,7 +148,12 @@ export interface IFilter {
export interface IBasicFilter extends IFilter {
operator: BasicFilterOperators;
values: (string | number | boolean)[] | (string | number | boolean)[][];
values: (string | number | boolean)[];
}
export interface IBasicFilterWithKeys extends IBasicFilter {
target: IFilterKeyColumnsTarget;
keyValues: (string | number | boolean)[][];
}
export type BasicFilterOperators = "In" | "NotIn" | "All";
@ -222,19 +230,20 @@ export abstract class Filter {
export class BasicFilter extends Filter {
static schemaUrl: string = "http://powerbi.com/product/schema#basic";
operator: BasicFilterOperators;
values: (string | number | boolean)[] | (string | number | boolean)[][];
values: (string | number | boolean)[];
keyValues: (string | number | boolean)[][];
constructor(
target: IFilterTarget,
operator: BasicFilterOperators,
...values: ((string | number | boolean) | (string | number | boolean)[] | (string | number | boolean)[][])[]
...values: ((string | number | boolean) | (string | number | boolean)[])[]
) {
super(target);
this.operator = operator;
this.schemaUrl = BasicFilter.schemaUrl;
if (values.length === 0 && operator !== "All") {
throw new Error(`values must be a non-empty array unless your operator is "All". You passed: ${values}`);
throw new Error(`values must be a non-empty array unless your operator is "All".`);
}
/**
@ -243,21 +252,10 @@ export class BasicFilter extends Filter {
* new BasicFilter('a', 'b', [1,2]);
*/
if (Array.isArray(values[0])) {
this.values = <(string | number | boolean)[] | (string | number | boolean)[][]>values[0];
this.values = <(string | number | boolean)[]>values[0];
}
else {
this.values = <(string | number | boolean)[] | (string | number | boolean)[][]>values;
}
let numberOfKeys = (<IFilterColumnTarget>target).keys ? (<IFilterColumnTarget>target).keys.length : 0;
for (let i = 0 ; i < this.values.length ; i++) {
if (this.values[i] && Array.isArray(this.values[i])) {
let lengthOfArray = (<(string | number | boolean)[]>this.values[i]).length;
if (lengthOfArray !== numberOfKeys) {
throw new Error(`Each tuple of values should contain a value for each of the key columns. You passed: ${lengthOfArray} values and ${numberOfKeys} key columns`);
}
}
this.values = <(string | number | boolean)[]>values;
}
}
@ -271,6 +269,47 @@ export class BasicFilter extends Filter {
}
}
export class BasicFilterWithKeys extends BasicFilter {
keyValues: (string | number | boolean)[][];
target: IFilterKeyColumnsTarget;
constructor(
target: IFilterKeyColumnsTarget,
operator: BasicFilterOperators,
values: ((string | number | boolean) | (string | number | boolean)[]),
keyValues: (string | number | boolean)[][]
) {
super(target, operator, values);
this.keyValues = keyValues;
this.target = target;
let numberOfKeys = target.keys ? target.keys.length : 0;
if (numberOfKeys && !keyValues) {
throw new Error(`You shold pass the values to be filtered for each key. You passed: no values and ${numberOfKeys} keys`);
}
if (!numberOfKeys && keyValues && keyValues.length > 0) {
throw new Error(`You passed key values but you target object doesn't contain the keys to be filtered`);
}
for (let i = 0 ; i < this.keyValues.length ; i++) {
if (this.keyValues[i] ) {
let lengthOfArray = this.keyValues[i].length;
if (lengthOfArray !== numberOfKeys) {
throw new Error(`Each tuple of key values should contain a value for each of the keys. You passed: ${lengthOfArray} values and ${numberOfKeys} keys`);
}
}
}
}
toJSON(): IBasicFilter {
const filter = <IBasicFilterWithKeys>super.toJSON();
filter.keyValues = this.keyValues;
return filter;
}
}
export class AdvancedFilter extends Filter {
static schemaUrl: string = "http://powerbi.com/product/schema#advanced";

Просмотреть файл

@ -31,7 +31,16 @@
"values": {
"type": "array",
"items": {
"type": ["string", "boolean", "number", "array"]
"type": ["string", "boolean", "number"]
}
},
"keyValues": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": ["string", "boolean", "number"]
}
}
}
},

Просмотреть файл

@ -0,0 +1,48 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"target": {
"type": "object",
"properties": {
"table": {
"type": "string"
},
"column": {
"type": "string"
},
"keys": {
"type": "array",
"items": {
"type": ["string"]
}
}
},
"required": [
"table",
"column",
"keys"
]
},
"operator": {
"type": "string"
},
"values": {
"type": "array",
"items": {
"type": ["string", "boolean", "number"]
}
},
"keyValues": {
"type": "array",
"items": {
"type": ["array"]
}
}
},
"required": [
"target",
"operator",
"values"
]
}

Просмотреть файл

@ -514,10 +514,11 @@ describe("Unit | Filters", function () {
it("should accept values as an array of tuples", function () {
// Arrange
const values = [[1, 2], [3,4]];
const values = [1, 2];
const keyValues = [[1, 2], [3,4]];
// Act
const basicFilter = new models.BasicFilter({ table: "t", column: "c" , keys: ["1", "2"]}, "In", values);
const basicFilter = new models.BasicFilterWithKeys({ table: "t", column: "c" , keys: ["1", "2"]}, "In", values, keyValues);
// Assert
expect(basicFilter.values).toEqual(values);
@ -525,11 +526,12 @@ describe("Unit | Filters", function () {
it("should throw an exception when values are an array of tuples, but tuples length is different than keys length", function () {
// Arrange
const values = [[1, 2], [3,4]];
const values = [1, 2];
const keyValues = [[1, 2], [3,4]];
// Act
const attemptToCreateFilter = () => {
return new models.BasicFilter({ table: "t", column: "c" , keys: ["1"]}, "In", values);
return new models.BasicFilterWithKeys({ table: "t", column: "c" , keys: ["1"]}, "In", values, keyValues);
};
expect(attemptToCreateFilter).toThrowError();
});
@ -706,7 +708,7 @@ describe("Unit | Filters", function () {
// Arrange
const testData = {
basicFilter: new models.BasicFilter({ table: "a", column: "b" }, "In", ["x", "y"]),
basicFilterWithKeys: new models.BasicFilter({ table: "a", column: "b", keys: ["1", "2"] }, "In", [["x1", 1], ["y2",2]]),
basicFilterWithKeys: new models.BasicFilterWithKeys({ table: "a", column: "b", keys: ["1", "2"] }, "In", ["x1", 1], [["x1", 1], ["y2",2]]),
advancedFilter: new models.AdvancedFilter({ table: "a", column: "b" }, "And",
{ operator: "Contains", value: "x" },
{ operator: "Contains", value: "x" }