Remove silly support for async initial_value

This complicates the handling of configs for no good reason.
This commit is contained in:
Hornwitser committed 2024-01-06 19:49:35 +01:00
1 parent ede150d80f
commit 27af142a87
15 files changed
+93 -93

No files matched your search

+3 -3
View File
@@ -156,7 +156,7 @@ async function handleBootstrapCommand(
return; return;
} }
let controlConfig = new lib.ControlConfig("control"); let controlConfig = new lib.ControlConfig("control");
await controlConfig.init(); controlConfig.init();
controlConfig.set("control.controller_url", Controller.calculateControllerUrl(controllerConfig)); controlConfig.set("control.controller_url", Controller.calculateControllerUrl(controllerConfig));
controlConfig.set( controlConfig.set(
@@ -325,12 +325,12 @@ async function initialize(): Promise<InitializeParameters> {
const controllerConfig = new lib.ControllerConfig("controller"); const controllerConfig = new lib.ControllerConfig("controller");
try { try {
let fileData = await fs.readFile(controllerConfigPath, { encoding: "utf8" }); let fileData = await fs.readFile(controllerConfigPath, { encoding: "utf8" });
await controllerConfig.load(JSON.parse(fileData)); controllerConfig.load(JSON.parse(fileData));
} catch (err: any) { } catch (err: any) {
if (err.code === "ENOENT") { if (err.code === "ENOENT") {
logger.info("Config not found, initializing new config"); logger.info("Config not found, initializing new config");
await controllerConfig.init(); controllerConfig.init();
} else { } else {
throw new lib.StartupError(`Failed to load ${controllerConfigPath}: ${err.message}`); throw new lib.StartupError(`Failed to load ${controllerConfigPath}: ${err.message}`);
+2 -2
View File
@@ -212,7 +212,7 @@ export default class ControlConnection extends BaseConnection {
async handleHostConfigCreateRequest(request: lib.HostConfigCreateRequest) { async handleHostConfigCreateRequest(request: lib.HostConfigCreateRequest) {
let hostConfig = new lib.HostConfig("control"); let hostConfig = new lib.HostConfig("control");
await hostConfig.init(); hostConfig.init();
hostConfig.set("host.controller_url", this._controller.getControllerUrl()); hostConfig.set("host.controller_url", this._controller.getControllerUrl());
if (request.id !== undefined) { if (request.id !== undefined) {
@@ -239,7 +239,7 @@ export default class ControlConnection extends BaseConnection {
// XXX should probably add a hook for host reuqests? // XXX should probably add a hook for host reuqests?
async handleInstanceCreateRequest(request: lib.InstanceCreateRequest) { async handleInstanceCreateRequest(request: lib.InstanceCreateRequest) {
let instanceConfig = new lib.InstanceConfig("controller"); let instanceConfig = new lib.InstanceConfig("controller");
await instanceConfig.load(request.config as lib.SerializedConfig); instanceConfig.load(request.config as lib.SerializedConfig);
await this._controller.instanceCreate(instanceConfig); await this._controller.instanceCreate(instanceConfig);
} }
+3 -3
View File
@@ -498,7 +498,7 @@ export default class Controller {
json = { config: json, status: "running" }; // Use running to force updatedAt json = { config: json, status: "running" }; // Use running to force updatedAt
} }
let instanceConfig = new lib.InstanceConfig("controller"); let instanceConfig = new lib.InstanceConfig("controller");
await instanceConfig.load(json.config as lib.SerializedConfig); instanceConfig.load(json.config as lib.SerializedConfig);
let instance = InstanceInfo.fromJSON(json, instanceConfig); let instance = InstanceInfo.fromJSON(json, instanceConfig);
const status = instance.config.get("instance.assigned_host") === null ? "unassigned" : "unknown"; const status = instance.config.get("instance.assigned_host") === null ? "unassigned" : "unknown";
if (instance.status !== status) { if (instance.status !== status) {
@@ -690,7 +690,7 @@ export default class Controller {
* *
* @example * @example
* let instanceConfig = new lib.InstanceConfig("controller"); * let instanceConfig = new lib.InstanceConfig("controller");
* await instanceConfig.init(); * instanceConfig.init();
* instanceConfig.set("instance.name", "My instance"); * instanceConfig.set("instance.name", "My instance");
* let instance = await controller.instanceAssign(instanceConfig); * let instance = await controller.instanceAssign(instanceConfig);
* await controller.instanceAssign(instance.id, hostId); * await controller.instanceAssign(instance.id, hostId);
@@ -1007,7 +1007,7 @@ export default class Controller {
} }
let controllerPlugin = new ControllerPluginClass(pluginInfo, this, metrics as any, logger); let controllerPlugin = new ControllerPluginClass(pluginInfo, this, metrics as any, logger);
await controllerPlugin.init(); controllerPlugin.init();
this.plugins.set(pluginInfo.name, controllerPlugin); this.plugins.set(pluginInfo.name, controllerPlugin);
} catch (err: any) { } catch (err: any) {
+1 -1
View File
@@ -198,7 +198,7 @@ export default class HostConnection extends BaseConnection {
const instanceUpdates: InstanceInfo[] = []; const instanceUpdates: InstanceInfo[] = [];
for (let instanceData of request.instances) { for (let instanceData of request.instances) {
let instanceConfig = new lib.InstanceConfig("controller"); let instanceConfig = new lib.InstanceConfig("controller");
await instanceConfig.load(instanceData.config as lib.SerializedConfig, "host"); instanceConfig.load(instanceData.config as lib.SerializedConfig, "host");
let controllerInstance = this._controller.instances.get(instanceConfig.get("instance.id")); let controllerInstance = this._controller.instances.get(instanceConfig.get("instance.id"));
if (controllerInstance) { if (controllerInstance) {
+2 -2
View File
@@ -221,12 +221,12 @@ async function startControl() {
logger.verbose(`Loading config from ${args.config}`); logger.verbose(`Loading config from ${args.config}`);
let controlConfig = new lib.ControlConfig("control"); let controlConfig = new lib.ControlConfig("control");
try { try {
await controlConfig.load(JSON.parse(await fs.readFile(args.config, "utf8"))); controlConfig.load(JSON.parse(await fs.readFile(args.config, "utf8")));
} catch (err: any) { } catch (err: any) {
if (err.code === "ENOENT") { if (err.code === "ENOENT") {
logger.verbose("Config not found, initializing new config"); logger.verbose("Config not found, initializing new config");
await controlConfig.init(); controlConfig.init();
} else { } else {
throw new lib.StartupError(`Failed to load ${args.config}: ${err.message}`); throw new lib.StartupError(`Failed to load ${args.config}: ${err.message}`);
+1 -1
View File
@@ -315,7 +315,7 @@ instanceCommands.add(new lib.Command({
}], }],
handler: async function(args: { name: string, id?: number }, control: Control) { handler: async function(args: { name: string, id?: number }, control: Control) {
let instanceConfig = new lib.InstanceConfig("control"); let instanceConfig = new lib.InstanceConfig("control");
await instanceConfig.init(); instanceConfig.init();
if (args.id !== undefined) { if (args.id !== undefined) {
instanceConfig.set("instance.id", args.id); instanceConfig.set("instance.id", args.id);
} }
+2 -2
View File
@@ -148,12 +148,12 @@ async function startHost() {
logger.info(`Loading config from ${args.config}`); logger.info(`Loading config from ${args.config}`);
let hostConfig = new lib.HostConfig("host"); let hostConfig = new lib.HostConfig("host");
try { try {
await hostConfig.load(JSON.parse(await fs.readFile(args.config, "utf8"))); hostConfig.load(JSON.parse(await fs.readFile(args.config, "utf8")));
} catch (err: any) { } catch (err: any) {
if (err.code === "ENOENT") { if (err.code === "ENOENT") {
logger.info("Config not found, initializing new config"); logger.info("Config not found, initializing new config");
await hostConfig.init(); hostConfig.init();
} else { } else {
throw new lib.StartupError(`Failed to load ${args.config}: ${err.message}`); throw new lib.StartupError(`Failed to load ${args.config}: ${err.message}`);
+2 -2
View File
@@ -47,7 +47,7 @@ async function discoverInstances(instancesDir: string) {
let configPath = path.join(instancesDir, entry.name, "instance.json"); let configPath = path.join(instancesDir, entry.name, "instance.json");
try { try {
await instanceConfig.load(JSON.parse(await fs.readFile(configPath, "utf8"))); instanceConfig.load(JSON.parse(await fs.readFile(configPath, "utf8")));
} catch (err: any) { } catch (err: any) {
if (err.code === "ENOENT") { if (err.code === "ENOENT") {
@@ -574,7 +574,7 @@ export default class Host extends lib.Link {
} else { } else {
let instanceConfig = new lib.InstanceConfig("host"); let instanceConfig = new lib.InstanceConfig("host");
await instanceConfig.load(config as any, "controller"); instanceConfig.load(config as any, "controller");
let instanceDir = await this._createNewInstanceDir(instanceConfig.get("instance.name")); let instanceDir = await this._createNewInstanceDir(instanceConfig.get("instance.name"));
+9 -9
View File
@@ -108,11 +108,11 @@ export class Config extends events.EventEmitter {
} }
} }
async init() { init() {
for (let [name, GroupClass] of (this.constructor as typeof Config)._groups) { for (let [name, GroupClass] of (this.constructor as typeof Config)._groups) {
if (!this._groups.has(name)) { if (!this._groups.has(name)) {
let group = new GroupClass(this); let group = new GroupClass(this);
await group.init(); group.init();
this._groups.set(name, group); this._groups.set(name, group);
} }
} }
@@ -135,7 +135,7 @@ export class Config extends events.EventEmitter {
* @param serializedConfig - Serialized config to load. * @param serializedConfig - Serialized config to load.
* @param location - Location used for access control. * @param location - Location used for access control.
*/ */
async load( load(
serializedConfig: SerializedConfig, serializedConfig: SerializedConfig,
location = this.location location = this.location
) { ) {
@@ -148,11 +148,11 @@ export class Config extends events.EventEmitter {
} }
let group = new GroupClass(this); let group = new GroupClass(this);
await group.load(serializedGroup, location); group.load(serializedGroup, location);
this._groups.set(group.name, group); this._groups.set(group.name, group);
} }
await this.init(); this.init();
} }
/** /**
@@ -428,7 +428,7 @@ export class ConfigGroup {
* Computes and assigns the initial values for all fields of the * Computes and assigns the initial values for all fields of the
* config group. * config group.
*/ */
async init() { init() {
for (let [name, def] of (this.constructor as typeof ConfigGroup)._definitions) { for (let [name, def] of (this.constructor as typeof ConfigGroup)._definitions) {
if (this._fields.has(name)) { if (this._fields.has(name)) {
continue; continue;
@@ -439,7 +439,7 @@ export class ConfigGroup {
let value = null; let value = null;
if (typeof def.initial_value === "function") { if (typeof def.initial_value === "function") {
value = await def.initial_value(); value = def.initial_value();
} else if (def.initial_value !== undefined) { } else if (def.initial_value !== undefined) {
value = def.initial_value; value = def.initial_value;
@@ -460,9 +460,9 @@ export class ConfigGroup {
* Result from a previous call to .serialize(). * Result from a previous call to .serialize().
* @param location - Location used for access control. * @param location - Location used for access control.
*/ */
async load(serializedGroup: SerializedGroup, location = this.config.location) { load(serializedGroup: SerializedGroup, location = this.config.location) {
this.update(serializedGroup, false, location); this.update(serializedGroup, false, location);
await this.init(); this.init();
} }
/** /**
@@ -49,7 +49,7 @@ export default function BaseConfigTree(props: BaseConfigTreeProps) {
async function updateConfig() { async function updateConfig() {
let serializedConfig = await props.retrieveConfig(); let serializedConfig = await props.retrieveConfig();
let newConfig = new props.ConfigClass("control"); let newConfig = new props.ConfigClass("control");
await newConfig.load(serializedConfig); newConfig.load(serializedConfig);
setConfig(newConfig); setConfig(newConfig);
return newConfig; return newConfig;
} }
@@ -27,7 +27,7 @@ function CreateInstanceButton() {
} }
let instanceConfig = new lib.InstanceConfig("control"); let instanceConfig = new lib.InstanceConfig("control");
await instanceConfig.init(); instanceConfig.init();
instanceConfig.set("instance.name", values.instanceName); instanceConfig.set("instance.name", values.instanceName);
let serializedConfig = instanceConfig.serialize("controller"); let serializedConfig = instanceConfig.serialize("controller");
await control.send(new lib.InstanceCreateRequest(serializedConfig)); await control.send(new lib.InstanceCreateRequest(serializedConfig));
+2 -2
View File
@@ -7,7 +7,7 @@ const lib = require("@clusterio/lib");
describe("controller/InstanceInfo", function() { describe("controller/InstanceInfo", function() {
describe("class InstanceInfo", function() { describe("class InstanceInfo", function() {
it("should round trip serialize", async function() { it("should round trip serialize", function() {
const validate = lib.compile(InstanceInfo.jsonSchema); const validate = lib.compile(InstanceInfo.jsonSchema);
function check(info) { function check(info) {
const json = JSON.parse(JSON.stringify(info)); const json = JSON.parse(JSON.stringify(info));
@@ -21,7 +21,7 @@ describe("controller/InstanceInfo", function() {
lib.InstanceConfig.finalize(); lib.InstanceConfig.finalize();
} }
const config = new lib.InstanceConfig("controller"); const config = new lib.InstanceConfig("controller");
await config.init(); config.init();
check(InstanceInfo.fromJSON({ config, status: "stopped" }, config)); check(InstanceInfo.fromJSON({ config, status: "stopped" }, config));
check(InstanceInfo.fromJSON({ config, status: "running" }, config)); check(InstanceInfo.fromJSON({ config, status: "running" }, config));
+1 -1
View File
@@ -17,7 +17,7 @@ describe("Host testing", function() {
let instanceInfos = await _discoverInstances(instancePath); let instanceInfos = await _discoverInstances(instancePath);
let referenceConfig = new lib.InstanceConfig("host"); let referenceConfig = new lib.InstanceConfig("host");
await referenceConfig.init(); referenceConfig.init();
referenceConfig.set("instance.id", 1); referenceConfig.set("instance.id", 1);
referenceConfig.set("instance.name", "test"); referenceConfig.set("instance.name", "test");
referenceConfig.dirty = false; referenceConfig.dirty = false;
+2 -2
View File
@@ -19,9 +19,9 @@ describe("class Instance", function() {
let dst = addr({ hostId: 1 }); let dst = addr({ hostId: 1 });
let instance; let instance;
let connector; let connector;
beforeEach(async function() { beforeEach(function() {
let instanceConfig = new lib.InstanceConfig("host"); let instanceConfig = new lib.InstanceConfig("host");
await instanceConfig.init(); instanceConfig.init();
instanceConfig.set("instance.name", "foo"); instanceConfig.set("instance.name", "foo");
src = addr({ instanceId: instanceConfig.get("instance.id") }); src = addr({ instanceId: instanceConfig.get("instance.id") });
connector = new MockConnector(src, dst); connector = new MockConnector(src, dst);
+61 -61
View File
@@ -166,35 +166,35 @@ describe("lib/config/classes", function() {
}); });
describe(".init()", function() { describe(".init()", function() {
it("should initialize all fields with defaults", async function() { it("should initialize all fields with defaults", function() {
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.init(); testInstance.init();
assert.equal(testInstance.get("enum"), "b"); assert.equal(testInstance.get("enum"), "b");
assert.equal(testInstance.get("test"), null); assert.equal(testInstance.get("test"), null);
assert.equal(testInstance.get("func"), 42); assert.equal(testInstance.get("func"), 42);
assert.equal(testInstance.get("priv"), null); assert.equal(testInstance.get("priv"), null);
}); });
it("should not initalize inaccessible fields", async function() { it("should not initalize inaccessible fields", function() {
let testInstance = new TestGroup({ location: "remote" }); let testInstance = new TestGroup({ location: "remote" });
await testInstance.init(); testInstance.init();
assert.equal(testInstance._fields.get("enum"), "b"); assert.equal(testInstance._fields.get("enum"), "b");
assert.equal(testInstance._fields.get("priv"), undefined); assert.equal(testInstance._fields.get("priv"), undefined);
}); });
}); });
describe("get name", function() { describe("get name", function() {
it("should give the name of the group", async function() { it("should give the name of the group", function() {
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.init(); testInstance.init();
assert.equal(testInstance.name, "test_group"); assert.equal(testInstance.name, "test_group");
}); });
}); });
describe(".serialize()", function() { describe(".serialize()", function() {
it("should serialize a basic group", async function() { it("should serialize a basic group", function() {
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.init(); testInstance.init();
assert.deepEqual(testInstance.serialize(), { assert.deepEqual(testInstance.serialize(), {
name: "test_group", name: "test_group",
@@ -208,9 +208,9 @@ describe("lib/config/classes", function() {
}, },
}); });
}); });
it("should leave out inaccessible fields", async function() { it("should leave out inaccessible fields", function() {
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.init(); testInstance.init();
assert.deepEqual(testInstance.serialize("remote"), { assert.deepEqual(testInstance.serialize("remote"), {
name: "test_group", name: "test_group",
@@ -226,9 +226,9 @@ describe("lib/config/classes", function() {
}); });
describe(".load()", function() { describe(".load()", function() {
it("should load a basic group", async function() { it("should load a basic group", function() {
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.load({ name: "test_group", fields: { testInstance.load({ name: "test_group", fields: {
enum: "c", enum: "c",
test: "blah", test: "blah",
func: 22, func: 22,
@@ -244,21 +244,21 @@ describe("lib/config/classes", function() {
assert.equal(testInstance.get("priv"), "bar"); assert.equal(testInstance.get("priv"), "bar");
assert.deepEqual(testInstance.get("json"), { valid: true }); assert.deepEqual(testInstance.get("json"), { valid: true });
}); });
it("should load defaults for missing serialized fields", async function() { it("should load defaults for missing serialized fields", function() {
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.load({ name: "test_group", fields: { enum: "a" } }); testInstance.load({ name: "test_group", fields: { enum: "a" } });
assert.equal(testInstance.get("enum"), "a"); assert.equal(testInstance.get("enum"), "a");
assert.equal(testInstance.get("test"), null); assert.equal(testInstance.get("test"), null);
assert.equal(testInstance.get("func"), 42); assert.equal(testInstance.get("func"), 42);
}); });
it("should ignore inaccessible fields", async function() { it("should ignore inaccessible fields", function() {
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.load({ name: "test_group", fields: { priv: "bad" } }, "remote"); testInstance.load({ name: "test_group", fields: { priv: "bad" } }, "remote");
assert.equal(testInstance.get("priv"), null); assert.equal(testInstance.get("priv"), null);
}); });
it("should preserve unknown fields when serialized back", async function() { it("should preserve unknown fields when serialized back", function() {
let testFields = { let testFields = {
enum: "a", enum: "a",
test: "blah", test: "blah",
@@ -272,25 +272,25 @@ describe("lib/config/classes", function() {
}; };
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.load({ name: "test_group", fields: testFields }); testInstance.load({ name: "test_group", fields: testFields });
assert.deepEqual(testInstance.serialize().fields, testFields); assert.deepEqual(testInstance.serialize().fields, testFields);
}); });
}); });
describe(".update()", function() { describe(".update()", function() {
it("should skip updating invalid values", async function() { it("should skip updating invalid values", function() {
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.init(); testInstance.init();
testInstance.update({ name: "test_group", fields: { enum: "wrong", test: 3, func: null }}, false); testInstance.update({ name: "test_group", fields: { enum: "wrong", test: 3, func: null }}, false);
assert.equal(testInstance.get("enum"), "b"); assert.equal(testInstance.get("enum"), "b");
assert.equal(testInstance.get("test"), null); assert.equal(testInstance.get("test"), null);
assert.equal(testInstance.get("func"), 42); assert.equal(testInstance.get("func"), 42);
}); });
it("should skip updating inaccessible fields", async function() { it("should skip updating inaccessible fields", function() {
let testInstance = new TestGroup(mockConfig); let testInstance = new TestGroup(mockConfig);
await testInstance.init(); testInstance.init();
testInstance.update( testInstance.update(
{ name: "test_group", fields: { test: "a", priv: "bad" }}, false, "remote" { name: "test_group", fields: { test: "a", priv: "bad" }}, false, "remote"
); );
@@ -326,9 +326,9 @@ describe("lib/config/classes", function() {
describe(".canAccess()", function() { describe(".canAccess()", function() {
let testInstance; let testInstance;
before(async function() { before(function() {
testInstance = new TestGroup(mockConfig); testInstance = new TestGroup(mockConfig);
await testInstance.load({ name: "test_group", fields: { testInstance.load({ name: "test_group", fields: {
enum: "a", priv: "blah", func: 27, enum: "a", priv: "blah", func: 27,
}}); }});
}); });
@@ -346,9 +346,9 @@ describe("lib/config/classes", function() {
describe(".get()", function() { describe(".get()", function() {
let testInstance; let testInstance;
before(async function() { before(function() {
testInstance = new TestGroup(mockConfig); testInstance = new TestGroup(mockConfig);
await testInstance.load({ name: "test_group", fields: { testInstance.load({ name: "test_group", fields: {
enum: "a", priv: "blah", func: 27, enum: "a", priv: "blah", func: 27,
}}); }});
}); });
@@ -367,9 +367,9 @@ describe("lib/config/classes", function() {
describe(".set()", function() { describe(".set()", function() {
let testInstance; let testInstance;
before(async function() { before(function() {
testInstance = new TestGroup(mockConfig); testInstance = new TestGroup(mockConfig);
await testInstance.load({ name: "test_group", fields: { enum: "a", test: "blah", func: 27 }}); testInstance.load({ name: "test_group", fields: { enum: "a", test: "blah", func: 27 }});
}); });
it("should throw if field does not exist", function() { it("should throw if field does not exist", function() {
@@ -472,9 +472,9 @@ describe("lib/config/classes", function() {
describe(".setProp()", function() { describe(".setProp()", function() {
let testInstance; let testInstance;
before(async function() { before(function() {
testInstance = new TestGroup(mockConfig); testInstance = new TestGroup(mockConfig);
await testInstance.load({ name: "test_group", fields: { testInstance.load({ name: "test_group", fields: {
enum: "a", test: "blah", func: 27, enum: "a", test: "blah", func: 27,
}}); }});
}); });
@@ -588,18 +588,18 @@ describe("lib/config/classes", function() {
}); });
describe(".init()", function() { describe(".init()", function() {
it("should initialize all fields", async function() { it("should initialize all fields", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
assert.equal(testInstance.get("alpha.foo"), null); assert.equal(testInstance.get("alpha.foo"), null);
assert.deepEqual(testInstance.get("beta.bar"), {}); assert.deepEqual(testInstance.get("beta.bar"), {});
}); });
}); });
describe(".serialize()", function() { describe(".serialize()", function() {
it("should serialize a basic config", async function() { it("should serialize a basic config", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
assert.deepEqual(testInstance.serialize(), { assert.deepEqual(testInstance.serialize(), {
groups: [ groups: [
{ {
@@ -616,31 +616,31 @@ describe("lib/config/classes", function() {
}); });
describe(".load()", function() { describe(".load()", function() {
it("should reject on incorrect input passed", async function() { it("should reject on incorrect input passed", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await assert.rejects( assert.throws(
testInstance.load(null), testInstance.load(null),
new Error("Expected object, not null for config") new Error("Expected object, not null for config")
); );
await assert.rejects( assert.throws(
testInstance.load(undefined), testInstance.load(undefined),
new Error("Expected object, not undefined for config") new Error("Expected object, not undefined for config")
); );
await assert.rejects( assert.throws(
testInstance.load({ groups: null }), testInstance.load({ groups: null }),
new Error("Expected groups to be an array, not null") new Error("Expected groups to be an array, not null")
); );
}); });
it("should load defaults for missing serialized groups", async function() { it("should load defaults for missing serialized groups", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.load({ groups: [{ name: "alpha", fields: { foo: "a" }}] }); testInstance.load({ groups: [{ name: "alpha", fields: { foo: "a" }}] });
assert.equal(testInstance.get("alpha.foo"), "a"); assert.equal(testInstance.get("alpha.foo"), "a");
assert.deepEqual(testInstance.get("beta.bar"), {}); assert.deepEqual(testInstance.get("beta.bar"), {});
}); });
it("should preserve unknown groups when serialized back", async function() { it("should preserve unknown groups when serialized back", function() {
let testGroups = [ let testGroups = [
{ {
name: "extra", name: "extra",
@@ -657,16 +657,16 @@ describe("lib/config/classes", function() {
]; ];
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.load({ groups: testGroups }); testInstance.load({ groups: testGroups });
assert.deepEqual(testInstance.serialize().groups, testGroups); assert.deepEqual(testInstance.serialize().groups, testGroups);
}); });
}); });
describe(".update()", function() { describe(".update()", function() {
it("should update a basic config", async function() { it("should update a basic config", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
testInstance.update({ groups: [ testInstance.update({ groups: [
{ {
name: "extra", name: "extra",
@@ -708,48 +708,48 @@ describe("lib/config/classes", function() {
}); });
describe(".canAccess()", function() { describe(".canAccess()", function() {
it("should throw if group does not exist", async function() { it("should throw if group does not exist", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
assert.throws(() => testInstance.canAccess("invalid"), new Error("No config group named 'invalid'")); assert.throws(() => testInstance.canAccess("invalid"), new Error("No config group named 'invalid'"));
}); });
it("should throw if no field is specified", async function() { it("should throw if no field is specified", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
assert.throws(() => testInstance.canAccess("alpha"), new Error("No field named ''")); assert.throws(() => testInstance.canAccess("alpha"), new Error("No field named ''"));
}); });
it("should return true for an accessible field", async function() { it("should return true for an accessible field", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
assert.equal(testInstance.canAccess("alpha.foo"), true); assert.equal(testInstance.canAccess("alpha.foo"), true);
}); });
}); });
describe(".get()", function() { describe(".get()", function() {
it("should throw if group does not exist", async function() { it("should throw if group does not exist", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
assert.throws(() => testInstance.get("invalid"), new Error("No config group named 'invalid'")); assert.throws(() => testInstance.get("invalid"), new Error("No config group named 'invalid'"));
}); });
it("should throw if no field is specified", async function() { it("should throw if no field is specified", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
assert.throws(() => testInstance.get("alpha"), new Error("No field named ''")); assert.throws(() => testInstance.get("alpha"), new Error("No field named ''"));
}); });
}); });
describe(".set()", function() { describe(".set()", function() {
it("should set the value", async function() { it("should set the value", function() {
let testInstance = new TestConfig("local"); let testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
testInstance.set("alpha.foo", "new value"); testInstance.set("alpha.foo", "new value");
assert.equal(testInstance.get("alpha.foo"), "new value"); assert.equal(testInstance.get("alpha.foo"), "new value");
@@ -765,9 +765,9 @@ describe("lib/config/classes", function() {
describe("fieldChanged event", function() { describe("fieldChanged event", function() {
let testInstance; let testInstance;
let called; let called;
beforeEach(async function() { beforeEach(function() {
testInstance = new TestConfig("local"); testInstance = new TestConfig("local");
await testInstance.init(); testInstance.init();
called = false; called = false;
testInstance.once("fieldChanged", (group, field, prev) => { testInstance.once("fieldChanged", (group, field, prev) => {
@@ -777,17 +777,17 @@ describe("lib/config/classes", function() {
}); });
}); });
it("should be called when setting a field", async function() { it("should be called when setting a field", function() {
testInstance.set("beta.bar", { value: 1 }); testInstance.set("beta.bar", { value: 1 });
assert(called, "fieldChanged was not called"); assert(called, "fieldChanged was not called");
}); });
it("should be called when updating a config", async function() { it("should be called when updating a config", function() {
testInstance.update({ groups: [{ name: "beta", fields: { bar: { value: 1 }}}]}, true); testInstance.update({ groups: [{ name: "beta", fields: { bar: { value: 1 }}}]}, true);
assert(called, "fieldChanged was not called"); assert(called, "fieldChanged was not called");
}); });
it("should be called when setting a prop", async function() { it("should be called when setting a prop", function() {
testInstance.setProp("beta.bar", "value", 2); testInstance.setProp("beta.bar", "value", 2);
assert(called, "fieldChanged was not called"); assert(called, "fieldChanged was not called");
}); });