Move state loading for Atom environment to an instance method

This commit is contained in:
Nathan Sobo 2015-10-02 11:28:50 -06:00
parent a87605164b
commit 6c67f42eab
5 changed files with 59 additions and 76 deletions

View File

@ -145,29 +145,31 @@ describe "the `atom` global", ->
expect(errors).toEqual []
describe "saving and loading", ->
afterEach -> atom.mode = "spec"
it "selects the state based on the current project paths", ->
Atom = atom.constructor
jasmine.unspy(atom, 'saveStateSync')
# jasmine.unspy(atom, 'loadStateSync')
[dir1, dir2] = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")]
loadSettings = _.extend Atom.getLoadSettings(),
loadSettings = _.extend atom.constructor.getLoadSettings(),
initialPaths: [dir1]
windowState: null
spyOn(Atom, 'getLoadSettings').andCallFake -> loadSettings
spyOn(Atom.getStorageFolder(), 'getPath').andReturn(temp.mkdirSync("storage-dir-"))
spyOn(atom, 'getLoadSettings').andCallFake -> loadSettings
spyOn(atom.getStorageFolder(), 'getPath').andReturn(temp.mkdirSync("storage-dir-"))
atom.state.stuff = "cool"
atom.project.setPaths([dir1, dir2])
atom.saveSync.originalValue.call(atom)
atom.saveStateSync()
atom1 = Atom.loadOrCreate()
expect(atom1.state.stuff).toBeUndefined()
atom.state = {}
atom.loadStateSync()
expect(atom.state.stuff).toBeUndefined()
loadSettings.initialPaths = [dir2, dir1]
atom2 = Atom.loadOrCreate()
expect(atom2.state.stuff).toBe("cool")
atom.state = {}
atom.loadStateSync()
expect(atom.state.stuff).toBe("cool")
describe "openInitialEmptyEditorIfNecessary", ->
describe "when there are no paths set", ->
@ -224,7 +226,7 @@ describe "the `atom` global", ->
expect(atom.state.workspace).toEqual workspaceState
expect(atom.state.grammars).toEqual grammarsState
expect(atom.state.project).toEqual projectState
expect(atom.saveSync).toHaveBeenCalled()
expect(atom.saveStateSync).toHaveBeenCalled()
describe "::removeEditorWindow()", ->
it "unsubscribes from all buffers", ->

View File

@ -104,7 +104,7 @@ beforeEach ->
serializedWindowState = null
spyOn(atom, 'saveSync')
spyOn(atom, 'saveStateSync')
atom.grammars.clearGrammarOverrides()
spy = spyOn(atom.packages, 'resolvePackagePath').andCallFake (packageName) ->
@ -170,7 +170,6 @@ afterEach ->
document.getElementById('jasmine-content').innerHTML = '' unless window.debugContent
jasmine.unspy(atom, 'saveSync')
ensureNoPathSubscriptions()
waits(0) # yield to ui thread to make screen update more frequently

View File

@ -37,53 +37,6 @@ module.exports =
class Atom extends Model
@version: 1 # Increment this when the serialization format changes
# Load or create the Atom environment in the given mode.
#
# * `mode` A {String} mode that is either 'editor' or 'spec' depending on the
# kind of environment you want to build.
#
# Returns an Atom instance, fully initialized
@loadOrCreate: ->
startTime = Date.now()
atom = @deserialize(@loadState()) ? new this({@version})
atom.deserializeTimings.atom = Date.now() - startTime
atom
# Deserializes the Atom environment from a state object
@deserialize: (state) ->
new this(state) if state?.version is @version
# Loads and returns the serialized state corresponding to this window
# if it exists; otherwise returns undefined.
@loadState: ->
if stateKey = @getStateKey(@getLoadSettings().initialPaths)
if state = @getStorageFolder().load(stateKey)
return state
if windowState = @getLoadSettings().windowState
try
JSON.parse(@getLoadSettings().windowState)
catch error
console.warn "Error parsing window state: #{statePath} #{error.stack}", error
# Returns the path where the state for the current window will be
# located if it exists.
@getStateKey: (paths) ->
if paths?.length > 0
sha1 = crypto.createHash('sha1').update(paths.slice().sort().join("\n")).digest('hex')
"editor-#{sha1}"
else
null
# Get the directory path to Atom's configuration area.
#
# Returns the absolute path to ~/.atom
@getConfigDirPath: ->
@configDirPath ?= process.env.ATOM_HOME
@getStorageFolder: ->
@storageFolder ?= new StorageFolder(@getConfigDirPath())
# Returns the load settings hash associated with the current window.
@getLoadSettings: -> getWindowLoadSettings()
@ -154,8 +107,8 @@ class Atom extends Model
###
# Call .loadOrCreate instead
constructor: (@state={}) ->
@state.version ?= @constructor.version
constructor: ->
@state = {version: @constructor.version}
@loadTime = null
{devMode, safeMode, resourcePath} = @getLoadSettings()
@ -318,12 +271,6 @@ class Atom extends Model
isReleasedVersion: ->
not /\w{7}/.test(@getVersion()) # Check if the release is a 7-character SHA prefix
# Public: Get the directory path to Atom's configuration area.
#
# Returns the absolute path to `~/.atom`.
getConfigDirPath: ->
@constructor.getConfigDirPath()
# Public: Get the time taken to completely load the current window.
#
# This time include things like loading and activating packages, creating
@ -586,7 +533,7 @@ class Atom extends Model
@state.workspace = @workspace.serialize()
@packages.deactivatePackages()
@state.packageStates = @packages.packageStates
@saveSync()
@saveStateSync()
@windowState = null
removeEditorWindow: ->
@ -777,12 +724,41 @@ class Atom extends Model
options.defaultPath ?= @project?.getPaths()[0]
dialog.showSaveDialog currentWindow, options
saveSync: ->
if storageKey = @constructor.getStateKey(@project?.getPaths())
@constructor.getStorageFolder().store(storageKey, @state)
saveStateSync: ->
if storageKey = @getStateKey(@project?.getPaths())
@getStorageFolder().store(storageKey, @state)
else
@getCurrentWindow().loadSettings.windowState = JSON.stringify(@state)
loadStateSync: ->
startTime = Date.now()
if stateKey = @getStateKey(@getLoadSettings().initialPaths)
if state = @getStorageFolder().load(stateKey)
@state = state
if not @state? and windowState = @getLoadSettings().windowState
try
if state = JSON.parse(@getLoadSettings().windowState)
@state = state
catch error
console.warn "Error parsing window state: #{statePath} #{error.stack}", error
@deserializeTimings.atom = Date.now() - startTime
getStateKey: (paths) ->
if paths?.length > 0
sha1 = crypto.createHash('sha1').update(paths.slice().sort().join("\n")).digest('hex')
"editor-#{sha1}"
else
null
getConfigDirPath: ->
@configDirPath ?= process.env.ATOM_HOME
getStorageFolder: ->
@storageFolder ?= new StorageFolder(@getConfigDirPath())
crashMainProcess: ->
remote.process.crash()

View File

@ -15,9 +15,10 @@ process.env.NODE_PATH = exportsPath
process.env.NODE_ENV ?= 'production' unless devMode
Atom = require './atom'
window.atom = Atom.loadOrCreate('editor')
window.atom = new Atom
atom.displayWindow() unless isSpec
atom.displayWindow()
atom.loadStateSync()
atom.startEditorWindow()
# Workaround for focus getting cleared upon window creation

View File

@ -3,10 +3,15 @@ require('crash-reporter').start(productName: 'Atom', companyName: 'GitHub')
path = require 'path'
ipc = require 'ipc'
ipc.send('call-window-method', 'openDevTools')
try
require '../src/window'
Atom = require '../src/atom'
window.atom = Atom.loadOrCreate('spec')
window.atom = new Atom
# Show window synchronously so a focusout doesn't fire on input elements
# that are focused in the very first spec run.