-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
150 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import computeDomain from "./compute_domain.js"; | ||
|
||
export function generateFilter( | ||
includeDomains = [], | ||
includeEntities = [], | ||
excludeDomains = [], | ||
excludeEntities = [] | ||
) { | ||
includeDomains = new Set(includeDomains); | ||
includeEntities = new Set(includeEntities); | ||
excludeDomains = new Set(excludeDomains); | ||
excludeEntities = new Set(excludeEntities); | ||
|
||
const haveInclude = includeDomains.size | (includeEntities.size !== 0); | ||
const haveExclude = excludeDomains.size | (excludeEntities.size !== 0); | ||
|
||
// Case 1 - no includes or excludes - pass all entities | ||
if (!haveInclude && !haveExclude) { | ||
return () => true; | ||
} | ||
|
||
// Case 2 - includes, no excludes - only include specified entities | ||
if (haveInclude && !haveExclude) { | ||
return (entityId) => | ||
includeEntities.has(entityId) || | ||
includeDomains.has(computeDomain(entityId)); | ||
} | ||
|
||
// Case 3 - excludes, no includes - only exclude specified entities | ||
if (!haveInclude && haveExclude) { | ||
return (entityId) => | ||
!excludeEntities.has(entityId) && | ||
!excludeDomains.has(computeDomain(entityId)); | ||
} | ||
|
||
// Case 4 - both includes and excludes specified | ||
// Case 4a - include domain specified | ||
// - if domain is included, and entity not excluded, pass | ||
// - if domain is not included, and entity not included, fail | ||
// note: if both include and exclude domains specified, | ||
// the exclude domains are ignored | ||
if (includeDomains.size) { | ||
return (entityId) => | ||
includeDomains.has(computeDomain(entityId)) | ||
? !excludeEntities.has(entityId) | ||
: includeEntities.has(entityId); | ||
} | ||
|
||
// Case 4b - exclude domain specified | ||
// - if domain is excluded, and entity not included, fail | ||
// - if domain is not excluded, and entity not excluded, pass | ||
if (excludeDomains.size) { | ||
return (entityId) => | ||
excludeDomains.has(computeDomain(entityId)) | ||
? includeEntities.has(entityId) | ||
: !excludeEntities.has(entityId); | ||
} | ||
|
||
// Case 4c - neither include or exclude domain specified | ||
// - Only pass if entity is included. Ignore entity excludes. | ||
return (entityId) => includeEntities.has(entityId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { generateFilter } from "../../../src/common/entity/entity_filter.js"; | ||
|
||
const assert = require("assert"); | ||
|
||
describe("EntityFilter", () => { | ||
// case 1 | ||
it("passes all when no filters passed in", () => { | ||
const filter = generateFilter(); | ||
|
||
assert(filter("sensor.test")); | ||
assert(filter("sun.sun")); | ||
assert(filter("light.test")); | ||
}); | ||
|
||
// case 2 | ||
it("allows whitelisting entities by entity id", () => { | ||
const filter = generateFilter(null, ["light.kitchen"]); | ||
|
||
assert(filter("light.kitchen")); | ||
assert(!filter("light.living_room")); | ||
}); | ||
|
||
it("allows whitelisting entities by domain", () => { | ||
const filter = generateFilter(["switch"]); | ||
|
||
assert(filter("switch.bla")); | ||
assert(!filter("light.kitchen")); | ||
}); | ||
|
||
// case 3 | ||
it("allows blacklisting entities by entity id", () => { | ||
const filter = generateFilter(null, null, null, ["light.kitchen"]); | ||
|
||
assert(!filter("light.kitchen")); | ||
assert(filter("light.living_room")); | ||
}); | ||
|
||
it("allows blacklisting entities by domain", () => { | ||
const filter = generateFilter(null, null, ["switch"]); | ||
|
||
assert(!filter("switch.bla")); | ||
assert(filter("light.kitchen")); | ||
}); | ||
|
||
// case 4a | ||
it("allows whitelisting domain and blacklisting entity", () => { | ||
const filter = generateFilter(["switch"], null, null, ["switch.kitchen"]); | ||
|
||
assert(filter("switch.living_room")); | ||
assert(!filter("switch.kitchen")); | ||
assert(!filter("sensor.bla")); | ||
}); | ||
|
||
it("allows whitelisting entity while whitelisting other domains", () => { | ||
const filter = generateFilter(["switch"], ["light.kitchen"]); | ||
|
||
assert(filter("switch.living_room")); | ||
assert(filter("light.kitchen")); | ||
assert(!filter("sensor.bla")); | ||
}); | ||
|
||
// case 4b | ||
it("allows blacklisting domain and whitelisting entity", () => { | ||
const filter = generateFilter(null, ["switch.kitchen"], ["switch"]); | ||
|
||
assert(filter("switch.kitchen")); | ||
assert(!filter("switch.living_room")); | ||
assert(filter("sensor.bla")); | ||
}); | ||
|
||
it("allows blacklisting domain and excluding entities", () => { | ||
const filter = generateFilter(null, null, ["switch"], ["light.kitchen"]); | ||
|
||
assert(!filter("switch.living_room")); | ||
assert(!filter("light.kitchen")); | ||
assert(filter("sensor.bla")); | ||
}); | ||
|
||
// case 4c | ||
it("allows whitelisting entities", () => { | ||
const filter = generateFilter(null, ["light.kitchen"]); | ||
|
||
assert(filter("light.kitchen")); | ||
assert(!filter("switch.living_room")); | ||
assert(!filter("light.living_room")); | ||
assert(!filter("sensor.bla")); | ||
}); | ||
}); |