Commit 5808a6b5 authored by David Sveningsson's avatar David Sveningsson
Browse files

feat(event)!: `ConfigReadyEvent` passes `ResolvedConfig` instance instead of `ConfigData`

parent 3ebcae55
Pipeline #377492857 passed with stages
in 14 minutes and 9 seconds
......@@ -2,6 +2,9 @@
## Upgrading to `%version%`
- CLI users: No required changes but if custom element metadata is present it can benefit from upgrading format.
- API users: Breaking changes!
### Configuration changes
The format for specifying attribute metadata has changed.
......@@ -163,3 +166,9 @@ If you used `requiredAttributes` or `deprecatedAttributes` these have now been i
-const isDeprecated = meta.deprecatedAttributes.includes(attr.key);
+const isDeprecated = meta.attribute[attr.key]?.deprecated;
```
### `ConfigReadyEvent`
If you have a rule or plugin listening to the `ConfigReadyEvent` event the datatype of the `config` property has changed from `ConfigData` to `ResolvedConfig`.
For most part it contains the same information but is normalized, for instance rules are now always passed as `Record<RuleID, [Severity, Options]>`.
Configured transformers, plugins etc are resolved instances and fields suchs as `root` and `extends` will never be present.
......@@ -91,7 +91,7 @@ describe("Engine", () => {
},
});
config.init();
engine = new ExposedEngine(config.resolve(), config.get(), MockParser);
engine = new ExposedEngine(config.resolve(), MockParser);
});
describe("lint()", () => {
......@@ -176,7 +176,8 @@ describe("Engine", () => {
it("should generate config:ready event", () => {
expect.assertions(5);
const source: Source[] = [inline("<div></div>")];
const parser = new Parser(config.resolve());
const resolved = config.resolve();
const parser = new Parser(resolved);
const spy = jest.fn();
parser.on("config:ready", spy);
jest.spyOn(engine, "instantiateParser").mockReturnValue(parser);
......@@ -193,7 +194,7 @@ describe("Engine", () => {
"size": 1,
}
`);
expect(event.config).toEqual(config.get());
expect(event.config).toEqual(resolved);
expect(event.rules).toBeDefined();
});
......@@ -488,7 +489,7 @@ describe("Engine", () => {
(config as any).plugins = [plugin];
const source = inline("");
const engine = new ExposedEngine(config.resolve(), config.get(), MockParser);
const engine = new ExposedEngine(config.resolve(), MockParser);
engine.lint([source]);
expect(plugin.init).toHaveBeenCalledWith();
});
......@@ -504,7 +505,7 @@ describe("Engine", () => {
(config as any).plugins = [plugin];
const source = inline("");
const engine = new ExposedEngine(config.resolve(), config.get(), MockParser);
const engine = new ExposedEngine(config.resolve(), MockParser);
engine.lint([source]);
expect(plugin.setup).toHaveBeenCalledWith(source, expect.any(EventHandler));
});
......@@ -590,11 +591,7 @@ describe("Engine", () => {
},
];
const engine: ExposedEngine<Parser> = new ExposedEngine(
config.resolve(),
config.get(),
MockParser
);
const engine: ExposedEngine<Parser> = new ExposedEngine(config.resolve(), MockParser);
const rule = engine.loadRule(
"custom/my-rule",
config.resolve(),
......@@ -619,11 +616,7 @@ describe("Engine", () => {
},
];
const engine: ExposedEngine<Parser> = new ExposedEngine(
config.resolve(),
config.get(),
MockParser
);
const engine: ExposedEngine<Parser> = new ExposedEngine(config.resolve(), MockParser);
const missingRule = jest.spyOn(engine, "missingRule");
engine.loadRule("custom/my-rule", config.resolve(), Severity.ERROR, {}, parser, reporter);
expect(missingRule).toHaveBeenCalledWith("custom/my-rule");
......@@ -644,11 +637,7 @@ describe("Engine", () => {
},
];
const engine: ExposedEngine<Parser> = new ExposedEngine(
config.resolve(),
config.get(),
MockParser
);
const engine: ExposedEngine<Parser> = new ExposedEngine(config.resolve(), MockParser);
const rule = engine.loadRule(
"custom/my-rule",
config.resolve(),
......@@ -664,7 +653,7 @@ describe("Engine", () => {
expect.assertions(1);
/* mock loading of plugins */
(config as any).plugins = [{}];
expect(() => new ExposedEngine(config.resolve(), config.get(), MockParser)).not.toThrow();
expect(() => new ExposedEngine(config.resolve(), MockParser)).not.toThrow();
});
});
});
......
import { ConfigData, ResolvedConfig, RuleOptions, Severity } from "../config";
import { ResolvedConfig, RuleOptions, Severity } from "../config";
import { Location, Source } from "../context";
import { HtmlElement } from "../dom";
import { DOMInternalID } from "../dom/domnode";
......@@ -28,18 +28,12 @@ export interface TokenDump {
export class Engine<T extends Parser = Parser> {
protected report: Reporter;
protected configData: ConfigData;
protected config: ResolvedConfig;
protected ParserClass: new (config: ResolvedConfig) => T;
protected availableRules: Record<string, RuleConstructor<any, any>>;
public constructor(
config: ResolvedConfig,
configData: ConfigData,
ParserClass: new (config: ResolvedConfig) => T
) {
public constructor(config: ResolvedConfig, ParserClass: new (config: ResolvedConfig) => T) {
this.report = new Reporter();
this.configData = configData;
this.config = config;
this.ParserClass = ParserClass;
......@@ -77,7 +71,7 @@ export class Engine<T extends Parser = Parser> {
/* trigger configuration ready event */
const configEvent: ConfigReadyEvent = {
location,
config: this.configData,
config: this.config,
rules,
};
parser.trigger("config:ready", configEvent);
......
import { ConfigData } from "../config";
import { ResolvedConfig } from "../config";
import { Location, Source } from "../context";
import { DOMTree, DynamicValue, HtmlElement } from "../dom";
import { TokenType } from "../lexer";
......@@ -16,7 +16,7 @@ export interface Event {
* Configuration ready event.
*/
export interface ConfigReadyEvent extends Event {
config: ConfigData;
config: ResolvedConfig;
rules: { [ruleId: string]: Rule };
}
......
......@@ -99,7 +99,7 @@ class HtmlValidate {
const config = this.getConfigFor(input.filename, configOverride);
const resolved = config.resolve();
const source = resolved.transformSource(input);
const engine = new Engine(resolved, config.get(), Parser);
const engine = new Engine(resolved, Parser);
return engine.lint(source);
}
......@@ -114,7 +114,7 @@ class HtmlValidate {
const config = this.getConfigFor(filename);
const resolved = config.resolve();
const source = resolved.transformFilename(filename);
const engine = new Engine(resolved, config.get(), Parser);
const engine = new Engine(resolved, Parser);
return engine.lint(source);
}
......@@ -163,7 +163,7 @@ class HtmlValidate {
const config = this.getConfigFor(filename);
const resolved = config.resolve();
const source = resolved.transformFilename(filename);
const engine = new Engine(resolved, config.get(), Parser);
const engine = new Engine(resolved, Parser);
return engine.dumpTokens(source);
}
......@@ -179,7 +179,7 @@ class HtmlValidate {
const config = this.getConfigFor(filename);
const resolved = config.resolve();
const source = resolved.transformFilename(filename);
const engine = new Engine(resolved, config.get(), Parser);
const engine = new Engine(resolved, Parser);
return engine.dumpEvents(source);
}
......@@ -195,7 +195,7 @@ class HtmlValidate {
const config = this.getConfigFor(filename);
const resolved = config.resolve();
const source = resolved.transformFilename(filename);
const engine = new Engine(resolved, config.get(), Parser);
const engine = new Engine(resolved, Parser);
return engine.dumpTree(source);
}
......@@ -283,7 +283,7 @@ class HtmlValidate {
context: any | null = null
): RuleDocumentation | null {
const c = config || this.getConfigFor("inline");
const engine = new Engine(c.resolve(), c.get(), Parser);
const engine = new Engine(c.resolve(), Parser);
return engine.getRuleDocumentation(ruleId, context);
}
......
......@@ -305,13 +305,13 @@ describe("Plugin", () => {
it("Engine should handle missing plugin callbacks", () => {
expect.assertions(1);
expect(() => new Engine(config.resolve(), config.get(), Parser)).not.toThrow();
expect(() => new Engine(config.resolve(), Parser)).not.toThrow();
});
it("Engine should call plugin init callback", () => {
expect.assertions(1);
mockPlugin.init = jest.fn();
const engine = new Engine(config.resolve(), config.get(), Parser);
const engine = new Engine(config.resolve(), Parser);
engine.lint([source]);
expect(mockPlugin.init).toHaveBeenCalledWith();
});
......@@ -319,7 +319,7 @@ describe("Plugin", () => {
it("Engine should call plugin setup callback", () => {
expect.assertions(1);
mockPlugin.setup = jest.fn();
const engine = new Engine(config.resolve(), config.get(), Parser);
const engine = new Engine(config.resolve(), Parser);
engine.lint([source]);
expect(mockPlugin.setup).toHaveBeenCalledWith(source, expect.any(EventHandler));
});
......@@ -330,7 +330,7 @@ describe("Plugin", () => {
mockPlugin.setup = (source: Source, eventhandler: EventHandler) => {
eventhandler.on("dom:ready", handler);
};
const engine = new Engine(config.resolve(), config.get(), Parser);
const engine = new Engine(config.resolve(), Parser);
engine.lint([source]);
expect(handler).toHaveBeenCalledWith("dom:ready", expect.anything());
});
......@@ -359,7 +359,7 @@ describe("Plugin", () => {
"mock-rule": null /* instantiateRule is mocked, this can be anything */,
};
const setup = jest.spyOn(mockRule, "setup");
const engine = new Engine(config.resolve(), config.get(), Parser);
const engine = new Engine(config.resolve(), Parser);
jest.spyOn(engine as any, "instantiateRule").mockImplementation(() => mockRule);
engine.lint([source]);
expect(setup).toHaveBeenCalledWith();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment