From 0fc773c1fc2c02b8da103dca732752750c6827fd Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Wed, 24 Sep 2014 17:13:01 -0700 Subject: [PATCH] Warn when loading bogus values from the user's config --- spec/config-spec.coffee | 32 ++++++++++++++++++++++++++++++++ src/config.coffee | 21 ++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/spec/config-spec.coffee b/spec/config-spec.coffee index 8a5c04a00..f17fc47f7 100644 --- a/spec/config-spec.coffee +++ b/spec/config-spec.coffee @@ -360,6 +360,38 @@ describe "Config", -> expect(fs.existsSync(atom.config.configFilePath)).toBe true expect(CSON.readFileSync(atom.config.configFilePath)).toEqual {} + describe "when a schema is specified", -> + beforeEach -> + schema = + type: 'object' + properties: + bar: + type: 'string' + default: 'def' + int: + type: 'integer' + default: 12 + + atom.config.setSchema('foo', schema) + + describe "when the config file contains values that do not adhere to the schema", -> + warnSpy = null + beforeEach -> + warnSpy = spyOn console, 'warn' + fs.writeFileSync atom.config.configFilePath, """ + foo: + bar: 'baz' + int: 'bad value' + """ + atom.config.loadUserConfig() + + it "updates the config data based on the file contents", -> + expect(atom.config.get("foo.bar")).toBe 'baz' + expect(atom.config.get("foo.int")).toBe 12 + + expect(warnSpy).toHaveBeenCalled() + expect(warnSpy.mostRecentCall.args[0]).toContain "'foo.int' could not be set" + describe ".observeUserConfig()", -> updatedHandler = null diff --git a/src/config.coffee b/src/config.coffee index f67a63232..50ae711a4 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -284,7 +284,7 @@ class Config try userConfig = CSON.readFileSync(@configFilePath) - _.extend(@settings, userConfig) + @setAllRecursive(userConfig) @configFileHasErrors = false @emit 'updated' @emitter.emit 'did-change' @@ -314,6 +314,22 @@ class Config save: -> CSON.writeFileSync(@configFilePath, @settings) + setAllRecursive: (value) -> + @setRecursive(key, childValue) for key, childValue of value + return + + setRecursive: (keyPath, value) -> + if value? and isPlainObject(value) + keys = keyPath.split('.') + for key, childValue of value + continue unless value.hasOwnProperty(key) + @setRecursive(keys.concat([key]).join('.'), childValue) + else + unless @set(keyPath, value) + console.warn("'#{keyPath}' could not be set. Attempted value: #{JSON.stringify(value)}; Schema: #{JSON.stringify(@getSchema(keyPath))}") + + return + setDefaults: (keyPath, defaults) -> if typeof defaults isnt 'object' return _.setValueForKeyPath(@defaultSettings, keyPath, defaults) @@ -446,3 +462,6 @@ Config.addSchemaValidators return value if _.isEqual(possibleValue, value) throw new Error('Value is not one of the possible values') + +isPlainObject = (value) -> + _.isObject(value) and not _.isArray(value) and not _.isFunction(value) and not _.isString(value)