12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483 |
- describe('Config', () => {
- let savedSettings;
- beforeEach(() => {
- spyOn(console, 'warn');
- atom.config.settingsLoaded = true;
- savedSettings = [];
- atom.config.saveCallback = function (settings) {
- savedSettings.push(settings);
- };
- });
- describe('.get(keyPath, {scope, sources, excludeSources})', () => {
- it("allows a key path's value to be read", () => {
- expect(atom.config.set('foo.bar.baz', 42)).toBe(true);
- expect(atom.config.get('foo.bar.baz')).toBe(42);
- expect(atom.config.get('foo.quux')).toBeUndefined();
- });
- it("returns a deep clone of the key path's value", () => {
- atom.config.set('value', { array: [1, { b: 2 }, 3] });
- const retrievedValue = atom.config.get('value');
- retrievedValue.array[0] = 4;
- retrievedValue.array[1].b = 2.1;
- expect(atom.config.get('value')).toEqual({ array: [1, { b: 2 }, 3] });
- });
- it('merges defaults into the returned value if both the assigned value and the default value are objects', () => {
- atom.config.setDefaults('foo.bar', { baz: 1, ok: 2 });
- atom.config.set('foo.bar', { baz: 3 });
- expect(atom.config.get('foo.bar')).toEqual({ baz: 3, ok: 2 });
- atom.config.setDefaults('other', { baz: 1 });
- atom.config.set('other', 7);
- expect(atom.config.get('other')).toBe(7);
- atom.config.set('bar.baz', { a: 3 });
- atom.config.setDefaults('bar', { baz: 7 });
- expect(atom.config.get('bar.baz')).toEqual({ a: 3 });
- });
- describe("when a 'sources' option is specified", () => {
- afterEach(() => {
- atom.project.replace(null);
- });
- it('only retrieves values from the specified sources', () => {
- atom.config.set('x.y', 1, { scopeSelector: '.foo', source: 'a' });
- atom.config.set('x.y', 2, { scopeSelector: '.foo', source: 'b' });
- atom.config.set('x.y', 3, { scopeSelector: '.foo', source: 'c' });
- atom.config.setSchema('x.y', { type: 'integer', default: 4 });
- expect(
- atom.config.get('x.y', { sources: ['a'], scope: ['.foo'] })
- ).toBe(1);
- expect(
- atom.config.get('x.y', { sources: ['b'], scope: ['.foo'] })
- ).toBe(2);
- expect(
- atom.config.get('x.y', { sources: ['c'], scope: ['.foo'] })
- ).toBe(3);
- // Schema defaults never match a specific source. We could potentially add a special "schema" source.
- expect(
- atom.config.get('x.y', { sources: ['x'], scope: ['.foo'] })
- ).toBeUndefined();
- expect(
- atom.config.get(null, { sources: ['a'], scope: ['.foo'] }).x.y
- ).toBe(1);
- })
- it(`ignores project-specific settings unless specified in the "sources" option`, () => {
- atom.config.set('x.y', 1);
- atom.config.set('u.v', 5);
- atom.project.replace({
- originPath: 'TEST',
- paths: atom.project.getPaths(),
- config: {
- "*": {
- "x": {
- "y": 4
- }
- }
- }
- });
- expect(
- atom.config.get('x.y', { sources: [atom.config.mainSource] })
- ).toBe(1);
- expect(
- atom.config.get('x.y', { sources: [atom.config.mainSource, atom.config.projectFile] })
- ).toBe(4);
- expect(
- atom.config.get('x.y', { sources: [atom.config.projectFile] })
- ).toBe(4);
- expect(
- atom.config.get('u.v', {
- sources: [atom.config.projectFile],
- excludeSources: [atom.config.mainSource]
- })
- ).toBeUndefined();
- });
- });
- describe("when an 'excludeSources' option is specified", () => {
- afterEach(() => {
- atom.project.replace(null);
- });
- it('only retrieves values from the specified sources', () => {
- atom.config.set('x.y', 0);
- atom.config.set('x.y', 1, { scopeSelector: '.foo', source: 'a' });
- atom.config.set('x.y', 2, { scopeSelector: '.foo', source: 'b' });
- atom.config.set('x.y', 3, { scopeSelector: '.foo', source: 'c' });
- atom.config.setSchema('x.y', { type: 'integer', default: 4 });
- expect(
- atom.config.get('x.y', { excludeSources: ['a'], scope: ['.foo'] })
- ).toBe(3);
- expect(
- atom.config.get('x.y', { excludeSources: ['c'], scope: ['.foo'] })
- ).toBe(2);
- expect(
- atom.config.get('x.y', {
- excludeSources: ['b', 'c'],
- scope: ['.foo']
- })
- ).toBe(1);
- expect(
- atom.config.get('x.y', {
- excludeSources: ['b', 'c', 'a'],
- scope: ['.foo']
- })
- ).toBe(0);
- expect(
- atom.config.get('x.y', {
- excludeSources: ['b', 'c', 'a', atom.config.getUserConfigPath()],
- scope: ['.foo']
- })
- ).toBe(4);
- expect(
- atom.config.get('x.y', {
- excludeSources: [atom.config.getUserConfigPath()]
- })
- ).toBe(4);
- });
- it("merges project-specific settings with other settings when the keypath is an object", () => {
- atom.config.set('x.y', 1);
- atom.config.set('x.z', "fibrinolysis");
- atom.project.replace({
- originPath: 'TEST',
- paths: atom.project.getPaths(),
- config: {
- "*": {
- "x": {
- "y": 4
- }
- }
- }
- });
- // Project-specific settings work fine, as the spec below shows, when
- // the value being retrieved is a primitive. But until recently, Pulsar
- // didn't know what to do if the value being retrieved was an object.
- //
- // Imagine asking for _all_ config settings. The non-project-specific
- // lookup returns everything. The project-specific lookup returns only
- // a few overrides. Pulsar needs to _blend_ these two objects, but was
- // previously choosing the project-specific lookup just because it
- // wasn't undefined.
- // Here we demonstrate that it now retrieves an object for the given
- // key path at the normal location and applies a project-specific
- // “patch…”
- expect(atom.config.get('x')).toEqual({ y: 4, z: "fibrinolysis" })
- // …without any general settings leaking into the project config.
- expect(atom.config.projectSettings.x.z).toBeUndefined();
- });
- it("ignores the project-specific source when 'excludeSources' tells it to", () => {
- atom.config.set('x.y', 1);
- atom.project.replace({
- originPath: 'TEST',
- paths: atom.project.getPaths(),
- config: {
- "*": {
- "x": {
- "y": 4
- }
- }
- }
- });
- expect( atom.config.get('x.y') ).toBe(4);
- expect(
- atom.config.get('x.y', { excludeSources: [atom.config.projectFile] })
- ).toBe(1);
- });
- });
- describe("when a 'scope' option is given", () => {
- it('returns the property with the most specific scope selector', () => {
- atom.config.set('foo.bar.baz', 42, {
- scopeSelector: '.source.coffee .string.quoted.double.coffee'
- });
- atom.config.set('foo.bar.baz', 22, {
- scopeSelector: '.source .string.quoted.double'
- });
- atom.config.set('foo.bar.baz', 11, { scopeSelector: '.source' });
- expect(
- atom.config.get('foo.bar.baz', {
- scope: ['.source.coffee', '.string.quoted.double.coffee']
- })
- ).toBe(42);
- expect(
- atom.config.get('foo.bar.baz', {
- scope: ['.source.js', '.string.quoted.double.js']
- })
- ).toBe(22);
- expect(
- atom.config.get('foo.bar.baz', {
- scope: ['.source.js', '.variable.assignment.js']
- })
- ).toBe(11);
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.text'] })
- ).toBeUndefined();
- });
- it('favors the most recently added properties in the event of a specificity tie', () => {
- atom.config.set('foo.bar.baz', 42, {
- scopeSelector: '.source.coffee .string.quoted.single'
- });
- atom.config.set('foo.bar.baz', 22, {
- scopeSelector: '.source.coffee .string.quoted.double'
- });
- expect(
- atom.config.get('foo.bar.baz', {
- scope: ['.source.coffee', '.string.quoted.single']
- })
- ).toBe(42);
- expect(
- atom.config.get('foo.bar.baz', {
- scope: ['.source.coffee', '.string.quoted.single.double']
- })
- ).toBe(22);
- });
- describe('when there are global defaults', () =>
- it('falls back to the global when there is no scoped property specified', () => {
- atom.config.setDefaults('foo', { hasDefault: 'ok' });
- expect(
- atom.config.get('foo.hasDefault', {
- scope: ['.source.coffee', '.string.quoted.single']
- })
- ).toBe('ok');
- }));
- describe('when package settings are added after user settings', () =>
- it("returns the user's setting because the user's setting has higher priority", () => {
- atom.config.set('foo.bar.baz', 100, {
- scopeSelector: '.source.coffee'
- });
- atom.config.set('foo.bar.baz', 1, {
- scopeSelector: '.source.coffee',
- source: 'some-package'
- });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(100);
- }));
- });
- });
- describe('.getAll(keyPath, {scope, sources, excludeSources})', () => {
- it('reads all of the values for a given key-path', () => {
- expect(atom.config.set('foo', 41)).toBe(true);
- expect(atom.config.set('foo', 43, { scopeSelector: '.a .b' })).toBe(true);
- expect(atom.config.set('foo', 42, { scopeSelector: '.a' })).toBe(true);
- expect(atom.config.set('foo', 44, { scopeSelector: '.a .b.c' })).toBe(
- true
- );
- expect(atom.config.set('foo', -44, { scopeSelector: '.d' })).toBe(true);
- expect(atom.config.getAll('foo', { scope: ['.a', '.b.c'] })).toEqual([
- { scopeSelector: '.a .b.c', value: 44 },
- { scopeSelector: '.a .b', value: 43 },
- { scopeSelector: '.a', value: 42 },
- { scopeSelector: '*', value: 41 }
- ]);
- });
- it("includes the schema's default value", () => {
- atom.config.setSchema('foo', { type: 'number', default: 40 });
- expect(atom.config.set('foo', 43, { scopeSelector: '.a .b' })).toBe(true);
- expect(atom.config.getAll('foo', { scope: ['.a', '.b.c'] })).toEqual([
- { scopeSelector: '.a .b', value: 43 },
- { scopeSelector: '*', value: 40 }
- ]);
- });
- });
- describe('.set(keyPath, value, {source, scopeSelector})', () => {
- it("allows a key path's value to be written", () => {
- expect(atom.config.set('foo.bar.baz', 42)).toBe(true);
- expect(atom.config.get('foo.bar.baz')).toBe(42);
- });
- it("saves the user's config to disk after it stops changing", () => {
- atom.config.set('foo.bar.baz', 42);
- expect(savedSettings.length).toBe(0);
- atom.config.set('foo.bar.baz', 43);
- expect(savedSettings.length).toBe(0);
- atom.config.set('foo.bar.baz', 44);
- advanceClock(10);
- expect(savedSettings.length).toBe(1);
- });
- it("does not save when a non-default 'source' is given", () => {
- atom.config.set('foo.bar.baz', 42, {
- source: 'some-other-source',
- scopeSelector: '.a'
- });
- advanceClock(500);
- expect(savedSettings.length).toBe(0);
- });
- it("does not allow a 'source' option without a 'scopeSelector'", () => {
- expect(() =>
- atom.config.set('foo', 1, { source: ['.source.ruby'] })
- ).toThrow();
- });
- describe('when the key-path is null', () =>
- it('sets the root object', () => {
- expect(atom.config.set(null, { editor: { tabLength: 6 } })).toBe(true);
- expect(atom.config.get('editor.tabLength')).toBe(6);
- expect(
- atom.config.set(null, {
- editor: { tabLength: 8, scopeSelector: ['.source.js'] }
- })
- ).toBe(true);
- expect(
- atom.config.get('editor.tabLength', { scope: ['.source.js'] })
- ).toBe(8);
- }));
- describe('when the value equals the default value', () =>
- it("does not store the value in the user's config", () => {
- atom.config.setSchema('foo', {
- type: 'object',
- properties: {
- same: {
- type: 'number',
- default: 1
- },
- changes: {
- type: 'number',
- default: 1
- },
- sameArray: {
- type: 'array',
- default: [1, 2, 3]
- },
- sameObject: {
- type: 'object',
- default: { a: 1, b: 2 }
- },
- null: {
- type: '*',
- default: null
- },
- undefined: {
- type: '*',
- default: undefined
- }
- }
- });
- expect(atom.config.settings.foo).toBeUndefined();
- atom.config.set('foo.same', 1);
- atom.config.set('foo.changes', 2);
- atom.config.set('foo.sameArray', [1, 2, 3]);
- atom.config.set('foo.null', undefined);
- atom.config.set('foo.undefined', null);
- atom.config.set('foo.sameObject', { b: 2, a: 1 });
- const userConfigPath = atom.config.getUserConfigPath();
- expect(
- atom.config.get('foo.same', { sources: [userConfigPath] })
- ).toBeUndefined();
- expect(atom.config.get('foo.changes')).toBe(2);
- expect(
- atom.config.get('foo.changes', { sources: [userConfigPath] })
- ).toBe(2);
- atom.config.set('foo.changes', 1);
- expect(
- atom.config.get('foo.changes', { sources: [userConfigPath] })
- ).toBeUndefined();
- }));
- describe("when a 'scopeSelector' is given", () =>
- it('sets the value and overrides the others', () => {
- atom.config.set('foo.bar.baz', 42, {
- scopeSelector: '.source.coffee .string.quoted.double.coffee'
- });
- atom.config.set('foo.bar.baz', 22, {
- scopeSelector: '.source .string.quoted.double'
- });
- atom.config.set('foo.bar.baz', 11, { scopeSelector: '.source' });
- expect(
- atom.config.get('foo.bar.baz', {
- scope: ['.source.coffee', '.string.quoted.double.coffee']
- })
- ).toBe(42);
- expect(
- atom.config.set('foo.bar.baz', 100, {
- scopeSelector: '.source.coffee .string.quoted.double.coffee'
- })
- ).toBe(true);
- expect(
- atom.config.get('foo.bar.baz', {
- scope: ['.source.coffee', '.string.quoted.double.coffee']
- })
- ).toBe(100);
- }));
- });
- describe('.unset(keyPath, {source, scopeSelector})', () => {
- beforeEach(() =>
- atom.config.setSchema('foo', {
- type: 'object',
- properties: {
- bar: {
- type: 'object',
- properties: {
- baz: {
- type: 'integer',
- default: 0
- },
- ok: {
- type: 'integer',
- default: 0
- }
- }
- },
- quux: {
- type: 'integer',
- default: 0
- }
- }
- })
- );
- it('sets the value of the key path to its default', () => {
- atom.config.setDefaults('a', { b: 3 });
- atom.config.set('a.b', 4);
- expect(atom.config.get('a.b')).toBe(4);
- atom.config.unset('a.b');
- expect(atom.config.get('a.b')).toBe(3);
- atom.config.set('a.c', 5);
- expect(atom.config.get('a.c')).toBe(5);
- atom.config.unset('a.c');
- expect(atom.config.get('a.c')).toBeUndefined();
- });
- it('calls ::save()', () => {
- atom.config.setDefaults('a', { b: 3 });
- atom.config.set('a.b', 4);
- savedSettings.length = 0;
- atom.config.unset('a.c');
- advanceClock(500);
- expect(savedSettings.length).toBe(1);
- });
- describe("when no 'scopeSelector' is given", () => {
- describe("when a 'source' but no key-path is given", () =>
- it('removes all scoped settings with the given source', () => {
- atom.config.set('foo.bar.baz', 1, {
- scopeSelector: '.a',
- source: 'source-a'
- });
- atom.config.set('foo.bar.quux', 2, {
- scopeSelector: '.b',
- source: 'source-a'
- });
- expect(atom.config.get('foo.bar', { scope: ['.a.b'] })).toEqual({
- baz: 1,
- quux: 2
- });
- atom.config.unset(null, { source: 'source-a' });
- expect(atom.config.get('foo.bar', { scope: ['.a'] })).toEqual({
- baz: 0,
- ok: 0
- });
- }));
- describe("when a 'source' and a key-path is given", () =>
- it('removes all scoped settings with the given source and key-path', () => {
- atom.config.set('foo.bar.baz', 1);
- atom.config.set('foo.bar.baz', 2, {
- scopeSelector: '.a',
- source: 'source-a'
- });
- atom.config.set('foo.bar.baz', 3, {
- scopeSelector: '.a.b',
- source: 'source-b'
- });
- expect(atom.config.get('foo.bar.baz', { scope: ['.a.b'] })).toEqual(
- 3
- );
- atom.config.unset('foo.bar.baz', { source: 'source-b' });
- expect(atom.config.get('foo.bar.baz', { scope: ['.a.b'] })).toEqual(
- 2
- );
- expect(atom.config.get('foo.bar.baz')).toEqual(1);
- }));
- describe("when no 'source' is given", () =>
- it('removes all scoped and unscoped properties for that key-path', () => {
- atom.config.setDefaults('foo.bar', { baz: 100 });
- atom.config.set(
- 'foo.bar',
- { baz: 1, ok: 2 },
- { scopeSelector: '.a' }
- );
- atom.config.set(
- 'foo.bar',
- { baz: 11, ok: 12 },
- { scopeSelector: '.b' }
- );
- atom.config.set('foo.bar', { baz: 21, ok: 22 });
- atom.config.unset('foo.bar.baz');
- expect(atom.config.get('foo.bar.baz', { scope: ['.a'] })).toBe(100);
- expect(atom.config.get('foo.bar.baz', { scope: ['.b'] })).toBe(100);
- expect(atom.config.get('foo.bar.baz')).toBe(100);
- expect(atom.config.get('foo.bar.ok', { scope: ['.a'] })).toBe(2);
- expect(atom.config.get('foo.bar.ok', { scope: ['.b'] })).toBe(12);
- expect(atom.config.get('foo.bar.ok')).toBe(22);
- }));
- });
- describe("when a 'scopeSelector' is given", () => {
- it('restores the global default when no scoped default set', () => {
- atom.config.setDefaults('foo', { bar: { baz: 10 } });
- atom.config.set('foo.bar.baz', 55, { scopeSelector: '.source.coffee' });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(55);
- atom.config.unset('foo.bar.baz', { scopeSelector: '.source.coffee' });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(10);
- });
- it('restores the scoped default when a scoped default is set', () => {
- atom.config.setDefaults('foo', { bar: { baz: 10 } });
- atom.config.set('foo.bar.baz', 42, {
- scopeSelector: '.source.coffee',
- source: 'some-source'
- });
- atom.config.set('foo.bar.baz', 55, { scopeSelector: '.source.coffee' });
- atom.config.set('foo.bar.ok', 100, { scopeSelector: '.source.coffee' });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(55);
- atom.config.unset('foo.bar.baz', { scopeSelector: '.source.coffee' });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(42);
- expect(
- atom.config.get('foo.bar.ok', { scope: ['.source.coffee'] })
- ).toBe(100);
- });
- it('calls ::save()', () => {
- atom.config.setDefaults('foo', { bar: { baz: 10 } });
- atom.config.set('foo.bar.baz', 55, { scopeSelector: '.source.coffee' });
- savedSettings.length = 0;
- atom.config.unset('foo.bar.baz', { scopeSelector: '.source.coffee' });
- advanceClock(150);
- expect(savedSettings.length).toBe(1);
- });
- it('allows removing settings for a specific source and scope selector', () => {
- atom.config.set('foo.bar.baz', 55, {
- scopeSelector: '.source.coffee',
- source: 'source-a'
- });
- atom.config.set('foo.bar.baz', 65, {
- scopeSelector: '.source.coffee',
- source: 'source-b'
- });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(65);
- atom.config.unset('foo.bar.baz', {
- source: 'source-b',
- scopeSelector: '.source.coffee'
- });
- expect(
- atom.config.get('foo.bar.baz', {
- scope: ['.source.coffee', '.string']
- })
- ).toBe(55);
- });
- it('allows removing all settings for a specific source', () => {
- atom.config.set('foo.bar.baz', 55, {
- scopeSelector: '.source.coffee',
- source: 'source-a'
- });
- atom.config.set('foo.bar.baz', 65, {
- scopeSelector: '.source.coffee',
- source: 'source-b'
- });
- atom.config.set('foo.bar.ok', 65, {
- scopeSelector: '.source.coffee',
- source: 'source-b'
- });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(65);
- atom.config.unset(null, {
- source: 'source-b',
- scopeSelector: '.source.coffee'
- });
- expect(
- atom.config.get('foo.bar.baz', {
- scope: ['.source.coffee', '.string']
- })
- ).toBe(55);
- expect(
- atom.config.get('foo.bar.ok', {
- scope: ['.source.coffee', '.string']
- })
- ).toBe(0);
- });
- it('does not call ::save or add a scoped property when no value has been set', () => {
- // see https://github.com/atom/atom/issues/4175
- atom.config.setDefaults('foo', { bar: { baz: 10 } });
- atom.config.unset('foo.bar.baz', { scopeSelector: '.source.coffee' });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(10);
- expect(savedSettings.length).toBe(0);
- const scopedProperties = atom.config.scopedSettingsStore.propertiesForSource(
- 'user-config'
- );
- expect(scopedProperties['.coffee.source']).toBeUndefined();
- });
- it('removes the scoped value when it was the only set value on the object', () => {
- atom.config.setDefaults('foo', { bar: { baz: 10 } });
- atom.config.set('foo.bar.baz', 55, { scopeSelector: '.source.coffee' });
- atom.config.set('foo.bar.ok', 20, { scopeSelector: '.source.coffee' });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(55);
- advanceClock(150);
- savedSettings.length = 0;
- atom.config.unset('foo.bar.baz', { scopeSelector: '.source.coffee' });
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(10);
- expect(
- atom.config.get('foo.bar.ok', { scope: ['.source.coffee'] })
- ).toBe(20);
- advanceClock(150);
- expect(savedSettings[0]['.coffee.source']).toEqual({
- foo: {
- bar: {
- ok: 20
- }
- }
- });
- atom.config.unset('foo.bar.ok', { scopeSelector: '.source.coffee' });
- advanceClock(150);
- expect(savedSettings.length).toBe(2);
- expect(savedSettings[1]['.coffee.source']).toBeUndefined();
- });
- it('does not call ::save when the value is already at the default', () => {
- atom.config.setDefaults('foo', { bar: { baz: 10 } });
- atom.config.set('foo.bar.baz', 55);
- advanceClock(150);
- savedSettings.length = 0;
- atom.config.unset('foo.bar.ok', { scopeSelector: '.source.coffee' });
- advanceClock(150);
- expect(savedSettings.length).toBe(0);
- expect(
- atom.config.get('foo.bar.baz', { scope: ['.source.coffee'] })
- ).toBe(55);
- });
- });
- });
- describe('.onDidChange(keyPath, {scope})', () => {
- let observeHandler = [];
- describe('when a keyPath is specified', () => {
- beforeEach(() => {
- observeHandler = jasmine.createSpy('observeHandler');
- atom.config.set('foo.bar.baz', 'value 1');
- atom.config.onDidChange('foo.bar.baz', observeHandler);
- });
- it('does not fire the given callback with the current value at the keypath', () =>
- expect(observeHandler).not.toHaveBeenCalled());
- it('fires the callback every time the observed value changes', () => {
- atom.config.set('foo.bar.baz', 'value 2');
- expect(observeHandler).toHaveBeenCalledWith({
- newValue: 'value 2',
- oldValue: 'value 1'
- });
- observeHandler.reset();
- observeHandler.andCallFake(() => {
- throw new Error('oops');
- });
- expect(() => atom.config.set('foo.bar.baz', 'value 1')).toThrow('oops');
- expect(observeHandler).toHaveBeenCalledWith({
- newValue: 'value 1',
- oldValue: 'value 2'
- });
- observeHandler.reset();
- // Regression: exception in earlier handler shouldn't put observer
- // into a bad state.
- atom.config.set('something.else', 'new value');
- expect(observeHandler).not.toHaveBeenCalled();
- });
- });
- describe('when a keyPath is not specified', () => {
- beforeEach(() => {
- observeHandler = jasmine.createSpy('observeHandler');
- atom.config.set('foo.bar.baz', 'value 1');
- atom.config.onDidChange(observeHandler);
- });
- it('does not fire the given callback initially', () =>
- expect(observeHandler).not.toHaveBeenCalled());
- it('fires the callback every time any value changes', () => {
- observeHandler.reset(); // clear the initial call
- atom.config.set('foo.bar.baz', 'value 2');
- expect(observeHandler).toHaveBeenCalled();
- expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.baz).toBe(
- 'value 2'
- );
- expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.baz).toBe(
- 'value 1'
- );
- observeHandler.reset();
- atom.config.set('foo.bar.baz', 'value 1');
- expect(observeHandler).toHaveBeenCalled();
- expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.baz).toBe(
- 'value 1'
- );
- expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.baz).toBe(
- 'value 2'
- );
- observeHandler.reset();
- atom.config.set('foo.bar.int', 1);
- expect(observeHandler).toHaveBeenCalled();
- expect(observeHandler.mostRecentCall.args[0].newValue.foo.bar.int).toBe(
- 1
- );
- expect(observeHandler.mostRecentCall.args[0].oldValue.foo.bar.int).toBe(
- undefined
- );
- });
- });
- describe("when a 'scope' is given", () =>
- it('calls the supplied callback when the value at the descriptor/keypath changes', () => {
- const changeSpy = jasmine.createSpy('onDidChange callback');
- atom.config.onDidChange(
- 'foo.bar.baz',
- { scope: ['.source.coffee', '.string.quoted.double.coffee'] },
- changeSpy
- );
- atom.config.set('foo.bar.baz', 12);
- expect(changeSpy).toHaveBeenCalledWith({
- oldValue: undefined,
- newValue: 12
- });
- changeSpy.reset();
- atom.config.set('foo.bar.baz', 22, {
- scopeSelector: '.source .string.quoted.double',
- source: 'a'
- });
- expect(changeSpy).toHaveBeenCalledWith({ oldValue: 12, newValue: 22 });
- changeSpy.reset();
- atom.config.set('foo.bar.baz', 42, {
- scopeSelector: '.source.coffee .string.quoted.double.coffee',
- source: 'b'
- });
- expect(changeSpy).toHaveBeenCalledWith({ oldValue: 22, newValue: 42 });
- changeSpy.reset();
- atom.config.unset(null, {
- scopeSelector: '.source.coffee .string.quoted.double.coffee',
- source: 'b'
- });
- expect(changeSpy).toHaveBeenCalledWith({ oldValue: 42, newValue: 22 });
- changeSpy.reset();
- atom.config.unset(null, {
- scopeSelector: '.source .string.quoted.double',
- source: 'a'
- });
- expect(changeSpy).toHaveBeenCalledWith({ oldValue: 22, newValue: 12 });
- changeSpy.reset();
- atom.config.set('foo.bar.baz', undefined);
- expect(changeSpy).toHaveBeenCalledWith({
- oldValue: 12,
- newValue: undefined
- });
- changeSpy.reset();
- }));
- });
- describe('.observe(keyPath, {scope})', () => {
- let [observeHandler, observeSubscription] = [];
- beforeEach(() => {
- observeHandler = jasmine.createSpy('observeHandler');
- atom.config.set('foo.bar.baz', 'value 1');
- observeSubscription = atom.config.observe('foo.bar.baz', observeHandler);
- });
- it('fires the given callback with the current value at the keypath', () =>
- expect(observeHandler).toHaveBeenCalledWith('value 1'));
- it('fires the callback every time the observed value changes', () => {
- observeHandler.reset(); // clear the initial call
- atom.config.set('foo.bar.baz', 'value 2');
- expect(observeHandler).toHaveBeenCalledWith('value 2');
- observeHandler.reset();
- atom.config.set('foo.bar.baz', 'value 1');
- expect(observeHandler).toHaveBeenCalledWith('value 1');
- advanceClock(100); // complete pending save that was requested in ::set
- observeHandler.reset();
- atom.config.resetUserSettings({ foo: {} });
- expect(observeHandler).toHaveBeenCalledWith(undefined);
- });
- it('fires the callback when the observed value is deleted', () => {
- observeHandler.reset(); // clear the initial call
- atom.config.set('foo.bar.baz', undefined);
- expect(observeHandler).toHaveBeenCalledWith(undefined);
- });
- it('fires the callback when the full key path goes into and out of existence', () => {
- observeHandler.reset(); // clear the initial call
- atom.config.set('foo.bar', undefined);
- expect(observeHandler).toHaveBeenCalledWith(undefined);
- observeHandler.reset();
- atom.config.set('foo.bar.baz', "i'm back");
- expect(observeHandler).toHaveBeenCalledWith("i'm back");
- });
- it('does not fire the callback once the subscription is disposed', () => {
- observeHandler.reset(); // clear the initial call
- observeSubscription.dispose();
- atom.config.set('foo.bar.baz', 'value 2');
- expect(observeHandler).not.toHaveBeenCalled();
- });
- it('does not fire the callback for a similarly named keyPath', () => {
- const bazCatHandler = jasmine.createSpy('bazCatHandler');
- observeSubscription = atom.config.observe(
- 'foo.bar.bazCat',
- bazCatHandler
- );
- bazCatHandler.reset();
- atom.config.set('foo.bar.baz', 'value 10');
- expect(bazCatHandler).not.toHaveBeenCalled();
- });
- describe("when a 'scope' is given", () => {
- let otherHandler = null;
- beforeEach(() => {
- observeSubscription.dispose();
- otherHandler = jasmine.createSpy('otherHandler');
- });
- it('allows settings to be observed in a specific scope', () => {
- atom.config.observe(
- 'foo.bar.baz',
- { scope: ['.some.scope'] },
- observeHandler
- );
- atom.config.observe(
- 'foo.bar.baz',
- { scope: ['.another.scope'] },
- otherHandler
- );
- atom.config.set('foo.bar.baz', 'value 2', { scopeSelector: '.some' });
- expect(observeHandler).toHaveBeenCalledWith('value 2');
- expect(otherHandler).not.toHaveBeenCalledWith('value 2');
- });
- it('calls the callback when properties with more specific selectors are removed', () => {
- const changeSpy = jasmine.createSpy();
- atom.config.observe(
- 'foo.bar.baz',
- { scope: ['.source.coffee', '.string.quoted.double.coffee'] },
- changeSpy
- );
- expect(changeSpy).toHaveBeenCalledWith('value 1');
- changeSpy.reset();
- atom.config.set('foo.bar.baz', 12);
- expect(changeSpy).toHaveBeenCalledWith(12);
- changeSpy.reset();
- atom.config.set('foo.bar.baz', 22, {
- scopeSelector: '.source .string.quoted.double',
- source: 'a'
- });
- expect(changeSpy).toHaveBeenCalledWith(22);
- changeSpy.reset();
- atom.config.set('foo.bar.baz', 42, {
- scopeSelector: '.source.coffee .string.quoted.double.coffee',
- source: 'b'
- });
- expect(changeSpy).toHaveBeenCalledWith(42);
- changeSpy.reset();
- atom.config.unset(null, {
- scopeSelector: '.source.coffee .string.quoted.double.coffee',
- source: 'b'
- });
- expect(changeSpy).toHaveBeenCalledWith(22);
- changeSpy.reset();
- atom.config.unset(null, {
- scopeSelector: '.source .string.quoted.double',
- source: 'a'
- });
- expect(changeSpy).toHaveBeenCalledWith(12);
- changeSpy.reset();
- atom.config.set('foo.bar.baz', undefined);
- expect(changeSpy).toHaveBeenCalledWith(undefined);
- changeSpy.reset();
- });
- });
- });
- describe('.transact(callback)', () => {
- let changeSpy = null;
- beforeEach(() => {
- changeSpy = jasmine.createSpy('onDidChange callback');
- atom.config.onDidChange('foo.bar.baz', changeSpy);
- });
- it('allows only one change event for the duration of the given callback', () => {
- atom.config.transact(() => {
- atom.config.set('foo.bar.baz', 1);
- atom.config.set('foo.bar.baz', 2);
- atom.config.set('foo.bar.baz', 3);
- });
- expect(changeSpy.callCount).toBe(1);
- expect(changeSpy.argsForCall[0][0]).toEqual({
- newValue: 3,
- oldValue: undefined
- });
- });
- it('does not emit an event if no changes occur while paused', () => {
- atom.config.transact(() => {});
- expect(changeSpy).not.toHaveBeenCalled();
- });
- });
- describe('.transactAsync(callback)', () => {
- let changeSpy = null;
- beforeEach(() => {
- changeSpy = jasmine.createSpy('onDidChange callback');
- atom.config.onDidChange('foo.bar.baz', changeSpy);
- });
- it('allows only one change event for the duration of the given promise if it gets resolved', () => {
- let promiseResult = null;
- const transactionPromise = atom.config.transactAsync(() => {
- atom.config.set('foo.bar.baz', 1);
- atom.config.set('foo.bar.baz', 2);
- atom.config.set('foo.bar.baz', 3);
- return Promise.resolve('a result');
- });
- waitsForPromise(() =>
- transactionPromise.then(result => {
- promiseResult = result;
- })
- );
- runs(() => {
- expect(promiseResult).toBe('a result');
- expect(changeSpy.callCount).toBe(1);
- expect(changeSpy.argsForCall[0][0]).toEqual({
- newValue: 3,
- oldValue: undefined
- });
- });
- });
- it('allows only one change event for the duration of the given promise if it gets rejected', () => {
- let promiseError = null;
- const transactionPromise = atom.config.transactAsync(() => {
- atom.config.set('foo.bar.baz', 1);
- atom.config.set('foo.bar.baz', 2);
- atom.config.set('foo.bar.baz', 3);
- return Promise.reject(new Error('an error'));
- });
- waitsForPromise(() =>
- transactionPromise.catch(error => {
- promiseError = error;
- })
- );
- runs(() => {
- expect(promiseError.message).toBe('an error');
- expect(changeSpy.callCount).toBe(1);
- expect(changeSpy.argsForCall[0][0]).toEqual({
- newValue: 3,
- oldValue: undefined
- });
- });
- });
- it('allows only one change event even when the given callback throws', () => {
- const error = new Error('Oops!');
- let promiseError = null;
- const transactionPromise = atom.config.transactAsync(() => {
- atom.config.set('foo.bar.baz', 1);
- atom.config.set('foo.bar.baz', 2);
- atom.config.set('foo.bar.baz', 3);
- throw error;
- });
- waitsForPromise(() =>
- transactionPromise.catch(e => {
- promiseError = e;
- })
- );
- runs(() => {
- expect(promiseError).toBe(error);
- expect(changeSpy.callCount).toBe(1);
- expect(changeSpy.argsForCall[0][0]).toEqual({
- newValue: 3,
- oldValue: undefined
- });
- });
- });
- });
- describe('.getSources()', () => {
- it("returns an array of all of the config's source names", () => {
- expect(atom.config.getSources()).toEqual([]);
- atom.config.set('a.b', 1, { scopeSelector: '.x1', source: 'source-1' });
- atom.config.set('a.c', 1, { scopeSelector: '.x1', source: 'source-1' });
- atom.config.set('a.b', 2, { scopeSelector: '.x2', source: 'source-2' });
- atom.config.set('a.b', 1, { scopeSelector: '.x3', source: 'source-3' });
- expect(atom.config.getSources()).toEqual([
- 'source-1',
- 'source-2',
- 'source-3'
- ]);
- });
- });
- describe('.save()', () => {
- it('calls the save callback with any non-default properties', () => {
- atom.config.set('a.b.c', 1);
- atom.config.set('a.b.d', 2);
- atom.config.set('x.y.z', 3);
- atom.config.setDefaults('a.b', { e: 4, f: 5 });
- atom.config.save();
- expect(savedSettings).toEqual([{ '*': atom.config.settings }]);
- });
- it('serializes properties in alphabetical order', () => {
- atom.config.set('foo', 1);
- atom.config.set('bar', 2);
- atom.config.set('baz.foo', 3);
- atom.config.set('baz.bar', 4);
- savedSettings.length = 0;
- atom.config.save();
- const writtenConfig = savedSettings[0];
- expect(writtenConfig).toEqual({ '*': atom.config.settings });
- let expectedKeys = ['bar', 'baz', 'foo'];
- let foundKeys = [];
- for (const key in writtenConfig['*']) {
- if (expectedKeys.includes(key)) {
- foundKeys.push(key);
- }
- }
- expect(foundKeys).toEqual(expectedKeys);
- expectedKeys = ['bar', 'foo'];
- foundKeys = [];
- for (const key in writtenConfig['*']['baz']) {
- if (expectedKeys.includes(key)) {
- foundKeys.push(key);
- }
- }
- expect(foundKeys).toEqual(expectedKeys);
- });
- describe('when scoped settings are defined', () => {
- it('serializes any explicitly set config settings', () => {
- atom.config.set('foo.bar', 'ruby', { scopeSelector: '.source.ruby' });
- atom.config.set('foo.omg', 'wow', { scopeSelector: '.source.ruby' });
- atom.config.set('foo.bar', 'coffee', {
- scopeSelector: '.source.coffee'
- });
- savedSettings.length = 0;
- atom.config.save();
- const writtenConfig = savedSettings[0];
- expect(writtenConfig).toEqualJson({
- '*': atom.config.settings,
- '.ruby.source': {
- foo: {
- bar: 'ruby',
- omg: 'wow'
- }
- },
- '.coffee.source': {
- foo: {
- bar: 'coffee'
- }
- }
- });
- });
- });
- });
- describe('.resetUserSettings()', () => {
- beforeEach(() => {
- atom.config.setSchema('foo', {
- type: 'object',
- properties: {
- bar: {
- type: 'string',
- default: 'def'
- },
- int: {
- type: 'integer',
- default: 12
- }
- }
- });
- });
- describe('when the config file contains scoped settings', () => {
- it('updates the config data based on the file contents', () => {
- atom.config.resetUserSettings({
- '*': {
- foo: {
- bar: 'baz'
- }
- },
- '.source.ruby': {
- foo: {
- bar: 'more-specific'
- }
- }
- });
- expect(atom.config.get('foo.bar')).toBe('baz');
- expect(atom.config.get('foo.bar', { scope: ['.source.ruby'] })).toBe(
- 'more-specific'
- );
- });
- });
- describe('when the config file does not conform to the schema', () => {
- it('validates and does not load the incorrect values', () => {
- atom.config.resetUserSettings({
- '*': {
- foo: {
- bar: 'omg',
- int: 'baz'
- }
- },
- '.source.ruby': {
- foo: {
- bar: 'scoped',
- int: 'nope'
- }
- }
- });
- expect(atom.config.get('foo.int')).toBe(12);
- expect(atom.config.get('foo.bar')).toBe('omg');
- expect(atom.config.get('foo.int', { scope: ['.source.ruby'] })).toBe(
- 12
- );
- expect(atom.config.get('foo.bar', { scope: ['.source.ruby'] })).toBe(
- 'scoped'
- );
- });
- });
- it('updates the config data based on the file contents', () => {
- atom.config.resetUserSettings({ foo: { bar: 'baz' } });
- expect(atom.config.get('foo.bar')).toBe('baz');
- });
- it('notifies observers for updated keypaths on load', () => {
- const observeHandler = jasmine.createSpy('observeHandler');
- atom.config.observe('foo.bar', observeHandler);
- atom.config.resetUserSettings({ foo: { bar: 'baz' } });
- expect(observeHandler).toHaveBeenCalledWith('baz');
- });
- describe('when the config file contains values that do not adhere to the schema', () => {
- it('updates the only the settings that have values matching the schema', () => {
- atom.config.resetUserSettings({
- foo: {
- bar: 'baz',
- int: 'bad value'
- }
- });
- expect(atom.config.get('foo.bar')).toBe('baz');
- expect(atom.config.get('foo.int')).toBe(12);
- expect(console.warn).toHaveBeenCalled();
- expect(console.warn.mostRecentCall.args[0]).toContain('foo.int');
- });
- });
- it('does not fire a change event for paths that did not change', () => {
- atom.config.resetUserSettings({
- foo: { bar: 'baz', int: 3 }
- });
- const noChangeSpy = jasmine.createSpy('unchanged');
- atom.config.onDidChange('foo.bar', noChangeSpy);
- atom.config.resetUserSettings({
- foo: { bar: 'baz', int: 4 }
- });
- expect(noChangeSpy).not.toHaveBeenCalled();
- expect(atom.config.get('foo.bar')).toBe('baz');
- expect(atom.config.get('foo.int')).toBe(4);
- });
- it('does not fire a change event for paths whose non-primitive values did not change', () => {
- atom.config.setSchema('foo.bar', {
- type: 'array',
- items: {
- type: 'string'
- }
- });
- atom.config.resetUserSettings({
- foo: { bar: ['baz', 'quux'], int: 2 }
- });
- const noChangeSpy = jasmine.createSpy('unchanged');
- atom.config.onDidChange('foo.bar', noChangeSpy);
- atom.config.resetUserSettings({
- foo: { bar: ['baz', 'quux'], int: 2 }
- });
- expect(noChangeSpy).not.toHaveBeenCalled();
- expect(atom.config.get('foo.bar')).toEqual(['baz', 'quux']);
- });
- describe('when a setting with a default is removed', () => {
- it('resets the setting back to the default', () => {
- atom.config.resetUserSettings({
- foo: { bar: ['baz', 'quux'], int: 2 }
- });
- const events = [];
- atom.config.onDidChange('foo.int', event => events.push(event));
- atom.config.resetUserSettings({
- foo: { bar: ['baz', 'quux'] }
- });
- expect(events.length).toBe(1);
- expect(events[0]).toEqual({ oldValue: 2, newValue: 12 });
- });
- });
- it('keeps all the global scope settings after overriding one', () => {
- atom.config.resetUserSettings({
- '*': {
- foo: {
- bar: 'baz',
- int: 99
- }
- }
- });
- atom.config.set('foo.int', 50, { scopeSelector: '*' });
- advanceClock(100);
- expect(savedSettings[0]['*'].foo).toEqual({
- bar: 'baz',
- int: 50
- });
- expect(atom.config.get('foo.int', { scope: ['*'] })).toEqual(50);
- expect(atom.config.get('foo.bar', { scope: ['*'] })).toEqual('baz');
- expect(atom.config.get('foo.int')).toEqual(50);
- });
- });
- describe('.pushAtKeyPath(keyPath, value)', () => {
- it('pushes the given value to the array at the key path and updates observers', () => {
- atom.config.set('foo.bar.baz', ['a']);
- const observeHandler = jasmine.createSpy('observeHandler');
- atom.config.observe('foo.bar.baz', observeHandler);
- observeHandler.reset();
- expect(atom.config.pushAtKeyPath('foo.bar.baz', 'b')).toBe(2);
- expect(atom.config.get('foo.bar.baz')).toEqual(['a', 'b']);
- expect(observeHandler).toHaveBeenCalledWith(
- atom.config.get('foo.bar.baz')
- );
- });
- });
- describe('.unshiftAtKeyPath(keyPath, value)', () => {
- it('unshifts the given value to the array at the key path and updates observers', () => {
- atom.config.set('foo.bar.baz', ['b']);
- const observeHandler = jasmine.createSpy('observeHandler');
- atom.config.observe('foo.bar.baz', observeHandler);
- observeHandler.reset();
- expect(atom.config.unshiftAtKeyPath('foo.bar.baz', 'a')).toBe(2);
- expect(atom.config.get('foo.bar.baz')).toEqual(['a', 'b']);
- expect(observeHandler).toHaveBeenCalledWith(
- atom.config.get('foo.bar.baz')
- );
- });
- });
- describe('.removeAtKeyPath(keyPath, value)', () => {
- it('removes the given value from the array at the key path and updates observers', () => {
- atom.config.set('foo.bar.baz', ['a', 'b', 'c']);
- const observeHandler = jasmine.createSpy('observeHandler');
- atom.config.observe('foo.bar.baz', observeHandler);
- observeHandler.reset();
- expect(atom.config.removeAtKeyPath('foo.bar.baz', 'b')).toEqual([
- 'a',
- 'c'
- ]);
- expect(atom.config.get('foo.bar.baz')).toEqual(['a', 'c']);
- expect(observeHandler).toHaveBeenCalledWith(
- atom.config.get('foo.bar.baz')
- );
- });
- });
- describe('.setDefaults(keyPath, defaults)', () => {
- it('assigns any previously-unassigned keys to the object at the key path', () => {
- atom.config.set('foo.bar.baz', { a: 1 });
- atom.config.setDefaults('foo.bar.baz', { a: 2, b: 3, c: 4 });
- expect(atom.config.get('foo.bar.baz.a')).toBe(1);
- expect(atom.config.get('foo.bar.baz.b')).toBe(3);
- expect(atom.config.get('foo.bar.baz.c')).toBe(4);
- atom.config.setDefaults('foo.quux', { x: 0, y: 1 });
- expect(atom.config.get('foo.quux.x')).toBe(0);
- expect(atom.config.get('foo.quux.y')).toBe(1);
- });
- it('emits an updated event', () => {
- const updatedCallback = jasmine.createSpy('updated');
- atom.config.onDidChange('foo.bar.baz.a', updatedCallback);
- expect(updatedCallback.callCount).toBe(0);
- atom.config.setDefaults('foo.bar.baz', { a: 2 });
- expect(updatedCallback.callCount).toBe(1);
- });
- });
- describe('.setSchema(keyPath, schema)', () => {
- it('creates a properly nested schema', () => {
- const schema = {
- type: 'object',
- properties: {
- anInt: {
- type: 'integer',
- default: 12
- }
- }
- };
- atom.config.setSchema('foo.bar', schema);
- expect(atom.config.getSchema('foo')).toEqual({
- type: 'object',
- properties: {
- bar: {
- type: 'object',
- properties: {
- anInt: {
- type: 'integer',
- default: 12
- }
- }
- }
- }
- });
- });
- it('sets defaults specified by the schema', () => {
- const schema = {
- type: 'object',
- properties: {
- anInt: {
- type: 'integer',
- default: 12
- },
- anObject: {
- type: 'object',
- properties: {
- nestedInt: {
- type: 'integer',
- default: 24
- },
- nestedObject: {
- type: 'object',
- properties: {
- superNestedInt: {
- type: 'integer',
- default: 36
- }
- }
- }
- }
- }
- }
- };
- atom.config.setSchema('foo.bar', schema);
- expect(atom.config.get('foo.bar.anInt')).toBe(12);
- expect(atom.config.get('foo.bar.anObject')).toEqual({
- nestedInt: 24,
- nestedObject: {
- superNestedInt: 36
- }
- });
- expect(atom.config.get('foo')).toEqual({
- bar: {
- anInt: 12,
- anObject: {
- nestedInt: 24,
- nestedObject: {
- superNestedInt: 36
- }
- }
- }
- });
- atom.config.set('foo.bar.anObject.nestedObject.superNestedInt', 37);
- expect(atom.config.get('foo')).toEqual({
- bar: {
- anInt: 12,
- anObject: {
- nestedInt: 24,
- nestedObject: {
- superNestedInt: 37
- }
- }
- }
- });
- });
- it('can set a non-object schema', () => {
- const schema = {
- type: 'integer',
- default: 12
- };
- atom.config.setSchema('foo.bar.anInt', schema);
- expect(atom.config.get('foo.bar.anInt')).toBe(12);
- expect(atom.config.getSchema('foo.bar.anInt')).toEqual({
- type: 'integer',
- default: 12
- });
- });
- it('allows the schema to be retrieved via ::getSchema', () => {
- const schema = {
- type: 'object',
- properties: {
- anInt: {
- type: 'integer',
- default: 12
- }
- }
- };
- atom.config.setSchema('foo.bar', schema);
- expect(atom.config.getSchema('foo.bar')).toEqual({
- type: 'object',
- properties: {
- anInt: {
- type: 'integer',
- default: 12
- }
- }
- });
- expect(atom.config.getSchema('foo.bar.anInt')).toEqual({
- type: 'integer',
- default: 12
- });
- expect(atom.config.getSchema('foo.baz')).toEqual({ type: 'any' });
- expect(atom.config.getSchema('foo.bar.anInt.baz')).toBe(null);
- });
- it('respects the schema for scoped settings', () => {
- const schema = {
- type: 'string',
- default: 'ok',
- scopes: {
- '.source.js': {
- default: 'omg'
- }
- }
- };
- atom.config.setSchema('foo.bar.str', schema);
- expect(atom.config.get('foo.bar.str')).toBe('ok');
- expect(atom.config.get('foo.bar.str', { scope: ['.source.js'] })).toBe(
- 'omg'
- );
- expect(
- atom.config.get('foo.bar.str', { scope: ['.source.coffee'] })
- ).toBe('ok');
- });
- describe('when a schema is added after config values have been set', () => {
- let schema = null;
- beforeEach(() => {
- schema = {
- type: 'object',
- properties: {
- int: {
- type: 'integer',
- default: 2
- },
- str: {
- type: 'string',
- default: 'def'
- }
- }
- };
- });
- it('respects the new schema when values are set', () => {
- expect(atom.config.set('foo.bar.str', 'global')).toBe(true);
- expect(
- atom.config.set('foo.bar.str', 'scoped', {
- scopeSelector: '.source.js'
- })
- ).toBe(true);
- expect(atom.config.get('foo.bar.str')).toBe('global');
- expect(atom.config.get('foo.bar.str', { scope: ['.source.js'] })).toBe(
- 'scoped'
- );
- expect(atom.config.set('foo.bar.noschema', 'nsGlobal')).toBe(true);
- expect(
- atom.config.set('foo.bar.noschema', 'nsScoped', {
- scopeSelector: '.source.js'
- })
- ).toBe(true);
- expect(atom.config.get('foo.bar.noschema')).toBe('nsGlobal');
- expect(
- atom.config.get('foo.bar.noschema', { scope: ['.source.js'] })
- ).toBe('nsScoped');
- expect(atom.config.set('foo.bar.int', 'nope')).toBe(true);
- expect(
- atom.config.set('foo.bar.int', 'notanint', {
- scopeSelector: '.source.js'
- })
- ).toBe(true);
- expect(
- atom.config.set('foo.bar.int', 23, {
- scopeSelector: '.source.coffee'
- })
- ).toBe(true);
- expect(atom.config.get('foo.bar.int')).toBe('nope');
- expect(atom.config.get('foo.bar.int', { scope: ['.source.js'] })).toBe(
- 'notanint'
- );
- expect(
- atom.config.get('foo.bar.int', { scope: ['.source.coffee'] })
- ).toBe(23);
- atom.config.setSchema('foo.bar', schema);
- expect(atom.config.get('foo.bar.str')).toBe('global');
- expect(atom.config.get('foo.bar.str', { scope: ['.source.js'] })).toBe(
- 'scoped'
- );
- expect(atom.config.get('foo.bar.noschema')).toBe('nsGlobal');
- expect(
- atom.config.get('foo.bar.noschema', { scope: ['.source.js'] })
- ).toBe('nsScoped');
- expect(atom.config.get('foo.bar.int')).toBe(2);
- expect(atom.config.get('foo.bar.int', { scope: ['.source.js'] })).toBe(
- 2
- );
- expect(
- atom.config.get('foo.bar.int', { scope: ['.source.coffee'] })
- ).toBe(23);
- });
- it('sets all values that adhere to the schema', () => {
- expect(atom.config.set('foo.bar.int', 10)).toBe(true);
- expect(
- atom.config.set('foo.bar.int', 15, { scopeSelector: '.source.js' })
- ).toBe(true);
- expect(
- atom.config.set('foo.bar.int', 23, {
- scopeSelector: '.source.coffee'
- })
- ).toBe(true);
- expect(atom.config.get('foo.bar.int')).toBe(10);
- expect(atom.config.get('foo.bar.int', { scope: ['.source.js'] })).toBe(
- 15
- );
- expect(
- atom.config.get('foo.bar.int', { scope: ['.source.coffee'] })
- ).toBe(23);
- atom.config.setSchema('foo.bar', schema);
- expect(atom.config.get('foo.bar.int')).toBe(10);
- expect(atom.config.get('foo.bar.int', { scope: ['.source.js'] })).toBe(
- 15
- );
- expect(
- atom.config.get('foo.bar.int', { scope: ['.source.coffee'] })
- ).toBe(23);
- });
- });
- describe('when the value has an "integer" type', () => {
- beforeEach(() => {
- const schema = {
- type: 'integer',
- default: 12
- };
- atom.config.setSchema('foo.bar.anInt', schema);
- });
- it('coerces a string to an int', () => {
- atom.config.set('foo.bar.anInt', '123');
- expect(atom.config.get('foo.bar.anInt')).toBe(123);
- });
- it('does not allow infinity', () => {
- atom.config.set('foo.bar.anInt', Infinity);
- expect(atom.config.get('foo.bar.anInt')).toBe(12);
- });
- it('coerces a float to an int', () => {
- atom.config.set('foo.bar.anInt', 12.3);
- expect(atom.config.get('foo.bar.anInt')).toBe(12);
- });
- it('will not set non-integers', () => {
- atom.config.set('foo.bar.anInt', null);
- expect(atom.config.get('foo.bar.anInt')).toBe(12);
- atom.config.set('foo.bar.anInt', 'nope');
- expect(atom.config.get('foo.bar.anInt')).toBe(12);
- });
- describe('when the minimum and maximum keys are used', () => {
- beforeEach(() => {
- const schema = {
- type: 'integer',
- minimum: 10,
- maximum: 20,
- default: 12
- };
- atom.config.setSchema('foo.bar.anInt', schema);
- });
- it('keeps the specified value within the specified range', () => {
- atom.config.set('foo.bar.anInt', '123');
- expect(atom.config.get('foo.bar.anInt')).toBe(20);
- atom.config.set('foo.bar.anInt', '1');
- expect(atom.config.get('foo.bar.anInt')).toBe(10);
- });
- });
- });
- describe('when the value has an "integer" and "string" type', () => {
- beforeEach(() => {
- const schema = {
- type: ['integer', 'string'],
- default: 12
- };
- atom.config.setSchema('foo.bar.anInt', schema);
- });
- it('can coerce an int, and fallback to a string', () => {
- atom.config.set('foo.bar.anInt', '123');
- expect(atom.config.get('foo.bar.anInt')).toBe(123);
- atom.config.set('foo.bar.anInt', 'cats');
- expect(atom.config.get('foo.bar.anInt')).toBe('cats');
- });
- });
- describe('when the value has an "string" and "boolean" type', () => {
- beforeEach(() => {
- const schema = {
- type: ['string', 'boolean'],
- default: 'def'
- };
- atom.config.setSchema('foo.bar', schema);
- });
- it('can set a string, a boolean, and revert back to the default', () => {
- atom.config.set('foo.bar', 'ok');
- expect(atom.config.get('foo.bar')).toBe('ok');
- atom.config.set('foo.bar', false);
- expect(atom.config.get('foo.bar')).toBe(false);
- atom.config.set('foo.bar', undefined);
- expect(atom.config.get('foo.bar')).toBe('def');
- });
- });
- describe('when the value has a "number" type', () => {
- beforeEach(() => {
- const schema = {
- type: 'number',
- default: 12.1
- };
- atom.config.setSchema('foo.bar.aFloat', schema);
- });
- it('coerces a string to a float', () => {
- atom.config.set('foo.bar.aFloat', '12.23');
- expect(atom.config.get('foo.bar.aFloat')).toBe(12.23);
- });
- it('will not set non-numbers', () => {
- atom.config.set('foo.bar.aFloat', null);
- expect(atom.config.get('foo.bar.aFloat')).toBe(12.1);
- atom.config.set('foo.bar.aFloat', 'nope');
- expect(atom.config.get('foo.bar.aFloat')).toBe(12.1);
- });
- describe('when the minimum and maximum keys are used', () => {
- beforeEach(() => {
- const schema = {
- type: 'number',
- minimum: 11.2,
- maximum: 25.4,
- default: 12.1
- };
- atom.config.setSchema('foo.bar.aFloat', schema);
- });
- it('keeps the specified value within the specified range', () => {
- atom.config.set('foo.bar.aFloat', '123.2');
- expect(atom.config.get('foo.bar.aFloat')).toBe(25.4);
- atom.config.set('foo.bar.aFloat', '1.0');
- expect(atom.config.get('foo.bar.aFloat')).toBe(11.2);
- });
- });
- });
- describe('when the value has a "boolean" type', () => {
- beforeEach(() => {
- const schema = {
- type: 'boolean',
- default: true
- };
- atom.config.setSchema('foo.bar.aBool', schema);
- });
- it('coerces various types to a boolean', () => {
- atom.config.set('foo.bar.aBool', 'true');
- expect(atom.config.get('foo.bar.aBool')).toBe(true);
- atom.config.set('foo.bar.aBool', 'false');
- expect(atom.config.get('foo.bar.aBool')).toBe(false);
- atom.config.set('foo.bar.aBool', 'TRUE');
- expect(atom.config.get('foo.bar.aBool')).toBe(true);
- atom.config.set('foo.bar.aBool', 'FALSE');
- expect(atom.config.get('foo.bar.aBool')).toBe(false);
- atom.config.set('foo.bar.aBool', 1);
- expect(atom.config.get('foo.bar.aBool')).toBe(false);
- atom.config.set('foo.bar.aBool', 0);
- expect(atom.config.get('foo.bar.aBool')).toBe(false);
- atom.config.set('foo.bar.aBool', {});
- expect(atom.config.get('foo.bar.aBool')).toBe(false);
- atom.config.set('foo.bar.aBool', null);
- expect(atom.config.get('foo.bar.aBool')).toBe(false);
- });
- it('reverts back to the default value when undefined is passed to set', () => {
- atom.config.set('foo.bar.aBool', 'false');
- expect(atom.config.get('foo.bar.aBool')).toBe(false);
- atom.config.set('foo.bar.aBool', undefined);
- expect(atom.config.get('foo.bar.aBool')).toBe(true);
- });
- });
- describe('when the value has an "string" type', () => {
- beforeEach(() => {
- const schema = {
- type: 'string',
- default: 'ok'
- };
- atom.config.setSchema('foo.bar.aString', schema);
- });
- it('allows strings', () => {
- atom.config.set('foo.bar.aString', 'yep');
- expect(atom.config.get('foo.bar.aString')).toBe('yep');
- });
- it('will only set strings', () => {
- expect(atom.config.set('foo.bar.aString', 123)).toBe(false);
- expect(atom.config.get('foo.bar.aString')).toBe('ok');
- expect(atom.config.set('foo.bar.aString', true)).toBe(false);
- expect(atom.config.get('foo.bar.aString')).toBe('ok');
- expect(atom.config.set('foo.bar.aString', null)).toBe(false);
- expect(atom.config.get('foo.bar.aString')).toBe('ok');
- expect(atom.config.set('foo.bar.aString', [])).toBe(false);
- expect(atom.config.get('foo.bar.aString')).toBe('ok');
- expect(atom.config.set('foo.bar.aString', { nope: 'nope' })).toBe(
- false
- );
- expect(atom.config.get('foo.bar.aString')).toBe('ok');
- });
- it('does not allow setting children of that key-path', () => {
- expect(atom.config.set('foo.bar.aString.something', 123)).toBe(false);
- expect(atom.config.get('foo.bar.aString')).toBe('ok');
- });
- describe('when the schema has a "maximumLength" key', () =>
- it('trims the string to be no longer than the specified maximum', () => {
- const schema = {
- type: 'string',
- default: 'ok',
- maximumLength: 3
- };
- atom.config.setSchema('foo.bar.aString', schema);
- atom.config.set('foo.bar.aString', 'abcdefg');
- expect(atom.config.get('foo.bar.aString')).toBe('abc');
- }));
- });
- describe('when the value has an "object" type', () => {
- beforeEach(() => {
- const schema = {
- type: 'object',
- properties: {
- anInt: {
- type: 'integer',
- default: 12
- },
- nestedObject: {
- type: 'object',
- properties: {
- nestedBool: {
- type: 'boolean',
- default: false
- }
- }
- }
- }
- };
- atom.config.setSchema('foo.bar', schema);
- });
- it('converts and validates all the children', () => {
- atom.config.set('foo.bar', {
- anInt: '23',
- nestedObject: {
- nestedBool: 'true'
- }
- });
- expect(atom.config.get('foo.bar')).toEqual({
- anInt: 23,
- nestedObject: {
- nestedBool: true
- }
- });
- });
- it('will set only the values that adhere to the schema', () => {
- expect(
- atom.config.set('foo.bar', {
- anInt: 'nope',
- nestedObject: {
- nestedBool: true
- }
- })
- ).toBe(true);
- expect(atom.config.get('foo.bar.anInt')).toEqual(12);
- expect(atom.config.get('foo.bar.nestedObject.nestedBool')).toEqual(
- true
- );
- });
- describe('when the value has additionalProperties set to false', () =>
- it('does not allow other properties to be set on the object', () => {
- atom.config.setSchema('foo.bar', {
- type: 'object',
- properties: {
- anInt: {
- type: 'integer',
- default: 12
- }
- },
- additionalProperties: false
- });
- expect(
- atom.config.set('foo.bar', { anInt: 5, somethingElse: 'ok' })
- ).toBe(true);
- expect(atom.config.get('foo.bar.anInt')).toBe(5);
- expect(atom.config.get('foo.bar.somethingElse')).toBeUndefined();
- expect(atom.config.set('foo.bar.somethingElse', { anInt: 5 })).toBe(
- false
- );
- expect(atom.config.get('foo.bar.somethingElse')).toBeUndefined();
- }));
- describe('when the value has an additionalProperties schema', () =>
- it('validates properties of the object against that schema', () => {
- atom.config.setSchema('foo.bar', {
- type: 'object',
- properties: {
- anInt: {
- type: 'integer',
- default: 12
- }
- },
- additionalProperties: {
- type: 'string'
- }
- });
- expect(
- atom.config.set('foo.bar', { anInt: 5, somethingElse: 'ok' })
- ).toBe(true);
- expect(atom.config.get('foo.bar.anInt')).toBe(5);
- expect(atom.config.get('foo.bar.somethingElse')).toBe('ok');
- expect(atom.config.set('foo.bar.somethingElse', 7)).toBe(false);
- expect(atom.config.get('foo.bar.somethingElse')).toBe('ok');
- expect(
- atom.config.set('foo.bar', { anInt: 6, somethingElse: 7 })
- ).toBe(true);
- expect(atom.config.get('foo.bar.anInt')).toBe(6);
- expect(atom.config.get('foo.bar.somethingElse')).toBe(undefined);
- }));
- });
- describe('when the value has an "array" type', () => {
- beforeEach(() => {
- const schema = {
- type: 'array',
- default: [1, 2, 3],
- items: {
- type: 'integer'
- }
- };
- atom.config.setSchema('foo.bar', schema);
- });
- it('converts an array of strings to an array of ints', () => {
- atom.config.set('foo.bar', ['2', '3', '4']);
- expect(atom.config.get('foo.bar')).toEqual([2, 3, 4]);
- });
- it('does not allow setting children of that key-path', () => {
- expect(atom.config.set('foo.bar.child', 123)).toBe(false);
- expect(atom.config.set('foo.bar.child.grandchild', 123)).toBe(false);
- expect(atom.config.get('foo.bar')).toEqual([1, 2, 3]);
- });
- });
- describe('when the value has a "color" type', () => {
- beforeEach(() => {
- const schema = {
- type: 'color',
- default: 'white'
- };
- atom.config.setSchema('foo.bar.aColor', schema);
- });
- it('returns a Color object', () => {
- let color = atom.config.get('foo.bar.aColor');
- expect(color.toHexString()).toBe('#ffffff');
- expect(color.toRGBAString()).toBe('rgba(255, 255, 255, 1)');
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- color.alpha = 0;
- atom.config.set('foo.bar.aColor', color);
- color = atom.config.get('foo.bar.aColor');
- expect(color.toHexString()).toBe('#000000');
- expect(color.toRGBAString()).toBe('rgba(0, 0, 0, 0)');
- color.red = 300;
- color.green = -200;
- color.blue = -1;
- color.alpha = 'not see through';
- atom.config.set('foo.bar.aColor', color);
- color = atom.config.get('foo.bar.aColor');
- expect(color.toHexString()).toBe('#ff0000');
- expect(color.toRGBAString()).toBe('rgba(255, 0, 0, 1)');
- color.red = 11;
- color.green = 11;
- color.blue = 124;
- color.alpha = 1;
- atom.config.set('foo.bar.aColor', color);
- color = atom.config.get('foo.bar.aColor');
- expect(color.toHexString()).toBe('#0b0b7c');
- expect(color.toRGBAString()).toBe('rgba(11, 11, 124, 1)');
- });
- it('coerces various types to a color object', () => {
- atom.config.set('foo.bar.aColor', 'red');
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 255,
- green: 0,
- blue: 0,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', '#020');
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 0,
- green: 34,
- blue: 0,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', '#abcdef');
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 171,
- green: 205,
- blue: 239,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', 'rgb(1,2,3)');
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 1,
- green: 2,
- blue: 3,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', 'rgba(4,5,6,.7)');
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 4,
- green: 5,
- blue: 6,
- alpha: 0.7
- });
- atom.config.set('foo.bar.aColor', 'hsl(120,100%,50%)');
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 0,
- green: 255,
- blue: 0,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', 'hsla(120,100%,50%,0.3)');
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 0,
- green: 255,
- blue: 0,
- alpha: 0.3
- });
- atom.config.set('foo.bar.aColor', {
- red: 100,
- green: 255,
- blue: 2,
- alpha: 0.5
- });
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 100,
- green: 255,
- blue: 2,
- alpha: 0.5
- });
- atom.config.set('foo.bar.aColor', { red: 255 });
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 255,
- green: 0,
- blue: 0,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', { red: 1000 });
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 255,
- green: 0,
- blue: 0,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', { red: 'dark' });
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 0,
- green: 0,
- blue: 0,
- alpha: 1
- });
- });
- it('reverts back to the default value when undefined is passed to set', () => {
- atom.config.set('foo.bar.aColor', undefined);
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 255,
- green: 255,
- blue: 255,
- alpha: 1
- });
- });
- it('will not set non-colors', () => {
- atom.config.set('foo.bar.aColor', null);
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 255,
- green: 255,
- blue: 255,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', 'nope');
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 255,
- green: 255,
- blue: 255,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', 30);
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 255,
- green: 255,
- blue: 255,
- alpha: 1
- });
- atom.config.set('foo.bar.aColor', false);
- expect(atom.config.get('foo.bar.aColor')).toEqual({
- red: 255,
- green: 255,
- blue: 255,
- alpha: 1
- });
- });
- it('returns a clone of the Color when returned in a parent object', () => {
- const color1 = atom.config.get('foo.bar').aColor;
- const color2 = atom.config.get('foo.bar').aColor;
- expect(color1.toRGBAString()).toBe('rgba(255, 255, 255, 1)');
- expect(color2.toRGBAString()).toBe('rgba(255, 255, 255, 1)');
- expect(color1).not.toBe(color2);
- expect(color1).toEqual(color2);
- });
- });
- describe('when the `enum` key is used', () => {
- beforeEach(() => {
- const schema = {
- type: 'object',
- properties: {
- str: {
- type: 'string',
- default: 'ok',
- enum: ['ok', 'one', 'two']
- },
- int: {
- type: 'integer',
- default: 2,
- enum: [2, 3, 5]
- },
- arr: {
- type: 'array',
- default: ['one', 'two'],
- items: {
- type: 'string',
- enum: ['one', 'two', 'three']
- }
- },
- str_options: {
- type: 'string',
- default: 'one',
- enum: [
- { value: 'one', description: 'One' },
- 'two',
- { value: 'three', description: 'Three' }
- ]
- }
- }
- };
- atom.config.setSchema('foo.bar', schema);
- });
- it('will only set a string when the string is in the enum values', () => {
- expect(atom.config.set('foo.bar.str', 'nope')).toBe(false);
- expect(atom.config.get('foo.bar.str')).toBe('ok');
- expect(atom.config.set('foo.bar.str', 'one')).toBe(true);
- expect(atom.config.get('foo.bar.str')).toBe('one');
- });
- it('will only set an integer when the integer is in the enum values', () => {
- expect(atom.config.set('foo.bar.int', '400')).toBe(false);
- expect(atom.config.get('foo.bar.int')).toBe(2);
- expect(atom.config.set('foo.bar.int', '3')).toBe(true);
- expect(atom.config.get('foo.bar.int')).toBe(3);
- });
- it('will only set an array when the array values are in the enum values', () => {
- expect(atom.config.set('foo.bar.arr', ['one', 'five'])).toBe(true);
- expect(atom.config.get('foo.bar.arr')).toEqual(['one']);
- expect(atom.config.set('foo.bar.arr', ['two', 'three'])).toBe(true);
- expect(atom.config.get('foo.bar.arr')).toEqual(['two', 'three']);
- });
- it('will honor the enum when specified as an array', () => {
- expect(atom.config.set('foo.bar.str_options', 'one')).toBe(true);
- expect(atom.config.get('foo.bar.str_options')).toEqual('one');
- expect(atom.config.set('foo.bar.str_options', 'two')).toBe(true);
- expect(atom.config.get('foo.bar.str_options')).toEqual('two');
- expect(atom.config.set('foo.bar.str_options', 'One')).toBe(false);
- expect(atom.config.get('foo.bar.str_options')).toEqual('two');
- });
- });
- });
- describe('when .set/.unset is called prior to .resetUserSettings', () => {
- beforeEach(() => {
- atom.config.settingsLoaded = false;
- });
- it('ensures that early set and unset calls are replayed after the config is loaded from disk', () => {
- atom.config.unset('foo.bar');
- atom.config.set('foo.qux', 'boo');
- expect(atom.config.get('foo.bar')).toBeUndefined();
- expect(atom.config.get('foo.qux')).toBe('boo');
- expect(atom.config.get('do.ray')).toBeUndefined();
- advanceClock(100);
- expect(savedSettings.length).toBe(0);
- atom.config.resetUserSettings({
- '*': {
- foo: {
- bar: 'baz'
- },
- do: {
- ray: 'me'
- }
- }
- });
- advanceClock(100);
- expect(savedSettings.length).toBe(1);
- expect(atom.config.get('foo.bar')).toBeUndefined();
- expect(atom.config.get('foo.qux')).toBe('boo');
- expect(atom.config.get('do.ray')).toBe('me');
- });
- });
- describe('project specific settings', () => {
- describe('config.resetProjectSettings', () => {
- it('gracefully handles invalid config objects', () => {
- atom.config.resetProjectSettings({});
- expect(atom.config.get('foo.bar')).toBeUndefined();
- });
- });
- describe('config.get', () => {
- const dummyPath = '/Users/dummy/path.json';
- describe('project settings', () => {
- it('returns a deep clone of the property value', () => {
- atom.config.resetProjectSettings(
- { '*': { value: { array: [1, { b: 2 }, 3] } } },
- dummyPath
- );
- const retrievedValue = atom.config.get('value');
- retrievedValue.array[0] = 4;
- retrievedValue.array[1].b = 2.1;
- expect(atom.config.get('value')).toEqual({ array: [1, { b: 2 }, 3] });
- });
- it('properly gets project settings', () => {
- atom.config.resetProjectSettings({ '*': { foo: 'wei' } }, dummyPath);
- expect(atom.config.get('foo')).toBe('wei');
- atom.config.resetProjectSettings(
- { '*': { foo: { bar: 'baz' } } },
- dummyPath
- );
- expect(atom.config.get('foo.bar')).toBe('baz');
- });
- it('gets project settings with higher priority than regular settings', () => {
- atom.config.set('foo', 'bar');
- atom.config.resetProjectSettings({ '*': { foo: 'baz' } }, dummyPath);
- expect(atom.config.get('foo')).toBe('baz');
- });
- it('correctly gets nested and scoped properties for project settings', () => {
- expect(atom.config.set('foo.bar.str', 'global')).toBe(true);
- expect(
- atom.config.set('foo.bar.str', 'scoped', {
- scopeSelector: '.source.js'
- })
- ).toBe(true);
- expect(atom.config.get('foo.bar.str')).toBe('global');
- expect(
- atom.config.get('foo.bar.str', { scope: ['.source.js'] })
- ).toBe('scoped');
- });
- it('returns a deep clone of the property value', () => {
- atom.config.set('value', { array: [1, { b: 2 }, 3] });
- const retrievedValue = atom.config.get('value');
- retrievedValue.array[0] = 4;
- retrievedValue.array[1].b = 2.1;
- expect(atom.config.get('value')).toEqual({ array: [1, { b: 2 }, 3] });
- });
- it('gets scoped values correctly', () => {
- atom.config.set('foo', 'bam', { scope: ['second'] });
- expect(atom.config.get('foo', { scopeSelector: 'second' })).toBe(
- 'bam'
- );
- atom.config.resetProjectSettings(
- { '*': { foo: 'baz' }, second: { foo: 'bar' } },
- dummyPath
- );
- expect(atom.config.get('foo', { scopeSelector: 'second' })).toBe(
- 'baz'
- );
- atom.config.clearProjectSettings();
- expect(atom.config.get('foo', { scopeSelector: 'second' })).toBe(
- 'bam'
- );
- });
- it('clears project settings correctly', () => {
- atom.config.set('foo', 'bar');
- expect(atom.config.get('foo')).toBe('bar');
- atom.config.resetProjectSettings(
- { '*': { foo: 'baz' }, second: { foo: 'bar' } },
- dummyPath
- );
- expect(atom.config.get('foo')).toBe('baz');
- expect(atom.config.getSources().length).toBe(1);
- atom.config.clearProjectSettings();
- expect(atom.config.get('foo')).toBe('bar');
- expect(atom.config.getSources().length).toBe(0);
- });
- });
- });
- describe('config.getAll', () => {
- const dummyPath = '/Users/dummy/path.json';
- it('gets settings in the same way .get would return them', () => {
- atom.config.resetProjectSettings({ '*': { a: 'b' } }, dummyPath);
- atom.config.set('a', 'f');
- expect(atom.config.getAll('a')).toEqual([
- {
- scopeSelector: '*',
- value: 'b'
- }
- ]);
- });
- });
- });
- });
|