mirror of
https://github.com/atom/atom.git
synced 2026-01-22 13:28:01 -05:00
Return a cloned object from config.get()
This prevents mutations to the values of the default settings.
This commit is contained in:
@@ -48,11 +48,6 @@ the following way:
|
||||
```coffeescript
|
||||
# basic key update
|
||||
config.set("core.autosave", true)
|
||||
|
||||
# if you mutate a config key, you'll need to call `config.update` to inform
|
||||
# observers of the change
|
||||
config.get("fuzzyFinder.ignoredPaths").push "vendor"
|
||||
config.update()
|
||||
```
|
||||
|
||||
You can also use `setDefaults`, which will assign default values for keys that
|
||||
|
||||
@@ -8,6 +8,13 @@ describe "Config", ->
|
||||
expect(config.get("foo.bar.baz")).toBe 42
|
||||
expect(config.get("bogus.key.path")).toBeUndefined()
|
||||
|
||||
it "returns a deep clone of the key path's value", ->
|
||||
config.set('value', array: [1, b: 2, 3])
|
||||
retrievedValue = config.get('value')
|
||||
retrievedValue.array[0] = 4
|
||||
retrievedValue.array[1].b = 2.1
|
||||
expect(config.get('value')).toEqual(array: [1, b: 2, 3])
|
||||
|
||||
describe ".set(keyPath, value)", ->
|
||||
it "allows a key path's value to be written", ->
|
||||
expect(config.set("foo.bar.baz", 42)).toBe 42
|
||||
@@ -93,21 +100,6 @@ describe "Config", ->
|
||||
expect(config.get("foo.quux.x")).toBe 0
|
||||
expect(config.get("foo.quux.y")).toBe 1
|
||||
|
||||
describe ".update()", ->
|
||||
it "updates observers if a value is mutated without the use of .set", ->
|
||||
config.set("foo.bar.baz", ["a"])
|
||||
observeHandler = jasmine.createSpy "observeHandler"
|
||||
config.observe "foo.bar.baz", observeHandler
|
||||
observeHandler.reset()
|
||||
|
||||
config.get("foo.bar.baz").push("b")
|
||||
config.update()
|
||||
expect(observeHandler).toHaveBeenCalledWith config.get("foo.bar.baz")
|
||||
observeHandler.reset()
|
||||
|
||||
config.update()
|
||||
expect(observeHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe ".observe(keyPath)", ->
|
||||
observeHandler = null
|
||||
|
||||
|
||||
@@ -180,8 +180,9 @@ describe "Project", ->
|
||||
|
||||
it "ignores ignored.txt file", ->
|
||||
paths = null
|
||||
config.get("core.ignoredNames").push("ignored.txt")
|
||||
config.update()
|
||||
ignoredNames = config.get("core.ignoredNames")
|
||||
ignoredNames.push("ignored.txt")
|
||||
config.set("core.ignoredNames", ignoredNames)
|
||||
waitsForPromise ->
|
||||
project.getFilePaths().done (foundPaths) -> paths = foundPaths
|
||||
|
||||
|
||||
@@ -106,8 +106,8 @@ class Config
|
||||
# Returns the value from Atom's default settings, the user's configuration file,
|
||||
# or `null` if the key doesn't exist in either.
|
||||
get: (keyPath) ->
|
||||
_.valueForKeyPath(@settings, keyPath) ?
|
||||
_.valueForKeyPath(@defaultSettings, keyPath)
|
||||
value = _.valueForKeyPath(@settings, keyPath) ? _.valueForKeyPath(@defaultSettings, keyPath)
|
||||
_.deepClone(value)
|
||||
|
||||
# Retrieves the setting for the given key as an integer.
|
||||
#
|
||||
|
||||
@@ -29,11 +29,12 @@ class PackageConfigPanel extends ConfigPanel
|
||||
@on 'change', '#packages input[type=checkbox]', (e) ->
|
||||
checkbox = $(e.target)
|
||||
name = checkbox.closest('tr').attr('name')
|
||||
disabledPackages = config.get('core.disabledPackages')
|
||||
if checkbox.attr('checked')
|
||||
_.remove(config.get('core.disabledPackages'), name)
|
||||
_.remove(disabledPackages, name)
|
||||
else
|
||||
config.get('core.disabledPackages').push(name)
|
||||
config.update()
|
||||
disabledPackages.push(name)
|
||||
config.set('core.disabledPackages', disabledPackages)
|
||||
|
||||
@observeConfig 'core.disabledPackages', (disabledPackages) =>
|
||||
@packageTableBody.find("input[type='checkbox']").attr('checked', true)
|
||||
|
||||
@@ -126,6 +126,35 @@ _.mixin
|
||||
endsWith: (string, suffix) ->
|
||||
string.indexOf(suffix, string.length - suffix.length) isnt -1
|
||||
|
||||
# Transform the given object into another object.
|
||||
#
|
||||
# `object` - The object to transform.
|
||||
# `iterator` -
|
||||
# A function that takes `(key, value)` arguments and returns a
|
||||
# `[key, value]` tuple.
|
||||
#
|
||||
# Returns a new object based with the key/values returned by the iterator.
|
||||
mapObject: (object, iterator) ->
|
||||
newObject = {}
|
||||
for key, value of object
|
||||
[key, value] = iterator(key, value)
|
||||
newObject[key] = value
|
||||
|
||||
newObject
|
||||
|
||||
# Deep clones the given JSON object.
|
||||
#
|
||||
# `object` - The JSON object to clone.
|
||||
#
|
||||
# Returns a deep clone of the JSON object.
|
||||
deepClone: (object) ->
|
||||
if _.isArray(object)
|
||||
object.map (value) -> _.deepClone(value)
|
||||
else if _.isObject(object)
|
||||
@mapObject object, (key, value) => [key, @deepClone(value)]
|
||||
else
|
||||
object
|
||||
|
||||
valueForKeyPath: (object, keyPath) ->
|
||||
keys = keyPath.split('.')
|
||||
for key in keys
|
||||
|
||||
Reference in New Issue
Block a user