Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit 9315802

Browse files
author
Wliu
authored
Merge pull request #974 from atom/wl-settings-validation
Validate settings
2 parents 594c12f + 04248bf commit 9315802

2 files changed

Lines changed: 79 additions & 14 deletions

File tree

lib/settings-panel.js

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,22 @@ export default class SettingsPanel extends CollapsibleSectionPanel {
197197
}
198198
}
199199

200+
setText (editor, name, type, value) {
201+
let stringValue
202+
if (this.isDefault(name)) {
203+
stringValue = ''
204+
} else {
205+
stringValue = this.valueToString(value) || ''
206+
}
207+
208+
if (stringValue === editor.getText() || _.isEqual(value, this.parseValue(type, editor.getText()))) {
209+
return
210+
}
211+
212+
editor.setText(stringValue)
213+
editor.moveToEndOfLine()
214+
}
215+
200216
bindSelectFields () {
201217
const disposables = Array.from(this.element.querySelectorAll('select[id]')).map((select) => {
202218
const name = select.id
@@ -213,7 +229,6 @@ export default class SettingsPanel extends CollapsibleSectionPanel {
213229

214230
bindEditors() {
215231
const disposables = Array.from(this.element.querySelectorAll('atom-text-editor')).map((editorElement) => {
216-
let left
217232
let editor = editorElement.getModel()
218233
let name = editorElement.id
219234
let type = editorElement.getAttribute('type')
@@ -242,22 +257,21 @@ export default class SettingsPanel extends CollapsibleSectionPanel {
242257
subscriptions.add(new Disposable(() => editorElement.removeEventListener('blur', blurHandler)))
243258

244259
this.observe(name, (value) => {
245-
let stringValue
246-
if (this.isDefault(name)) {
247-
stringValue = ''
248-
} else {
249-
stringValue = (left = this.valueToString(value)) != null ? left : ''
250-
}
251-
252-
if (stringValue === editor.getText() || _.isEqual(value, this.parseValue(type, editor.getText()))) {
253-
return
254-
}
255-
256-
editor.setText(stringValue)
260+
this.setText(editor, name, type, value)
257261
})
258262

259263
subscriptions.add(editor.onDidStopChanging(() => {
260-
this.set(name, this.parseValue(type, editor.getText()))
264+
const {minimum, maximum} = atom.config.getSchema(name)
265+
const value = this.parseValue(type, editor.getText())
266+
if (minimum != null && value < minimum) {
267+
this.set(name, minimum)
268+
this.setText(editor, name, type, minimum)
269+
} else if (maximum != null && value > maximum) {
270+
this.set(name, maximum)
271+
this.setText(editor, name, type, maximum)
272+
} else if (!this.set(name, value)) {
273+
this.setText(editor, name, type, atom.config.get(name))
274+
}
261275
}))
262276

263277
return subscriptions

spec/settings-panel-spec.coffee

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,54 @@ describe "SettingsPanel", ->
214214
expect(controlGroups[1].querySelector('.sub-section .sub-section-heading').classList.contains('has-items')).toBe true
215215
# Should be already collapsed
216216
expect(controlGroups[1].querySelector('.sub-section .sub-section-heading').parentElement.classList.contains('collapsed')).toBe true
217+
218+
describe 'settings validation', ->
219+
beforeEach ->
220+
config =
221+
type: 'object'
222+
properties:
223+
minMax:
224+
name: 'minMax'
225+
title: 'Min max'
226+
description: 'The minMax setting'
227+
type: 'integer'
228+
default: 10
229+
minimum: 1
230+
maximum: 100
231+
232+
atom.config.setSchema('foo', config)
233+
settingsPanel = new SettingsPanel({namespace: 'foo', includeTitle: false})
234+
235+
it 'prevents setting a value below the minimum', ->
236+
minMaxEditor = settingsPanel.element.querySelector('[id="foo.minMax"]')
237+
minMaxEditor.getModel().setText('0')
238+
advanceClock(minMaxEditor.getModel().getBuffer().getStoppedChangingDelay())
239+
expect(minMaxEditor.getModel().getText()).toBe '1'
240+
241+
minMaxEditor.getModel().setText('-5')
242+
advanceClock(minMaxEditor.getModel().getBuffer().getStoppedChangingDelay())
243+
expect(minMaxEditor.getModel().getText()).toBe '1'
244+
245+
it 'prevents setting a value above the maximum', ->
246+
minMaxEditor = settingsPanel.element.querySelector('[id="foo.minMax"]')
247+
minMaxEditor.getModel().setText('1000')
248+
advanceClock(minMaxEditor.getModel().getBuffer().getStoppedChangingDelay())
249+
expect(minMaxEditor.getModel().getText()).toBe '100'
250+
251+
minMaxEditor.getModel().setText('10000')
252+
advanceClock(minMaxEditor.getModel().getBuffer().getStoppedChangingDelay())
253+
expect(minMaxEditor.getModel().getText()).toBe '100'
254+
255+
it 'prevents setting a value that cannot be coerced to the correct type', ->
256+
minMaxEditor = settingsPanel.element.querySelector('[id="foo.minMax"]')
257+
minMaxEditor.getModel().setText('"abcde"')
258+
advanceClock(minMaxEditor.getModel().getBuffer().getStoppedChangingDelay())
259+
expect(minMaxEditor.getModel().getText()).toBe '' # aka default
260+
261+
minMaxEditor.getModel().setText('15')
262+
advanceClock(minMaxEditor.getModel().getBuffer().getStoppedChangingDelay())
263+
expect(minMaxEditor.getModel().getText()).toBe '15'
264+
265+
minMaxEditor.getModel().setText('"abcde"')
266+
advanceClock(minMaxEditor.getModel().getBuffer().getStoppedChangingDelay())
267+
expect(minMaxEditor.getModel().getText()).toBe '15'

0 commit comments

Comments
 (0)