Merge remote-tracking branch 'powerbi/master' into release-1.15.2

This commit is contained in:
Roi Hochler 2024-03-25 11:34:36 +00:00
Родитель 8745e11218 2ab2419d6b
Коммит 46b6866144
12 изменённых файлов: 9359 добавлений и 4992 удалений

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

@ -14,12 +14,11 @@ module.exports = function (config) {
exclude: [],
reporters: argv.debug ? ['spec', 'kjhtml'] : ['spec', 'coverage', 'kjhtml'],
autoWatch: true,
browsers: [argv.chrome ? 'Chrome_headless' : 'PhantomJS'],
browsers: ["Chrome_headless"],
plugins: [
'karma-chrome-launcher',
'karma-jasmine',
'karma-spec-reporter',
'karma-phantomjs-launcher',
'karma-coverage',
'karma-jasmine-html-reporter'
],

13912
package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,6 +1,6 @@
{
"name": "powerbi-models",
"version": "1.12.4",
"version": "1.15.2",
"description": "Contains JavaScript & TypeScript object models for Microsoft Power BI JavaScript SDK. For each model there is a TypeScript interface, and a validation function to ensure and object is valid.",
"main": "dist/models.js",
"typings": "dist/models.d.ts",
@ -61,9 +61,7 @@
"karma-coverage": "^2.0.1",
"karma-jasmine": "^0.3.8",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.4",
"karma-spec-reporter": "0.0.32",
"phantomjs-prebuilt": "^2.1.7",
"ts-loader": "^6.2.1",
"typedoc": "^0.22.14",
"typescript": "~4.6.0",

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

@ -173,7 +173,13 @@ export interface IVisual {
}
export interface IDatasetBinding {
datasetId: string;
datasetId?: string;
paginatedReportBindings?: IPaginatedReportDatasetBinding[];
}
export interface IPaginatedReportDatasetBinding {
sourceDatasetId: string;
targetDatasetId: string;
}
export enum Permissions {
@ -307,6 +313,10 @@ export enum MenuLocation {
Top
}
export interface IQueryNameTarget {
queryName: string;
}
export interface IBaseTarget {
table: string;
$schema?: string;
@ -378,7 +388,9 @@ export declare type IFilterKeyTarget = (IFilterKeyColumnsTarget | IFilterKeyHier
export declare type IFilterTarget = (IFilterColumnTarget | IFilterHierarchyTarget | IFilterMeasureTarget | INotSupportedFilterTarget | IFilterColumnAggrTarget | IFilterHierarchyAggrTarget);
export type ITupleFilterTarget = IFilterTarget[];
export type IIdentityFilterTarget = number[];
export type IFilterGeneralTarget = IFilterTarget | IFilterKeyTarget | ITupleFilterTarget | IIdentityFilterTarget;
export type IHierarchyIdentityFilterTarget = IQueryNameTarget[];
export type IIncludeExcludeFilterTarget = IFilterTarget | (IFilterTarget | IFilterKeyTarget)[][];
export type IFilterGeneralTarget = IFilterTarget | IFilterKeyTarget | ITupleFilterTarget | IIdentityFilterTarget | IIncludeExcludeFilterTarget | IHierarchyIdentityFilterTarget;
export interface IFilter {
$schema: string;
target: IFilterGeneralTarget;
@ -404,7 +416,8 @@ export interface INotSupportedFilter extends IFilter {
}
export interface IIncludeExcludeFilter extends IFilter {
values: (string | number | boolean)[];
values: (string | number | boolean)[] | IncludeExcludeFilterValuesType;
target: IIncludeExcludeFilterTarget;
isExclude: boolean;
}
@ -452,6 +465,14 @@ export interface ITupleFilter extends IFilter {
values: TupleValueType[];
}
export interface IIncludeExcludeTargetValue {
value: PrimitiveValueType;
keyValues?: PrimitiveValueType[];
}
export type IncludeExcludePointType = IIncludeExcludeTargetValue[];
export type IncludeExcludePointsGroupType = IncludeExcludePointType[];
export type IncludeExcludeFilterValuesType = IncludeExcludePointsGroupType[];
export enum FiltersOperations {
RemoveAll,
ReplaceAll,
@ -518,6 +539,21 @@ export interface IHierarchyFilter extends IFilter {
hierarchyData: IHierarchyFilterNode[];
}
export interface IHierarchyIdentityFilterNode<IdentityType> {
identity: IdentityType;
children?: IHierarchyIdentityFilterNode<IdentityType>[];
operator: HierarchyFilterNodeOperators;
}
export interface IHierarchyIdentityFilter<IdentityType> extends IFilter {
target: IHierarchyIdentityFilterTarget;
hierarchyData: IHierarchyIdentityFilterNode<IdentityType>[];
}
export interface ISmartNarratives {
summaryText: string;
}
export enum FilterType {
Advanced = 0,
Basic = 1,
@ -529,6 +565,7 @@ export enum FilterType {
RelativeTime = 7,
Identity = 8,
Hierarchy = 9,
HierarchyIdentity = 10,
}
export enum RelativeDateFilterTimeUnit {
@ -607,14 +644,16 @@ export class NotSupportedFilter extends Filter {
export class IncludeExcludeFilter extends Filter {
static schemaUrl: string = "http://powerbi.com/product/schema#includeExclude";
values: (string | number | boolean)[];
values: (string | number | boolean)[] | IncludeExcludeFilterValuesType;
isExclude: boolean;
target: IIncludeExcludeFilterTarget;
constructor(
target: IFilterTarget,
target: IIncludeExcludeFilterTarget,
isExclude: boolean,
values: (string | number | boolean)[]) {
values: (string | number | boolean)[] | IncludeExcludeFilterValuesType) {
super(target, FilterType.IncludeExclude);
this.target = target;
this.values = values;
this.isExclude = isExclude;
this.schemaUrl = IncludeExcludeFilter.schemaUrl;
@ -932,6 +971,29 @@ export class HierarchyFilter extends Filter {
}
}
export class HierarchyIdentityFilter<IdentityType> extends Filter {
static schemaUrl: string = "http://powerbi.com/product/schema#hierarchyIdentity";
target: IHierarchyIdentityFilterTarget;
hierarchyData: IHierarchyIdentityFilterNode<IdentityType>[];
constructor(
target: IHierarchyIdentityFilterTarget,
hierarchyData: IHierarchyIdentityFilterNode<IdentityType>[]
) {
super(target, FilterType.HierarchyIdentity);
this.schemaUrl = HierarchyIdentityFilter.schemaUrl;
this.hierarchyData = hierarchyData;
}
toJSON(): IHierarchyIdentityFilter<IdentityType> {
const filter = super.toJSON() as IHierarchyIdentityFilter<IdentityType>;
filter.hierarchyData = this.hierarchyData;
filter.target = this.target;
return filter;
}
}
export interface IDataReference {
target: IFilterTarget;
}
@ -1175,6 +1237,18 @@ export interface IColumnSchema {
name: string;
displayName?: string;
dataType: DataType;
aggregateFunction?: AggregateFunction;
}
export enum AggregateFunction {
Default = 1,
None,
Sum,
Min,
Max,
Count,
Average,
DistinctCount
}
export const enum DataType {
@ -1227,6 +1301,15 @@ export interface ILocaleSettings {
formatLocale?: string;
}
export enum BrowserPrintAdjustmentsMode {
Default,
NoAdjustments
}
export interface IPrintSettings {
browserPrintAdjustmentsMode?: BrowserPrintAdjustmentsMode;
}
export const enum ReportCreationMode {
Default = "Default",
QuickExplore = "QuickExplore",
@ -1253,6 +1336,7 @@ export interface ISettings {
visualSettings?: IVisualSettings;
localeSettings?: ILocaleSettings;
zoomLevel?: number;
printSettings?: IPrintSettings;
}
export interface IReportBars {
@ -1327,6 +1411,7 @@ export interface IPaginatedReportLoadConfiguration {
type?: string;
embedUrl?: string;
parameterValues?: IPaginatedReportParameter[];
datasetBindings?: IPaginatedReportDatasetBinding[];
}
export interface IPaginatedReportSettings {
@ -1663,6 +1748,7 @@ export interface ICommandsSettings {
groupVisualContainers?: ICommandSettings;
summarize?: ICommandSettings;
clearSelection?: ICommandSettings;
focusMode?: ICommandSettings;
}
export interface IPaginatedReportsCommandSettings {
@ -1961,3 +2047,8 @@ export function validateZoomLevel(input: any): IError[] {
const errors: any[] = Validators.zoomLevelValidator.validate(input);
return errors ? errors.map(normalizeError) : undefined;
}
export function validatePrintSettings(input: any): IError[] {
const errors: any[] = Validators.printSettingsValidator.validate(input);
return errors ? errors.map(normalizeError) : undefined;
}

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

@ -23,6 +23,7 @@ import {
HierarchyFilterNodeValidator,
HierarchyFilterValidator,
IncludeExcludeFilterValidator,
IncludeExcludePointValueValidator,
NotSupportedFilterValidator,
OnLoadFiltersBaseRemoveOperationValidator,
OnLoadFiltersBaseValidator,
@ -64,6 +65,8 @@ import { ArrayValidator, BooleanArrayValidator, BooleanValidator, EnumValidator,
import { ParametersPanelValidator } from '../models/parameterPanelValidator';
import { DatasetCreateConfigValidator, ColumnSchemaValidator, DatasourceConnectionConfigValidator, TableSchemaValidator, TableDataValidator, CredentialsValidator } from '../models/datasetCreateConfigValidator';
import { QuickCreateValidator } from '../models/quickCreateValidator';
import { PrintSettingsValidator } from '../models/printSettingsValidator';
import { PaginatedReportDatasetBindingValidator } from '../models/paginatedReportDatasetBindingValidator';
export interface IValidationError {
path?: string;
@ -136,7 +139,7 @@ export const Validators = {
filterConditionsValidator: new ArrayValidator([new ConditionItemValidator()]),
filterHierarchyTargetValidator: new FilterHierarchyTargetValidator(),
filterMeasureTargetValidator: new FilterMeasureTargetValidator(),
filterTargetValidator: new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new ArrayValidator([new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new FilterKeyColumnsTargetValidator(), new FilterKeyHierarchyTargetValidator()])])]),
filterTargetValidator: new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new ArrayValidator([new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new FilterKeyColumnsTargetValidator(), new FilterKeyHierarchyTargetValidator(), new ArrayValidator([new AnyOfValidator([new FilterColumnTargetValidator(), new FilterHierarchyTargetValidator(), new FilterMeasureTargetValidator(), new FilterKeyColumnsTargetValidator(), new FilterKeyHierarchyTargetValidator()])])])])]),
filterValidator: new FilterValidator(),
filterTypeValidator: new EnumValidator([0, 1, 2, 3, 4, 5, 6, 7, 9]),
filtersArrayValidator: new ArrayValidator([new FilterValidator()]),
@ -146,6 +149,7 @@ export const Validators = {
hyperlinkClickBehaviorValidator: new EnumValidator([0, 1, 2]),
includeExcludeFilterValidator: new IncludeExcludeFilterValidator(),
includeExludeFilterTypeValidator: new EnumValidator([3]),
includeExcludeFilterValuesValidator: new ArrayValidator([new AnyOfValidator([new StringValidator(), new NumberValidator(), new BooleanValidator(), new ArrayValidator([new ArrayValidator([new IncludeExcludePointValueValidator()])])])]),
hierarchyFilterTypeValidator: new EnumValidator([9]),
hierarchyFilterValuesValidator: new ArrayValidator([new HierarchyFilterNodeValidator()]),
layoutTypeValidator: new EnumValidator([0, 1, 2, 3]),
@ -168,12 +172,14 @@ export const Validators = {
pageViewFieldValidator: new PageViewFieldValidator(),
pagesLayoutValidator: new MapValidator([new StringValidator()], [new PageLayoutValidator()]),
paginatedReportCommandsValidator: new PaginatedReportCommandsValidator(),
paginatedReportDatasetBindingArrayValidator: new ArrayValidator([new PaginatedReportDatasetBindingValidator()]),
paginatedReportLoadValidator: new PaginatedReportLoadValidator(),
paginatedReportsettingsValidator: new PaginatedReportSettingsValidator(),
parameterValuesArrayValidator: new ArrayValidator([new ReportParameterFieldsValidator()]),
parametersPanelValidator: new ParametersPanelValidator(),
permissionsValidator: new EnumValidator([0, 1, 2, 4, 7]),
playBookmarkRequestValidator: new PlayBookmarkRequestValidator(),
printSettingsValidator: new PrintSettingsValidator(),
qnaInterpretInputDataValidator: new QnaInterpretInputDataValidator(),
qnaPanesValidator: new QnaPanesValidator(),
qnaSettingValidator: new QnaSettingsValidator(),

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

@ -16,10 +16,22 @@ export class DatasetBindingValidator extends ObjectValidator {
return errors;
}
if (!input["datasetId"] && !input["paginatedReportBindings"]) {
return [{
message: "datasetBinding cannot be empty",
path: (path ? path + "." : "") + field,
keyword: "invalid"
}];
}
const fields: IFieldValidatorsPair[] = [
{
field: "datasetId",
validators: [Validators.fieldRequiredValidator, Validators.stringValidator]
validators: [Validators.stringValidator]
},
{
field: "paginatedReportBindings",
validators: [Validators.paginatedReportDatasetBindingArrayValidator]
}
];

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

@ -430,7 +430,7 @@ export class IncludeExcludeFilterValidator extends FilterValidatorBase {
},
{
field: "values",
validators: [Validators.fieldRequiredValidator, Validators.anyArrayValidator]
validators: [Validators.fieldRequiredValidator, Validators.includeExcludeFilterValuesValidator]
},
{
field: "filterType",
@ -505,6 +505,33 @@ export class HierarchyFilterNodeValidator extends ObjectValidator {
}
}
export class IncludeExcludePointValueValidator extends ObjectValidator {
public validate(input: any, path?: string, field?: string): IValidationError[] {
if (input == null) {
return null;
}
const errors = super.validate(input, path, field);
if (errors) {
return errors;
}
const fields: IFieldValidatorsPair[] = [
{
field: "value",
validators: [Validators.fieldRequiredValidator, Validators.anyValueValidator]
},
{
field: "keyValues",
validators: [Validators.anyArrayValidator]
}
];
const multipleFieldsValidator = new MultipleFieldsValidator(fields);
return multipleFieldsValidator.validate(input, path, field);
}
}
export class FilterValidator extends ObjectValidator {
public validate(input: any, path?: string, field?: string): IValidationError[] {
if (input == null) {

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

@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { IFieldValidatorsPair, MultipleFieldsValidator } from '../core/multipleFieldsValidator';
import { ObjectValidator } from '../core/typeValidator';
import { IValidationError, Validators } from '../core/validator';
export class PaginatedReportDatasetBindingValidator extends ObjectValidator {
public validate(input: any, path?: string, field?: string): IValidationError[] {
if (input == null) {
return null;
}
const errors = super.validate(input, path, field);
if (errors) {
return errors;
}
const fields: IFieldValidatorsPair[] = [
{
field: "sourceDatasetId",
validators: [Validators.fieldRequiredValidator, Validators.stringValidator]
},
{
field: "targetDatasetId",
validators: [Validators.fieldRequiredValidator, Validators.stringValidator]
}
];
const multipleFieldsValidator = new MultipleFieldsValidator(fields);
return multipleFieldsValidator.validate(input, path, field);
}
}

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

@ -47,6 +47,10 @@ export class PaginatedReportLoadValidator extends ObjectValidator {
{
field: "parameterValues",
validators: [Validators.parameterValuesArrayValidator]
},
{
field: "datasetBindings",
validators: [Validators.paginatedReportDatasetBindingArrayValidator]
}
];

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

@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { IFieldValidatorsPair, MultipleFieldsValidator } from '../core/multipleFieldsValidator';
import { EnumValidator, ObjectValidator } from '../core/typeValidator';
import { IValidationError } from '../core/validator';
export class PrintSettingsValidator extends ObjectValidator {
public validate(input: any, path?: string, field?: string): IValidationError[] {
if (input == null) {
return null;
}
const errors = super.validate(input, path, field);
if (errors) {
return errors;
}
const fields: IFieldValidatorsPair[] = [
{
field: "browserPrintAdjustmentsMode",
validators: [new EnumValidator([0, 1])]
}
];
const multipleFieldsValidator = new MultipleFieldsValidator(fields);
return multipleFieldsValidator.validate(input, path, field);
}
}

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

@ -87,6 +87,10 @@ export class SettingsValidator extends ObjectValidator {
{
field: "authoringHintsEnabled",
validators: [Validators.booleanValidator]
},
{
field: "printSettings",
validators: [Validators.printSettingsValidator]
}
];

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

@ -18,7 +18,6 @@ describe('Unit | Models', () => {
const accessTokenRequiredMessage = "accessToken is required";
const accessTokenInvalidTypeMessage = "accessToken must be a string";
const datasetIdInvalidTypeMessage = "datasetId must be a string";
const datasetIdRequiredMessage = "datasetId is required";
const idRequiredMessage = "id is required";
const idInvalidTypeMessage = "id must be a string";
const pageNameInvalidTypeMessage = "pageName must be a string";
@ -266,7 +265,7 @@ describe('Unit | Models', () => {
expect(errors).toBeUndefined();
});
it(`should return errors with one containing message '${datasetIdRequiredMessage}' if datasetId doesn't exists`, () => {
it(`should return errors if no datasetId nor PaginatedReportDatasetBindings is provided`, () => {
// Arrange
const testData = {
load: {
@ -276,11 +275,51 @@ describe('Unit | Models', () => {
}
}
};
// Act
const errors = models.validateReportLoad(testData.load);
// Assert
testForExpectedMessage(errors, "datasetBinding cannot be empty");
});
it(`should return undefined if id, accessToken are provided and paginatedReportBindings is valid`, () => {
// Arrange
const testData = {
load: {
id: 'fakeId',
accessToken: 'fakeAccessToken',
datasetBinding: {
paginatedReportBindings: [
{ sourceDatasetId: 'sourceDatasetId', targetDatasetId: 'targetDatasetId' }
]
}
}
};
// Act
const errors = models.validateReportLoad(testData.load);
// Assert
testForExpectedMessage(errors, datasetIdRequiredMessage);
expect(errors).toBeUndefined();
});
it(`should return undefined if id, accessToken are provided and both datasetBinding and paginatedReportBindings is valid`, () => {
// Arrange
const testData = {
load: {
id: 'fakeId',
accessToken: 'fakeAccessToken',
datasetBinding: {
datasetId: "fakeDatasetId",
paginatedReportBindings: [
{ sourceDatasetId: 'sourceDatasetId', targetDatasetId: 'targetDatasetId' }
]
}
}
};
// Act
const errors = models.validateReportLoad(testData.load);
// Assert
expect(errors).toBeUndefined();
});
it(`should return errors with one containing message '${datasetIdInvalidTypeMessage}' if datasetId is not a string`, () => {
@ -651,10 +690,16 @@ describe('Unit | Models', () => {
});
describe('validatePaginatedReportLoad', () => {
const testData: any = {
let testData: any = {
accessToken: "token",
id: "reportid",
};
beforeEach(() => {
testData = {
accessToken: "token",
id: "reportid",
};
});
it(`happy path`, () => {
testData.settings = { commands: { parameterPanel: { enabled: true, expanded: true } } };
const errors = models.validatePaginatedReportLoad(testData);
@ -698,6 +743,34 @@ describe('Unit | Models', () => {
const errors = models.validatePaginatedReportLoad(testData);
testForExpectedMessage(errors, 'parameterValues property is invalid');
});
it('should fail if datasetBindings are defined without sourceDatasetId', () => {
testData.datasetBindings = [
{
targetDatasetId: 'targetDatasetId'
}
];
const errors = models.validatePaginatedReportLoad(testData);
testForExpectedMessage(errors, 'datasetBindings property is invalid');
});
it('should fail if datasetBindings are defined without targetDatasetId', () => {
testData.datasetBindings = [
{
sourceDatasetId: 'sourceDatasetId'
}
];
const errors = models.validatePaginatedReportLoad(testData);
testForExpectedMessage(errors, 'datasetBindings property is invalid');
});
it('should fail if datasetBindings are defined with not string types', () => {
testData.datasetBindings = [
{
sourceDatasetId: 2,
targetDatasetId: null
}
];
const errors = models.validatePaginatedReportLoad(testData);
testForExpectedMessage(errors, 'datasetBindings property is invalid');
});
});
describe('validateDashboardLoad', () => {
@ -1247,6 +1320,44 @@ describe('Unit | Models', () => {
expect(models.validateFilter(filter.toJSON())).toBeUndefined();
});
it("should return undefined if object is valid include/exclude filter schema with multiple targets", () => {
// Arrange
const expectedFilter: models.IIncludeExcludeFilter = {
$schema: "http://powerbi.com/product/schema#includeExclude",
target: [
[{
table: "a",
column: "b"
},
{
table: "a",
column: "c"
}]
],
values: [
[
[
{value: 1}, {value: 2}
],
[
{value: 3}, {value: 4}
]
]
],
isExclude: false,
filterType: models.FilterType.IncludeExclude
};
// Act
const filter = new models.IncludeExcludeFilter(
expectedFilter.target,
expectedFilter.isExclude,
expectedFilter.values);
// Assert
expect(models.validateFilter(filter.toJSON())).toBeUndefined();
});
it("should return undefined if object is valid advanced filter schema", () => {
// Arrange
const expectedFilter: models.IAdvancedFilter = {
@ -1490,6 +1601,8 @@ describe('Unit | Models', () => {
const layoutTypeInvalidTypeMessage = "layoutType must be a number";
const layoutTypeInvalidMessage = "layoutType property is invalid";
const customLayoutInvalidMessage = "customLayout must be an object";
const browserPrintAdjustmentsModeInvalidMessage = "browserPrintAdjustmentsMode property is invalid";
const printSettingsInvalidMessage = "printSettings must be an object";
const hyperlinkClickBehaviorInvalidTypeMessage = "hyperlinkClickBehavior must be a number";
const hyperlinkClickBehaviorInvalidMessage = "hyperlinkClickBehavior property is invalid";
const modeInvalidMessage = "mode property is invalid";
@ -1766,6 +1879,38 @@ describe('Unit | Models', () => {
testForExpectedMessage(errors, modeInvalidMessage);
});
it(`should return errors with one containing message '${printSettingsInvalidMessage}' if printSettings type is not valid`, () => {
// Arrange
const testData = {
settings: {
printSettings: 1
}
};
// Act
const errors = models.validateSettings(testData.settings);
// Assert
testForExpectedMessage(errors, printSettingsInvalidMessage);
});
it(`should return errors with one containing message '${browserPrintAdjustmentsModeInvalidMessage}' if browserPrintAdjustmentsMode value is not valid`, () => {
// Arrange
const testData = {
settings: {
printSettings: {
browserPrintAdjustmentsMode: 2
}
}
};
// Act
const errors = models.validateSettings(testData.settings);
// Assert
testForExpectedMessage(errors, browserPrintAdjustmentsModeInvalidMessage);
});
it(`should return undefined if settings is valid (empty)`, () => {
// Arrange
const testData = {
@ -1791,7 +1936,8 @@ describe('Unit | Models', () => {
extensions: [{ command: { name: "name", extend: {}, title: "title" } }],
commands: [{ exportData: { displayOption: models.CommandDisplayOption.Enabled } }],
layoutType: 0,
customLayout: {}
customLayout: {},
printSettings: { browserPrintAdjustmentsMode: 1 }
}
};
@ -3707,6 +3853,56 @@ describe("Unit | Filters", () => {
// Assert
expect(filter.toJSON()).toEqual(expectedFilter);
});
it("should output the correct json when toJSON is called with multiple targets", () => {
// Arrange
const expectedFilter: models.IIncludeExcludeFilter = {
$schema: "http://powerbi.com/product/schema#includeExclude",
target: [
[{
table: "a",
column: "b"
},
{
table: "a",
column: "c"
}],
[{
table: "a",
column: "d"
}]
],
values: [
[
[
{value: 1}, {value: 2}
],
[
{value: 3}, {value: 4}
]
],
[
[
{value: 5}
],
[
{value: 6}
]
]
],
isExclude: false,
filterType: models.FilterType.IncludeExclude
};
// Act
const filter = new models.IncludeExcludeFilter(
expectedFilter.target,
expectedFilter.isExclude,
expectedFilter.values);
// Assert
expect(filter.toJSON()).toEqual(expectedFilter);
});
});
describe('determine types', () => {