Comparar commits

..

1 Commits

Autor SHA1 Mensagem Data
Ivan Zuzak 0a0e848e7b Show devtools console for all console errors 2014-06-23 12:58:26 +02:00
233 arquivos alterados com 16127 adições e 19540 exclusões
-1
Ver Arquivo
@@ -1 +0,0 @@
v0.10.21
-1
Ver Arquivo
@@ -11,7 +11,6 @@ pairs:
bo: Ben Ogle; benogle
jr: Jason Rudolph; jasonrudolph
jl: Jessica Lord; jlord
dh: Daniel Hengeveld; danielh
email:
domain: github.com
#global: true
-27
Ver Arquivo
@@ -6,36 +6,10 @@ Visit [atom.io](https://atom.io) to learn more.
## Installing
### Mac OS X
Download the latest [Atom release](https://github.com/atom/atom/releases/latest).
Atom will automatically update when a new release is available.
### Windows
Install the [Atom chocolatey package](https://chocolatey.org/packages/Atom).
1. Install [chocolatey](https://chocolatey.org).
2. Close and reopen your command prompt or PowerShell window.
3. Run `cinst Atom`
4. In the future run `cup Atom` to upgrade to the latest release.
You can also download a `.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
The Windows version does not currently automatically update so you will need to
manually upgrade to future releases by re-downloading the `.zip` file.
### Debian Linux (Ubuntu)
Currently only a 64-bit version is available.
1. Download `atom-amd64.deb` from the [Atom releases page](https://github.com/atom/atom/releases/latest).
2. Run `sudo dpkg --install atom-amd64.deb` on the downloaded package.
3. Launch Atom using the installed `atom` command.
The Linux version does not currently automatically update so you will need to
repeat these steps to upgrade to future releases.
## Building
* [Linux](docs/build-instructions/linux.md)
@@ -44,5 +18,4 @@ repeat these steps to upgrade to future releases.
* [Windows](docs/build-instructions/windows.md)
## Developing
Check out the [guides](https://atom.io/docs/latest) and the [API reference](https://atom.io/docs/api).
+2 -2
Ver Arquivo
@@ -1,11 +1,11 @@
{
"name": "atom-bundled-apm",
"description": "Atom's bundled apm",
"description": "Atom's bundled APM",
"repository": {
"type": "git",
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
"atom-package-manager": "0.101.0"
"atom-package-manager": "0.69.0"
}
}
+3 -8
Ver Arquivo
@@ -50,7 +50,7 @@ if [ $OS == 'Mac' ]; then
# If ATOM_PATH isn't a executable file, use spotlight to search for Atom
if [ ! -x "$ATOM_PATH/$ATOM_APP_NAME" ]; then
ATOM_PATH=$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | grep -v ShipIt | head -1 | xargs dirname)
ATOM_PATH=$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | head -1 | xargs dirname)
fi
# Exit if Atom can't be found
@@ -69,11 +69,6 @@ elif [ $OS == 'Linux' ]; then
SCRIPT=$(readlink -f "$0")
USR_DIRECTORY=$(readlink -f $(dirname $SCRIPT)/..)
ATOM_PATH="$USR_DIRECTORY/share/atom/atom"
DOT_ATOM_DIR="$HOME/.atom"
if [ ! -d "$DOT_ATOM_DIR" ]; then
mkdir -p "$DOT_ATOM_DIR"
fi
: ${TMPDIR:=/tmp}
@@ -84,9 +79,9 @@ elif [ $OS == 'Linux' ]; then
exit $?
else
(
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$DOT_ATOM_DIR/nohup.out" 2>&1
nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$TMPDIR/atom-nohup.out" 2>&1
if [ $? -ne 0 ]; then
cat "$DOT_ATOM_DIR/nohup.out"
cat "$TMPDIR/atom-nohup.out"
exit $?
fi
) &
+3 -2
Ver Arquivo
@@ -1,6 +1,6 @@
require '../src/window'
Atom = require '../src/atom'
window.atom = Atom.loadOrCreate('spec')
atom = new Atom()
atom.show() unless atom.getLoadSettings().exitWhenDone
window.atom = atom
@@ -9,4 +9,5 @@ window.atom = atom
atom.openDevTools()
document.title = "Benchmark Suite"
runSpecSuite('../benchmark/benchmark-suite', atom.getLoadSettings().logFile)
benchmarkSuite = require.resolve('./benchmark-suite')
runSpecSuite(benchmarkSuite, true)
+2 -4
Ver Arquivo
@@ -1,9 +1,7 @@
require '../spec/spec-helper'
path = require 'path'
{$, Point} = require 'atom'
_ = require 'underscore-plus'
fs = require 'fs-plus'
{$, _, Point, fs} = require 'atom'
Project = require '../src/project'
TokenizedBuffer = require '../src/tokenized-buffer'
@@ -103,7 +101,7 @@ $.fn.resultOfTrigger = (type) ->
event.result
$.fn.enableKeymap = ->
@on 'keydown', (e) -> window.keymap.handleKeyEvent(e)
@on 'keydown', (e) => window.keymap.handleKeyEvent(e)
$.fn.attachToDom = ->
$('#jasmine-content').append(this)
+10 -10
Ver Arquivo
@@ -7,7 +7,7 @@ describe "editorView.", ->
beforeEach ->
atom.workspaceViewParentSelector = '#jasmine-content'
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
atom.workspaceView = new WorkspaceView
atom.workspaceView.attachToDom()
atom.workspaceView.width(1024)
@@ -53,7 +53,7 @@ describe "editorView.", ->
describe "at-end.", ->
beforeEach ->
editorView.moveToBottom()
editorView.moveCursorToBottom()
benchmark "insert-delete", ->
editorView.insertText('"')
@@ -62,8 +62,8 @@ describe "editorView.", ->
describe "empty-vs-set-innerHTML.", ->
[firstRow, lastRow] = []
beforeEach ->
firstRow = editorView.getModel().getFirstVisibleScreenRow()
lastRow = editorView.getModel().getLastVisibleScreenRow()
firstRow = editorView.getFirstVisibleScreenRow()
lastRow = editorView.getLastVisibleScreenRow()
benchmark "build-gutter-html.", 1000, ->
editorView.gutter.renderLineNumbers(null, firstRow, lastRow)
@@ -97,13 +97,13 @@ describe "editorView.", ->
describe "multiple-lines.", ->
[firstRow, lastRow] = []
beforeEach ->
firstRow = editorView.getModel().getFirstVisibleScreenRow()
lastRow = editorView.getModel().getLastVisibleScreenRow()
firstRow = editorView.getFirstVisibleScreenRow()
lastRow = editorView.getLastVisibleScreenRow()
benchmark "cache-entire-visible-area", 100, ->
for i in [firstRow..lastRow]
line = editorView.lineElementForScreenRow(i)[0]
editorView.positionLeftForLineAndColumn(line, i, Math.max(0, editorView.getModel().lineTextForBufferRow(i).length))
editorView.positionLeftForLineAndColumn(line, i, Math.max(0, editorView.lineLengthForBufferRow(i)))
describe "text-rendering.", ->
beforeEach ->
@@ -178,7 +178,7 @@ describe "editorView.", ->
atom.workspaceView.openSync('huge.js')
benchmark "moving-to-eof.", 1, ->
editorView.moveToBottom()
editorView.moveCursorToBottom()
describe "on-first-line.", ->
benchmark "inserting-newline", 5, ->
@@ -195,11 +195,11 @@ describe "editorView.", ->
endPosition = null
beforeEach ->
editorView.moveToBottom()
editorView.moveCursorToBottom()
endPosition = editorView.getCursorScreenPosition()
benchmark "move-to-beginning-of-word", ->
editorView.moveToBeginningOfWord()
editorView.moveCursorToBeginningOfWord()
editorView.setCursorScreenPosition(endPosition)
benchmark "insert", ->
-56
Ver Arquivo
@@ -1,56 +0,0 @@
#!/usr/bin/env coffee
{spawn, exec} = require 'child_process'
fs = require 'fs'
os = require 'os'
path = require 'path'
_ = require 'underscore-plus'
temp = require 'temp'
directoryToOpen = temp.mkdirSync('browser-process-startup-')
socketPath = path.join(os.tmpdir(), 'atom.sock')
numberOfRuns = 10
deleteSocketFile = ->
try
fs.unlinkSync(socketPath) if fs.existsSync(socketPath)
catch error
console.error(error)
launchAtom = (callback) ->
deleteSocketFile()
cmd = 'atom'
args = ['--safe', '--new-window', '--foreground', directoryToOpen]
atomProcess = spawn(cmd, args)
output = ''
startupTimes = []
dataListener = (data) ->
output += data
if match = /App load time: (\d+)/.exec(output)
startupTime = parseInt(match[1])
atomProcess.stderr.removeListener 'data', dataListener
atomProcess.kill()
exec 'pkill -9 Atom', (error) ->
console.error(error) if error?
callback(startupTime)
atomProcess.stderr.on 'data', dataListener
startupTimes = []
collector = (startupTime) ->
startupTimes.push(startupTime)
if startupTimes.length < numberOfRuns
launchAtom(collector)
else
maxTime = _.max(startupTimes)
minTime = _.min(startupTimes)
totalTime = startupTimes.reduce (previousValue=0, currentValue) -> previousValue + currentValue
console.log "Startup Runs: #{startupTimes.length}"
console.log "First run time: #{startupTimes[0]}ms"
console.log "Max time: #{maxTime}ms"
console.log "Min time: #{minTime}ms"
console.log "Average time: #{Math.round(totalTime/startupTimes.length)}ms"
launchAtom(collector)
+12 -29
Ver Arquivo
@@ -39,31 +39,21 @@ module.exports = (grunt) ->
tmpDir = os.tmpdir()
appName = if process.platform is 'darwin' then 'Atom.app' else 'Atom'
buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build')
buildDir = path.resolve(buildDir)
installDir = grunt.option('install-dir')
home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME
atomShellDownloadDir = path.join(home, '.atom', 'atom-shell')
atomShellDownloadDir = path.join(os.tmpdir(), 'atom-cached-atom-shells')
symbolsDir = path.join(buildDir, 'Atom.breakpad.syms')
shellAppDir = path.join(buildDir, appName)
if process.platform is 'win32'
contentsDir = shellAppDir
appDir = path.join(shellAppDir, 'resources', 'app')
installDir ?= path.join(process.env.ProgramFiles, appName)
killCommand = 'taskkill /F /IM atom.exe'
installDir = path.join(process.env.ProgramFiles, appName)
else if process.platform is 'darwin'
contentsDir = path.join(shellAppDir, 'Contents')
appDir = path.join(contentsDir, 'Resources', 'app')
installDir ?= path.join('/Applications', appName)
killCommand = 'pkill -9 Atom'
installDir = path.join('/Applications', appName)
else
contentsDir = shellAppDir
appDir = path.join(shellAppDir, 'resources', 'app')
installDir ?= process.env.INSTALL_PREFIX ? '/usr/local'
killCommand ='pkill -9 atom'
installDir = path.resolve(installDir)
installDir = process.env.INSTALL_PREFIX ? '/usr/local'
coffeeConfig =
glob_to_multiple:
@@ -99,8 +89,6 @@ module.exports = (grunt) ->
csonConfig =
options:
rootObject: true
cachePath: path.join(home, '.atom', 'compile-cache', 'grunt-cson')
glob_to_multiple:
expand: true
src: [
@@ -133,8 +121,6 @@ module.exports = (grunt) ->
atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir}
docsOutputDir: 'docs/output'
coffee: coffeeConfig
less: lessConfig
@@ -147,7 +133,12 @@ module.exports = (grunt) ->
coffeelint:
options:
configFile: 'coffeelint.json'
no_empty_param_list:
level: 'error'
max_line_length:
level: 'ignore'
indentation:
level: 'ignore'
src: [
'dot-atom/**/*.coffee'
'exports/**/*.coffee'
@@ -219,7 +210,7 @@ module.exports = (grunt) ->
shell:
'kill-atom':
command: killCommand
command: 'pkill -9 Atom'
options:
stdout: false
stderr: false
@@ -228,17 +219,9 @@ module.exports = (grunt) ->
grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson', 'peg'])
grunt.registerTask('lint', ['coffeelint', 'csslint', 'lesslint'])
grunt.registerTask('test', ['shell:kill-atom', 'run-specs'])
grunt.registerTask('ci', ['output-disk-space', 'download-atom-shell', 'build', 'dump-symbols', 'set-version', 'check-licenses', 'lint', 'test', 'codesign', 'publish-build'])
grunt.registerTask('docs', ['markdown:guides', 'build-docs'])
ciTasks = ['output-disk-space', 'download-atom-shell', 'build']
ciTasks.push('dump-symbols') if process.platform isnt 'win32'
ciTasks.push('set-version', 'check-licenses', 'lint')
ciTasks.push('mkdeb') if process.platform is 'linux'
ciTasks.push('test') if process.platform is 'darwin'
ciTasks.push('codesign')
ciTasks.push('publish-build')
grunt.registerTask('ci', ciTasks)
defaultTasks = ['download-atom-shell', 'build', 'set-version']
defaultTasks.push 'install' unless process.platform is 'linux'
grunt.registerTask('default', defaultTasks)
+10 -12
Ver Arquivo
@@ -7,17 +7,17 @@
},
"dependencies": {
"async": "~0.2.9",
"donna": "1.0.1",
"biscotto": ">=2.1.1 <3.0",
"formidable": "~1.0.14",
"fs-plus": "2.x",
"github-releases": "~0.2.0",
"grunt": "~0.4.1",
"grunt-cli": "~0.1.9",
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
"grunt-contrib-coffee": "~0.9.0",
"grunt-coffeelint": "git://github.com/atom/grunt-coffeelint.git",
"grunt-contrib-csslint": "~0.1.2",
"grunt-contrib-coffee": "~0.9.0",
"grunt-contrib-less": "~0.8.0",
"grunt-cson": "0.10.0",
"grunt-cson": "0.8.0",
"grunt-download-atom-shell": "~0.8.0",
"grunt-lesslint": "0.13.0",
"grunt-markdown": "~0.4.0",
@@ -26,18 +26,16 @@
"harmony-collections": "~0.3.8",
"json-front-matter": "~0.1.3",
"legal-eagle": "~0.4.0",
"minidump": "~0.8",
"normalize-package-data": "0.2.12",
"npm": "~1.4.5",
"rcedit": "~0.1.2",
"minidump": "~0.7",
"read-package-json": "1.1.8",
"normalize-package-data": "0.2.12",
"rcedit": "~0.1.2",
"request": "~2.27.0",
"rimraf": "~2.2.2",
"runas": "~1.0.1",
"tello": "1.0.3",
"temp": "~0.8.1",
"runas": "0.5.x",
"underscore-plus": "1.x",
"unzip": "~0.1.9",
"vm-compatibility-layer": "~0.1.0"
"vm-compatibility-layer": "~0.1.0",
"npm": "~1.4.5"
}
}
+11 -74
Ver Arquivo
@@ -14,9 +14,9 @@ module.exports = (grunt) ->
mkdir path.dirname(buildDir)
if process.platform is 'darwin'
cp 'atom-shell/Atom.app', shellAppDir, filter: /default_app/
cp 'atom-shell/Atom.app', shellAppDir
else
cp 'atom-shell', shellAppDir, filter: /default_app/
cp 'atom-shell', shellAppDir
mkdir appDir
@@ -45,45 +45,19 @@ module.exports = (grunt) ->
path.join('git-utils', 'deps')
path.join('oniguruma', 'deps')
path.join('less', 'dist')
path.join('less', 'test')
path.join('bootstrap', 'docs')
path.join('bootstrap', '_config.yml')
path.join('bootstrap', '_includes')
path.join('bootstrap', '_layouts')
path.join('npm', 'doc')
path.join('npm', 'html')
path.join('npm', 'man')
path.join('npm', 'node_modules', '.bin', 'beep')
path.join('npm', 'node_modules', '.bin', 'clear')
path.join('npm', 'node_modules', '.bin', 'starwars')
path.join('bootstrap', 'examples')
path.join('pegjs', 'examples')
path.join('plist', 'tests')
path.join('xmldom', 'test')
path.join('jasmine-reporters', 'ext')
path.join('jasmine-node', 'node_modules', 'gaze')
path.join('jasmine-node', 'spec')
path.join('node_modules', 'nan')
path.join('build', 'binding.Makefile')
path.join('build', 'config.gypi')
path.join('build', 'gyp-mac-tool')
path.join('build', 'Makefile')
path.join('build', 'Release', 'obj.target')
path.join('build', 'Release', 'obj')
path.join('build', 'Release', '.deps')
path.join('vendor', 'apm')
path.join('resources', 'mac')
path.join('resources', 'win')
# These are only require in dev mode when the grammar isn't precompiled
path.join('atom-keymap', 'node_modules', 'loophole')
path.join('atom-keymap', 'node_modules', 'pegjs')
path.join('atom-keymap', 'node_modules', '.bin', 'pegjs')
path.join('snippets', 'node_modules', 'loophole')
path.join('snippets', 'node_modules', 'pegjs')
path.join('snippets', 'node_modules', '.bin', 'pegjs')
'.DS_Store'
'.jshintrc'
'.npmignore'
'.pairs'
'.travis.yml'
]
ignoredPaths = ignoredPaths.map (ignoredPath) -> _.escapeRegExp(ignoredPath)
@@ -91,56 +65,21 @@ module.exports = (grunt) ->
ignoredPaths.push "#{_.escapeRegExp(path.join('spellchecker', 'vendor', 'hunspell') + path.sep)}.*"
ignoredPaths.push "#{_.escapeRegExp(path.join('build', 'Release') + path.sep)}.*\\.pdb"
# Ignore *.cc and *.h files from native modules
ignoredPaths.push "#{_.escapeRegExp(path.join('ctags', 'src') + path.sep)}.*\\.(cc|h)*"
ignoredPaths.push "#{_.escapeRegExp(path.join('git-utils', 'src') + path.sep)}.*\\.(cc|h)*"
ignoredPaths.push "#{_.escapeRegExp(path.join('keytar', 'src') + path.sep)}.*\\.(cc|h)*"
ignoredPaths.push "#{_.escapeRegExp(path.join('nslog', 'src') + path.sep)}.*\\.(cc|h)*"
ignoredPaths.push "#{_.escapeRegExp(path.join('oniguruma', 'src') + path.sep)}.*\\.(cc|h)*"
ignoredPaths.push "#{_.escapeRegExp(path.join('pathwatcher', 'src') + path.sep)}.*\\.(cc|h)*"
ignoredPaths.push "#{_.escapeRegExp(path.join('runas', 'src') + path.sep)}.*\\.(cc|h)*"
ignoredPaths.push "#{_.escapeRegExp(path.join('scrollbar-style', 'src') + path.sep)}.*\\.(cc|h)*"
ignoredPaths.push "#{_.escapeRegExp(path.join('spellchecker', 'src') + path.sep)}.*\\.(cc|h)*"
# Ignore build files
ignoredPaths.push "#{_.escapeRegExp(path.sep)}binding\\.gyp$"
ignoredPaths.push "#{_.escapeRegExp(path.sep)}.+\\.target.mk$"
ignoredPaths.push "#{_.escapeRegExp(path.sep)}linker\\.lock$"
ignoredPaths.push "#{_.escapeRegExp(path.join('build', 'Release') + path.sep)}.+\\.node\\.dSYM"
# Hunspell dictionaries are only not needed on OS X.
if process.platform is 'darwin'
ignoredPaths.push path.join('spellchecker', 'vendor', 'hunspell_dictionaries')
ignoredPaths = ignoredPaths.map (ignoredPath) -> "(#{ignoredPath})"
testFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}te?sts?#{_.escapeRegExp(path.sep)}")
exampleFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}examples?#{_.escapeRegExp(path.sep)}")
benchmarkFolderPattern = new RegExp("#{_.escapeRegExp(path.sep)}benchmarks?#{_.escapeRegExp(path.sep)}")
nodeModulesFilter = new RegExp(ignoredPaths.join('|'))
filterNodeModule = (pathToCopy) ->
return true if benchmarkFolderPattern.test(pathToCopy)
pathToCopy = path.resolve(pathToCopy)
nodeModulesFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
packageFilter = new RegExp("(#{ignoredPaths.join('|')})|(.+\\.(cson|coffee)$)")
filterPackage = (pathToCopy) ->
return true if benchmarkFolderPattern.test(pathToCopy)
pathToCopy = path.resolve(pathToCopy)
packageFilter.test(pathToCopy) or testFolderPattern.test(pathToCopy) or exampleFolderPattern.test(pathToCopy)
for directory in nonPackageDirectories
cp directory, path.join(appDir, directory), filter: filterNodeModule
cp directory, path.join(appDir, directory), filter: nodeModulesFilter
for directory in packageDirectories
cp directory, path.join(appDir, directory), filter: filterPackage
cp directory, path.join(appDir, directory), filter: packageFilter
cp 'spec', path.join(appDir, 'spec')
cp 'src', path.join(appDir, 'src'), filter: /.+\.(cson|coffee)$/
cp 'static', path.join(appDir, 'static')
cp 'apm', path.join(appDir, 'apm'), filter: filterNodeModule
cp 'apm', path.join(appDir, 'apm'), filter: nodeModulesFilter
if process.platform is 'darwin'
grunt.file.recurse path.join('resources', 'mac'), (sourcePath, rootDirectory, subDirectory='', filename) ->
@@ -148,10 +87,8 @@ module.exports = (grunt) ->
grunt.file.copy(sourcePath, path.resolve(appDir, '..', subDirectory, filename))
if process.platform is 'win32'
# Set up chocolatey ignore and gui files
fs.writeFileSync path.join(appDir, 'apm', 'node_modules', 'atom-package-manager', 'bin', 'node.exe.ignore'), ''
fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), ''
fs.writeFileSync path.join(shellAppDir, 'atom.exe.gui'), ''
cp path.join('resources', 'win', 'msvcp100.dll'), path.join(shellAppDir, 'msvcp100.dll')
cp path.join('resources', 'win', 'msvcr100.dll'), path.join(shellAppDir, 'msvcr100.dll')
dependencies = ['compile', "generate-license:save"]
dependencies.push('copy-info-plist') if process.platform is 'darwin'
+6 -25
Ver Arquivo
@@ -1,13 +1,12 @@
path = require 'path'
fs = require 'fs-plus'
module.exports = (grunt) ->
{spawn} = require('./task-helpers')(grunt)
grunt.registerTask 'codesign', 'Codesign the app', ->
return unless process.platform is 'darwin'
done = @async()
if process.platform is 'darwin' and process.env.XCODE_KEYCHAIN
if process.env.XCODE_KEYCHAIN
unlockKeychain (error) ->
if error?
done(error)
@@ -23,24 +22,6 @@ module.exports = (grunt) ->
spawn {cmd, args}, (error) -> callback(error)
signApp = (callback) ->
switch process.platform
when 'darwin'
cmd = 'codesign'
args = ['--deep', '--force', '--verbose', '--sign', 'Developer ID Application: GitHub', grunt.config.get('atom.shellAppDir')]
spawn {cmd, args}, (error) -> callback(error)
when 'win32'
spawn {cmd: 'taskkill', args: ['/F', '/IM', 'atom.exe']}, ->
cmd = process.env.JANKY_SIGNTOOL ? 'signtool'
args = [path.join(grunt.config.get('atom.shellAppDir'), 'atom.exe')]
spawn {cmd, args}, (error) ->
return callback(error) if error?
setupExePath = path.join(grunt.config.get('atom.shellAppDir'), '..', 'Releases', 'setup.exe')
if fs.isFileSync(setupExePath)
args = [setupExePath]
spawn {cmd, args}, (error) -> callback(error)
else
callback()
else
callback()
cmd = 'codesign'
args = ['-f', '-v', '-s', 'Developer ID Application: GitHub', grunt.config.get('atom.shellAppDir')]
spawn {cmd, args}, (error) -> callback(error)
-41
Ver Arquivo
@@ -1,41 +0,0 @@
fs = require 'fs'
path = require 'path'
_ = require 'underscore-plus'
module.exports = (grunt) ->
{spawn, rm} = require('./task-helpers')(grunt)
grunt.registerTask 'create-installer', 'Create the Windows installer', ->
return unless process.platform is 'win32'
done = @async()
buildDir = grunt.config.get('atom.buildDir')
atomDir = path.join(buildDir, 'Atom')
packageInfo = grunt.file.readJSON(path.join(atomDir, 'resources', 'app', 'package.json'))
inputTemplate = grunt.file.read(path.join('build', 'windows', 'atom.nuspec.erb'))
# NB: Build server has some sort of stamp on the version number
packageInfo.version = packageInfo.version.replace(/-.*$/, '')
targetNuspecPath = path.join(buildDir, 'atom.nuspec')
grunt.file.write(targetNuspecPath, _.template(inputTemplate, packageInfo))
cmd = 'build/windows/nuget.exe'
args = ['pack', targetNuspecPath, '-BasePath', atomDir, '-OutputDirectory', buildDir]
spawn {cmd, args}, (error, result, code) ->
return done(error) if error?
pkgs = pkg for pkg in fs.readdirSync(buildDir) when path.extname(pkg) is '.nupkg'
releasesDir = path.join(buildDir, 'Releases')
# NB: Gonna clear Releases for now, in the future we need to pull down
# the existing version
rm(releasesDir)
cmd = 'build/windows/update.com'
args = ['--releasify', path.join(buildDir, pkgs), '-r', releasesDir, '-g', 'build/windows/install-spinner.gif']
spawn {cmd, args}, (error, result, code) -> done(error)
+150 -30
Ver Arquivo
@@ -1,40 +1,160 @@
path = require 'path'
async = require 'async'
fs = require 'fs-plus'
_ = require 'underscore-plus'
donna = require 'donna'
tello = require 'tello'
request = require 'request'
module.exports = (grunt) ->
getClassesToInclude = ->
modulesPath = path.resolve(__dirname, '..', '..', 'node_modules')
classes = {}
fs.traverseTreeSync modulesPath, (modulePath) ->
return false if modulePath.match(/node_modules/g).length > 1 # dont need the dependencies of the dependencies
return true unless path.basename(modulePath) is 'package.json'
return true unless fs.isFileSync(modulePath)
{rm} = require('./task-helpers')(grunt)
apiPath = path.join(path.dirname(modulePath), 'api.json')
if fs.isFileSync(apiPath)
_.extend(classes, grunt.file.readJSON(apiPath).classes)
true
classes
sortClasses = (classes) ->
sortedClasses = {}
for className in Object.keys(classes).sort()
sortedClasses[className] = classes[className]
sortedClasses
cmd = path.join('node_modules', '.bin', 'coffee')
commonArgs = [path.join('build', 'node_modules', '.bin', 'biscotto'), '--']
opts =
stdio: 'inherit'
grunt.registerTask 'build-docs', 'Builds the API docs in src', ->
docsOutputDir = grunt.config.get('docsOutputDir')
done = @async()
metadata = donna.generateMetadata(['.'])
api = tello.digest(metadata)
_.extend(api.classes, getClassesToInclude())
api.classes = sortClasses(api.classes)
downloadIncludes (error, includePaths) ->
if error?
done(error)
else
rm('docs/output/api')
args = [
commonArgs...
'--title', 'Atom API Documentation'
'-o', 'docs/output/api'
'-r', 'docs/README.md'
'--stability', '1'
'src/'
includePaths...
]
grunt.util.spawn({cmd, args, opts}, done)
apiJson = JSON.stringify(api, null, 2)
apiJsonPath = path.join(docsOutputDir, 'api.json')
grunt.file.write(apiJsonPath, apiJson)
grunt.registerTask 'lint-docs', 'Generate stats about the doc coverage', ->
done = @async()
downloadIncludes (error, includePaths) ->
if error?
done(error)
else
args = [
commonArgs...
'--noOutput'
'src/'
includePaths...
]
grunt.util.spawn({cmd, args, opts}, done)
grunt.registerTask 'missing-docs', 'Generate stats about the doc coverage', ->
done = @async()
downloadIncludes (error, includePaths) ->
if error?
done(error)
else
args = [
commonArgs...
'--noOutput'
'--missing'
'src/'
includePaths...
]
grunt.util.spawn({cmd, args, opts}, done)
grunt.registerTask 'copy-docs', 'Copies over latest API docs to atom-docs', ->
done = @async()
fetchTag = (args..., callback) ->
cmd = 'git'
args = ['describe', '--abbrev=0', '--tags']
grunt.util.spawn {cmd, args}, (error, result) ->
if error?
callback(error)
else
callback(null, String(result).trim())
copyDocs = (tag, callback) ->
cmd = 'cp'
args = ['-r', 'docs/output/', "../atom.io/public/docs/api/#{tag}/"]
fs.exists "../atom.io/public/docs/api/", (exists) ->
if exists
grunt.util.spawn {cmd, args}, (error, result) ->
if error?
callback(error)
else
callback(null, tag)
else
grunt.log.error "../atom.io/public/docs/api/ doesn't exist"
return false
grunt.util.async.waterfall [fetchTag, copyDocs], done
grunt.registerTask 'deploy-docs', 'Publishes latest API docs to atom-docs.githubapp.com', ->
done = @async()
docsRepoArgs = ['--work-tree=../atom-docs/', '--git-dir=../atom-docs/.git/']
fetchTag = (args..., callback) ->
cmd = 'git'
args = ['describe', '--abbrev=0', '--tags']
grunt.util.spawn {cmd, args}, (error, result) ->
if error?
callback(error)
else
callback(null, String(result).trim().split('.')[0..1].join('.'))
stageDocs = (tag, callback) ->
cmd = 'git'
args = [docsRepoArgs..., 'add', "public/#{tag}"]
grunt.util.spawn({cmd, args, opts}, callback)
fetchSha = (args..., callback) ->
cmd = 'git'
args = ['rev-parse', 'HEAD']
grunt.util.spawn {cmd, args}, (error, result) ->
if error?
callback(error)
else
callback(null, String(result).trim())
commitChanges = (sha, callback) ->
cmd = 'git'
args = [docsRepoArgs..., 'commit', "-m Update API docs to #{sha}"]
grunt.util.spawn({cmd, args, opts}, callback)
pushOrigin = (args..., callback) ->
cmd = 'git'
args = [docsRepoArgs..., 'push', 'origin', 'master']
grunt.util.spawn({cmd, args, opts}, callback)
pushHeroku = (args..., callback) ->
cmd = 'git'
args = [docsRepoArgs..., 'push', 'heroku', 'master']
grunt.util.spawn({cmd, args, opts}, callback)
grunt.util.async.waterfall [fetchTag, stageDocs, fetchSha, commitChanges, pushOrigin, pushHeroku], done
downloadFileFromRepo = ({repo, file}, callback) ->
uri = "https://raw.github.com/atom/#{repo}/master/#{file}"
request uri, (error, response, contents) ->
return callback(error) if error?
downloadPath = path.join('docs', 'includes', repo, file)
fs.writeFile downloadPath, contents, (error) ->
callback(error, downloadPath)
downloadIncludes = (callback) ->
includes = [
{repo: 'atom-keymap', file: 'src/keymap-manager.coffee'}
{repo: 'atom-keymap', file: 'src/key-binding.coffee'}
{repo: 'first-mate', file: 'src/grammar.coffee'}
{repo: 'first-mate', file: 'src/grammar-registry.coffee'}
{repo: 'node-pathwatcher', file: 'src/directory.coffee'}
{repo: 'node-pathwatcher', file: 'src/file.coffee'}
{repo: 'space-pen', file: 'src/space-pen.coffee'}
{repo: 'text-buffer', file: 'src/marker.coffee'}
{repo: 'text-buffer', file: 'src/point.coffee'}
{repo: 'text-buffer', file: 'src/range.coffee'}
{repo: 'text-buffer', file: 'src/text-buffer.coffee'}
{repo: 'theorist', file: 'src/model.coffee'}
]
async.map(includes, downloadFileFromRepo, callback)
+12 -18
Ver Arquivo
@@ -3,7 +3,11 @@ path = require 'path'
_ = require 'underscore-plus'
fs = require 'fs-plus'
runas = null
temp = require 'temp'
fillTemplate = (filePath, data) ->
template = _.template(String(fs.readFileSync(filePath + '.in')))
filled = template(data)
fs.writeFileSync(filePath, filled)
module.exports = (grunt) ->
{cp, mkdir, rm} = require('./task-helpers')(grunt)
@@ -11,7 +15,6 @@ module.exports = (grunt) ->
grunt.registerTask 'install', 'Install the built application', ->
installDir = grunt.config.get('atom.installDir')
shellAppDir = grunt.config.get('atom.shellAppDir')
if process.platform is 'win32'
runas ?= require 'runas'
copyFolder = path.resolve 'script', 'copy-folder.cmd'
@@ -23,16 +26,13 @@ module.exports = (grunt) ->
else if process.platform is 'darwin'
rm installDir
mkdir path.dirname(installDir)
tempFolder = temp.path()
mkdir tempFolder
cp shellAppDir, tempFolder
fs.renameSync(tempFolder, installDir)
cp shellAppDir, installDir
else
binDir = path.join(installDir, 'bin')
shareDir = path.join(installDir, 'share', 'atom')
iconName = path.join(shareDir,'resources','app','resources','atom.png')
desktopFile = path.join('resources', 'linux', 'Atom.desktop')
mkdir binDir
cp 'atom.sh', path.join(binDir, 'atom')
@@ -40,19 +40,13 @@ module.exports = (grunt) ->
mkdir path.dirname(shareDir)
cp shellAppDir, shareDir
# Create Atom.desktop if installation not in temporary folder
# Create Atom.desktop if installation in '/usr/local'
applicationsDir = path.join('/usr','share','applications')
tmpDir = if process.env.TMPDIR? then process.env.TMPDIR else '/tmp'
if installDir.indexOf(tmpDir) isnt 0
desktopFile = path.join('resources', 'linux', 'Atom.desktop.in')
desktopInstallFile = path.join(installDir, 'share', 'applications', 'Atom.desktop')
if installDir.indexOf(tmpDir) isnt 0 and fs.isDirectorySync(applicationsDir)
{description} = grunt.file.readJSON('package.json')
iconName = path.join(shareDir, 'resources', 'app', 'resources', 'atom.png')
installDir = path.join(installDir, '.') # To prevent "Exec=/usr/local//share/atom/atom"
template = _.template(String(fs.readFileSync(desktopFile)))
filled = template({description, installDir, iconName})
grunt.file.write(desktopInstallFile, filled)
fillTemplate(desktopFile, {description, installDir, iconName})
cp desktopFile, path.join(applicationsDir,'Atom.desktop')
# Create relative symbol link for apm.
process.chdir(binDir)
+16 -29
Ver Arquivo
@@ -2,27 +2,16 @@ fs = require 'fs'
path = require 'path'
_ = require 'underscore-plus'
fillTemplate = (filePath, data) ->
template = _.template(String(fs.readFileSync(filePath + '.in')))
filled = template(data)
fs.writeFileSync(filePath, filled)
module.exports = (grunt) ->
{spawn} = require('./task-helpers')(grunt)
fillTemplate = (filePath, data) ->
template = _.template(String(fs.readFileSync("#{filePath}.in")))
filled = template(data)
outputPath = path.join(grunt.config.get('atom.buildDir'), path.basename(filePath))
grunt.file.write(outputPath, filled)
outputPath
getInstalledSize = (buildDir, callback) ->
cmd = 'du'
args = ['-sk', path.join(buildDir, 'Atom')]
spawn {cmd, args}, (error, {stdout}) ->
installedSize = stdout.split(/\s+/)?[0] or '200000' # default to 200MB
callback(null, installedSize)
grunt.registerTask 'mkdeb', 'Create debian package', ->
done = @async()
buildDir = grunt.config.get('atom.buildDir')
if process.arch is 'ia32'
arch = 'i386'
@@ -36,17 +25,15 @@ module.exports = (grunt) ->
maintainer = 'GitHub <atom@github.com>'
installDir = '/usr'
iconName = 'atom'
getInstalledSize buildDir, (error, installedSize) ->
data = {name, version, description, section, arch, maintainer, installDir, iconName, installedSize}
controlFilePath = fillTemplate(path.join('resources', 'linux', 'debian', 'control'), data)
desktopFilePath = fillTemplate(path.join('resources', 'linux', 'Atom.desktop'), data)
icon = path.join('resources', 'atom.png')
data = {name, version, description, section, arch, maintainer, installDir, iconName}
cmd = path.join('script', 'mkdeb')
args = [version, arch, controlFilePath, desktopFilePath, icon, buildDir]
spawn {cmd, args}, (error) ->
if error?
done(error)
else
grunt.log.ok "Created #{buildDir}/atom-#{version}-#{arch}.deb"
done()
control = path.join('resources', 'linux', 'debian', 'control')
fillTemplate(control, data)
desktop = path.join('resources', 'linux', 'Atom.desktop')
fillTemplate(desktop, data)
icon = path.join('resources', 'atom.png')
buildDir = grunt.config.get('atom.buildDir')
cmd = path.join('script', 'mkdeb')
args = [version, arch, control, desktop, icon, buildDir]
spawn({cmd, args}, done)
-21
Ver Arquivo
@@ -1,21 +0,0 @@
path = require 'path'
module.exports = (grunt) ->
grunt.registerTask 'output-build-filetypes', 'Log counts for each filetype in the built application', ->
shellAppDir = grunt.config.get('atom.shellAppDir')
types = {}
grunt.file.recurse shellAppDir, (absolutePath, rootPath, relativePath, fileName) ->
extension = path.extname(fileName) or fileName
types[extension] ?= 0
types[extension]++
extensions = Object.keys(types).sort (extension1, extension2) ->
diff = types[extension2] - types[extension1]
if diff is 0
extension1.toLowerCase().localeCompare(extension2.toLowerCase())
else
diff
extensions.forEach (extension) ->
grunt.log.error "#{extension}: #{types[extension]}"
-18
Ver Arquivo
@@ -1,18 +0,0 @@
path = require 'path'
module.exports = (grunt) ->
grunt.registerTask 'output-long-paths', 'Log long paths in the built application', ->
shellAppDir = grunt.config.get('atom.shellAppDir')
longPaths = []
grunt.file.recurse shellAppDir, (absolutePath, rootPath, relativePath, fileName) ->
if relativePath
fullPath = path.join(relativePath, fileName)
else
fullPath = fileName
longPaths.push(fullPath) if fullPath.length >= 200
longPaths.sort (longPath1, longPath2) -> longPath2.length - longPath1.length
longPaths.forEach (longPath) ->
grunt.log.error "#{longPath.length} character path: #{longPath}"
-2
Ver Arquivo
@@ -9,12 +9,10 @@ module.exports = (grunt) ->
['atom-dark-ui', 'atom-light-syntax']
['atom-dark-ui', 'solarized-dark-syntax']
['atom-dark-ui', 'base16-tomorrow-dark-theme']
['atom-dark-ui', 'base16-tomorrow-light-theme']
['atom-light-ui', 'atom-light-syntax']
['atom-light-ui', 'atom-dark-syntax']
['atom-light-ui', 'solarized-dark-syntax']
['atom-light-ui', 'base16-tomorrow-dark-theme']
['atom-light-ui', 'base16-tomorrow-light-theme']
]
directory = path.join(grunt.config.get('atom.appDir'), 'less-compile-cache')
+19 -49
Ver Arquivo
@@ -9,6 +9,16 @@ request = require 'request'
grunt = null
if process.platform is 'darwin'
assets = [
{assetName: 'atom-mac.zip', sourceName: 'Atom.app'}
{assetName: 'atom-mac-symbols.zip', sourceName: 'Atom.breakpad.syms'}
]
else
assets = [
{assetName: 'atom-windows.zip', sourceName: 'Atom'}
]
commitSha = process.env.JANKY_SHA1
token = process.env.ATOM_ACCESS_TOKEN
defaultHeaders =
@@ -17,25 +27,14 @@ defaultHeaders =
module.exports = (gruntObject) ->
grunt = gruntObject
{cp} = require('./task-helpers')(grunt)
grunt.registerTask 'publish-build', 'Publish the built app', ->
return if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH isnt 'master'
tasks = ['upload-assets']
tasks.unshift('build-docs', 'prepare-docs') if process.platform is 'darwin'
grunt.task.run(tasks)
grunt.registerTask 'prepare-docs', 'Move api.json to atom-api.json', ->
docsOutputDir = grunt.config.get('docsOutputDir')
buildDir = grunt.config.get('atom.buildDir')
cp path.join(docsOutputDir, 'api.json'), path.join(buildDir, 'atom-api.json')
grunt.registerTask 'upload-assets', 'Upload the assets to a GitHub release', ->
done = @async()
buildDir = grunt.config.get('atom.buildDir')
assets = getAssets()
zipAssets buildDir, assets, (error) ->
zipApps buildDir, assets, (error) ->
return done(error) if error?
getAtomDraftRelease (error, release) ->
return done(error) if error?
@@ -44,55 +43,26 @@ module.exports = (gruntObject) ->
return done(error) if error?
uploadAssets(release, buildDir, assets, done)
getAssets = ->
switch process.platform
when 'darwin'
[
{assetName: 'atom-mac.zip', sourcePath: 'Atom.app'}
{assetName: 'atom-mac-symbols.zip', sourcePath: 'Atom.breakpad.syms'}
{assetName: 'atom-api.json', sourcePath: 'atom-api.json'}
]
when 'win32'
[
{assetName: 'atom-windows.zip', sourcePath: 'Atom'}
]
when 'linux'
buildDir = grunt.config.get('atom.buildDir')
if process.arch is 'ia32'
arch = 'i386'
else
arch = 'amd64'
{version} = grunt.file.readJSON('package.json')
sourcePath = "#{buildDir}/atom-#{version}-#{arch}.deb"
assetName = "atom-#{arch}.deb"
{cp} = require('./task-helpers')(grunt)
cp sourcePath, path.join(buildDir, assetName)
[
{assetName, sourcePath}
]
logError = (message, error, details) ->
grunt.log.error(message)
grunt.log.error(error.message ? error) if error?
grunt.log.error(details) if details
zipAssets = (buildDir, assets, callback) ->
zip = (directory, sourcePath, assetName, callback) ->
zipApps = (buildDir, assets, callback) ->
zip = (directory, sourceName, assetName, callback) ->
if process.platform is 'win32'
zipCommand = "C:/psmodules/7z.exe a -r #{assetName} #{sourcePath}"
zipCommand = "C:/psmodules/7z.exe a -r #{assetName} #{sourceName}"
else
zipCommand = "zip -r --symlinks #{assetName} #{sourcePath}"
zipCommand = "zip -r --symlinks #{assetName} #{sourceName}"
options = {cwd: directory, maxBuffer: Infinity}
child_process.exec zipCommand, options, (error, stdout, stderr) ->
logError("Zipping #{sourcePath} failed", error, stderr) if error?
logError("Zipping #{sourceName} failed", error, stderr) if error?
callback(error)
tasks = []
for {assetName, sourcePath} in assets when path.extname(assetName) is '.zip'
for {assetName, sourceName} in assets
fs.removeSync(path.join(buildDir, assetName))
tasks.push(zip.bind(this, buildDir, sourcePath, assetName))
tasks.push(zip.bind(this, buildDir, sourceName, assetName))
async.parallel(tasks, callback)
getAtomDraftRelease = (callback) ->
@@ -157,7 +127,7 @@ uploadAssets = (release, buildDir, assets, callback) ->
fs.createReadStream(assetPath).pipe(assetRequest)
tasks = []
for {assetName} in assets
for {assetName, sourceName} in assets
assetPath = path.join(buildDir, assetName)
tasks.push(upload.bind(this, release, assetName, assetPath))
async.parallel(tasks, callback)
+2 -2
Ver Arquivo
@@ -45,8 +45,8 @@ module.exports = (grunt) ->
strings =
CompanyName: 'GitHub, Inc.'
FileDescription: 'Atom'
LegalCopyright: 'Copyright (C) 2014 GitHub, Inc. All rights reserved'
FileDescription: 'The hackable editor'
LegalCopyright: 'Copyright (C) 2013 GitHub, Inc. All rights reserved'
ProductName: 'Atom'
ProductVersion: version
+18 -24
Ver Arquivo
@@ -2,6 +2,7 @@ fs = require 'fs'
path = require 'path'
_ = require 'underscore-plus'
async = require 'async'
module.exports = (grunt) ->
@@ -9,27 +10,18 @@ module.exports = (grunt) ->
packageSpecQueue = null
getAppPath = ->
contentsDir = grunt.config.get('atom.contentsDir')
switch process.platform
when 'darwin'
path.join(contentsDir, 'MacOS', 'Atom')
when 'linux'
path.join(contentsDir, 'atom')
when 'win32'
path.join(contentsDir, 'atom.exe')
runPackageSpecs = (callback) ->
failedPackages = []
rootDir = grunt.config.get('atom.shellAppDir')
contentsDir = grunt.config.get('atom.contentsDir')
resourcePath = process.cwd()
appPath = getAppPath()
# Ensure application is executable on Linux
fs.chmodSync(appPath, '755') if process.platform is 'linux'
if process.platform is 'darwin'
appPath = path.join(contentsDir, 'MacOS', 'Atom')
else if process.platform is 'win32'
appPath = path.join(contentsDir, 'atom.exe')
packageSpecQueue = async.queue (packagePath, callback) ->
if process.platform in ['darwin', 'linux']
if process.platform is 'darwin'
options =
cmd: appPath
args: ['--test', "--resource-path=#{resourcePath}", "--spec-directory=#{path.join(packagePath, 'spec')}"]
@@ -61,15 +53,21 @@ module.exports = (grunt) ->
continue unless isAtomPackage(packagePath)
packageSpecQueue.push(packagePath)
packageSpecQueue.concurrency = 1
# TODO: Restore concurrency on Windows
packageSpecQueue.concurrency = 1 unless process.platform is 'win32'
packageSpecQueue.drain = -> callback(null, failedPackages)
runCoreSpecs = (callback) ->
appPath = getAppPath()
contentsDir = grunt.config.get('atom.contentsDir')
if process.platform is 'darwin'
appPath = path.join(contentsDir, 'MacOS', 'Atom')
else if process.platform is 'win32'
appPath = path.join(contentsDir, 'atom.exe')
resourcePath = process.cwd()
coreSpecsPath = path.resolve('spec')
if process.platform in ['darwin', 'linux']
if process.platform is 'darwin'
options =
cmd: appPath
args: ['--test', "--resource-path=#{resourcePath}", "--spec-directory=#{coreSpecsPath}"]
@@ -94,7 +92,7 @@ module.exports = (grunt) ->
# TODO: This should really be parallel on both platforms, however our
# fixtures step on each others toes currently.
if process.platform in ['darwin', 'linux']
if process.platform is 'darwin'
method = async.parallel
else if process.platform is 'win32'
method = async.series
@@ -107,8 +105,4 @@ module.exports = (grunt) ->
failures.push "atom core" if coreSpecFailed
grunt.log.error("[Error]".red + " #{failures.join(', ')} spec(s) failed") if failures.length > 0
if process.platform is 'win32' and process.env.JANKY_SHA1
done()
else
done(!coreSpecFailed and failedPackages.length == 0)
done(!coreSpecFailed and failedPackages.length == 0)
+2 -3
Ver Arquivo
@@ -7,7 +7,7 @@ module.exports = (grunt) ->
grunt.fatal("Cannot copy non-existent #{source.cyan} to #{destination.cyan}")
copyFile = (sourcePath, destinationPath) ->
return if filter?(sourcePath) or filter?.test?(sourcePath)
return if filter?.test(sourcePath)
stats = fs.lstatSync(sourcePath)
if stats.isSymbolicLink()
@@ -53,9 +53,8 @@ module.exports = (grunt) ->
proc = childProcess.spawn(options.cmd, options.args, options.opts)
proc.stdout.on 'data', (data) -> stdout.push(data.toString())
proc.stderr.on 'data', (data) -> stderr.push(data.toString())
proc.on 'error', (processError) -> error ?= processError
proc.on 'close', (exitCode, signal) ->
error ?= new Error(signal) if exitCode != 0
error = new Error(signal) if exitCode != 0
results = {stderr: stderr.join(''), stdout: stdout.join(''), code: exitCode}
grunt.log.error results.stderr if exitCode != 0
callback(error, results, exitCode)
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
-32
Ver Arquivo
@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id><%= name %></id>
<version><%= version %></version>
<authors>The Atom Community</authors>
<owners>The Atom Community</owners>
<iconUrl>https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description><%= description %></description>
</metadata>
<files>
<file src="locales\**" target="lib\net45\locales" />
<file src="resources\**" target="lib\net45\resources" />
<file src="*.pak" target="lib\net45" />
<file src="atom.exe" target="lib\net45\atom.exe" />
<file src="atom.exe.gui" target="lib\net45\atom.exe.gui" />
<file src="chromiumcontent.dll" target="lib\net45\chromiumcontent.dll" />
<file src="d3dcompiler_43.dll" target="lib\net45\d3dcompiler_43.dll" />
<file src="ffmpegsumo.dll" target="lib\net45\ffmpegsumo.dll" />
<file src="icudtl.dat" target="lib\net45\icudtl.dat" />
<file src="libEGL.dll" target="lib\net45\libEGL.dll" />
<file src="libGLESv2.dll" target="lib\net45\libGLESv2.dll" />
<file src="LICENSE" target="lib\net45\LICENSE" />
<file src="msvcp120.dll" target="lib\net45\msvcp120.dll" />
<file src="msvcr120.dll" target="lib\net45\msvcr120.dll" />
<file src="vccorlib120.dll" target="lib\net45\vccorlib120.dll" />
<file src="version" target="lib\net45\version" />
<file src="xinput1_3.dll" target="lib\net45\xinput1_3.dll" />
</files>
</package>
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 43 KiB

-17
Ver Arquivo
@@ -1,17 +0,0 @@
{
"max_line_length": {
"level": "ignore"
},
"no_empty_param_list": {
"level": "error"
},
"arrow_spacing": {
"level": "error"
},
"no_interpolation_in_single_quotes": {
"level": "error"
},
"no_debugger": {
"level": "error"
}
}
+31 -12
Ver Arquivo
@@ -11,31 +11,41 @@ value of a namespaced config key with `atom.config.get`:
@showInvisibles() if atom.config.get "editor.showInvisibles"
```
Or you can use the `::subscribe` with `atom.config.observe` to track changes
from any view object.
Or you can use the `::observeConfig` to track changes from any view object.
```coffeescript
class MyView extends View
initialize: ->
@subscribe atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
@observeConfig 'editor.fontSize', () =>
@adjustFontSize()
```
The `atom.config.observe` method will call the given callback immediately with
the current value for the specified key path, and it will also call it in the
future whenever the value of that key path changes.
The `::observeConfig` method will call the given callback immediately with the
current value for the specified key path, and it will also call it in the future
whenever the value of that key path changes.
Subscriptions made with `::subscribe` are automatically canceled when the
Subscriptions made with `observeConfig` are automatically canceled when the
view is removed. You can cancel config subscriptions manually via the
`off` method on the subscription object that `atom.config.observe` returns.
`unobserveConfig` method.
```coffeescript
fontSizeSubscription = atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
@adjustFontSize()
view1.unobserveConfig() # unobserve all properties
```
# ... later on
You can add the ability to observe config values to non-view classes by
extending their prototype with the `ConfigObserver` mixin:
fontSizeSubscription.off() # Stop observing
```coffeescript
{ConfigObserver} = require 'atom'
class MyClass
ConfigObserver.includeInto(this)
constructor: ->
@observeConfig 'editor.showInvisibles', -> # ...
destroy: ->
@unobserveConfig()
```
### Writing Config Settings
@@ -48,6 +58,15 @@ but you can programmatically write to it with `atom.config.set`:
atom.config.set("core.showInvisibles", true)
```
You should never mutate the value of a config key, because that would circumvent
the notification of observers. You can however use methods like `pushAtKeyPath`,
`unshiftAtKeyPath`, and `removeAtKeyPath` to manipulate mutable config values.
```coffeescript
atom.config.pushAtKeyPath("core.disabledPackages", "wrap-guide")
atom.config.removeAtKeyPath("core.disabledPackages", "terminal")
```
You can also use `setDefaults`, which will assign default values for keys that
are always overridden by values assigned with `set`. Defaults are not written
out to the the `config.json` file to prevent it from becoming cluttered.
+1 -1
Ver Arquivo
@@ -56,7 +56,7 @@ character of the current line:
class EditorView
listenForEvents: ->
@command 'editor:move-to-first-character-of-line', =>
@editor.moveToFirstCharacterOfLine()
@editor.moveCursorToFirstCharacterOfLine()
```
The `::command` method is basically an enhanced version of jQuery's `::on`
+10 -65
Ver Arquivo
@@ -1,4 +1,4 @@
# Atom.io package and update API
## Atom.io package and update API
This guide describes the web API used by [apm](https://github.com/atom/apm) and
Atom. The vast majority of use cases are met by the `apm` command-line tool,
@@ -8,8 +8,6 @@ and making sure you have pushed your git tag. In fact, Atom itself shells out to
uses `apm`, see the [PackageManager class](https://github.com/atom/settings-view/blob/master/lib/package-manager.coffee)
in the `settings-view` package.
*This API should be considered pre-release and is subject to change (though significant breaking changes are unlikely).*
### Authorization
For calls to the API that require authentication, provide a valid token from your
@@ -19,18 +17,12 @@ For calls to the API that require authentication, provide a valid token from you
All requests that take parameters require `application/json`.
# API Resources
## Resources
## Packages
### Listing packages
### Packages
#### GET /api/packages
Parameters:
- **page** (optional)
Returns a list of all packages in the following format:
```json
[
@@ -48,17 +40,6 @@ Returns a list of all packages in the following format:
]
```
Results are paginated 30 at a time, and links to the next and last pages are
provided in the `Link` header:
```
Link: <https://www.atom.io/api/packages?page=1>; rel="self",
<https://www.atom.io/api/packages?page=41>; rel="last",
<https://www.atom.io/api/packages?page=2>; rel="next"
```
### Showing package details
#### GET /api/packages/:package_name
Returns package details and versions for a single package
@@ -87,8 +68,6 @@ Returns:
}
```
### Creating a package
#### POST /api/packages
Create a new package; requires authentication.
@@ -113,7 +92,6 @@ Returns:
- The package.json at owner/repo isn't valid
- **409** - A package by that name already exists
### Deleting a package
#### DELETE /api/packages/:package_name
@@ -125,13 +103,6 @@ Returns:
- **400** - Repository is inaccessible
- **401** - Unauthorized
### Renaming a package
Packages are renamed by publishing a new version with the name changed in `package.json`
See [Creating a new package version](#creating-a-new-package-version) for details.
Requests made to the previous name will forward to the new name.
### Package Versions
#### GET /api/packages/:package_name/versions/:version_name
@@ -173,9 +144,7 @@ Returns `package.json` with `dist` key added for e.g. tarball download:
#### POST /api/packages/:package_name/versions
Creates a new package version from a git tag; requires authentication. If `rename`
is not `true`, the `name` field in `package.json` *must* match the current package
name.
Creates a new package version from a git tag; requires authentication.
#### Parameters
@@ -183,15 +152,14 @@ name.
that the version name will not be taken from the tag, but from the `version`
key in the `package.json` file at that ref. The authenticating user *must* have
access to the package repository.
- **rename** - Boolean indicating whether this version contains a new name for the package.
#### Returns
- **201** - Successfully created. Returns created version.
- **400** - Git tag not found / Repository inaccessible / package.json invalid
- **400** - Git tag not found / Repository inaccessible
- **409** - Version exists
### Deleting a version
### Delete a version
#### DELETE /api/packages/:package_name/versions/:version_name
@@ -204,9 +172,7 @@ you'll need to increment the version when republishing.
Returns 204 No Content
## Stars
### Listing user stars
### Stars
#### GET /api/users/:login/stars
@@ -220,40 +186,19 @@ List the authenticated user's starred packages; requires authentication.
Return value is similar to **GET /api/packages**
### Starring a package
#### POST /api/packages/:name/star
Star a package; requires authentication.
Returns a package.
### Unstarring a package
#### DELETE /api/packages/:name/star
Unstar a package; requires authentication.
Returns 204 No Content.
### Listing a package's stargazers
#### GET /api/packages/:name/stargazers
List the users that have starred a package.
Returns a list of user objects:
```json
[
{"login":"aperson"},
{"login":"anotherperson"},
]
```
## Atom updates
### Listing Atom updates
### Atom updates
#### GET /api/updates
@@ -261,10 +206,10 @@ Atom update feed, following the format expected by [Squirrel](https://github.com
Returns:
```json
```
{
"name": "0.96.0",
"notes": "[HTML release notes]",
"notes": "[HTML release notes]"
"pub_date": "2014-05-19T15:52:06.000Z",
"url": "https://www.atom.io/api/updates/download"
}
+23 -86
Ver Arquivo
@@ -6,85 +6,38 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
* OS with 64-bit or 32-bit architecture
* C++ toolchain
* [Git](http://git-scm.com/)
* [Node.js](http://nodejs.org/download/) v0.10.x
* [npm](http://www.npmjs.org/) v1.4.x (bundled with Node.js)
* `npm -v` to check the version.
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses python2.
* You might need to run this command as `sudo`, depending on how you have set up [npm](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
* development headers for [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring)
### Ubuntu / Debian
* `sudo apt-get install build-essential git libgnome-keyring-dev`
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
### Fedora
* `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel`
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora).
### Arch
* `sudo pacman -S base-devel git nodejs libgnome-keyring`
* `export PYTHON=/usr/bin/python2` before building Atom.
* on Ubuntu/Debian: `sudo apt-get install build-essential`
* on Fedora: `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel`
* [node.js](http://nodejs.org/download/) v0.10.x
* [Ubuntu/Debian/Mint instructions](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os)
* [Fedora instructions](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora)
* [npm](http://www.npmjs.org/) v1.4.x
* `npm` comes with node.js so no explicit installation is needed here.
* You can check `npm` 1.4 or above is installed by running `npm -v`.
* libgnome-keyring-dev
* on Ubuntu/Debian: `sudo apt-get install libgnome-keyring-dev`
* on Fedora: `sudo yum --assumeyes install libgnome-keyring-devel`
* on other distributions refer to the manual on how to install packages
* `npm config set python /usr/bin/python2 -g` to ensure that gyp uses Python 2
* This command may require `sudo` depending on how you have
[configured npm](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
* Git
* on Ubuntu/Debian: `sudo apt-get install git`
* on Fedora: `sudo yum install git-core`
## Instructions
If you have problems with permissions don't forget to prefix with `sudo`
1. Clone the Atom repository:
```sh
git clone https://github.com/atom/atom
cd atom
script/build # Creates application at $TMPDIR/atom-build/Atom
sudo script/grunt install # Installs command to /usr/local/bin/atom
script/grunt mkdeb # Generates a .deb package at $TMPDIR/atom-build
```
2. Checkout the latest Atom release:
```sh
git fetch
git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
```
3. Build Atom:
```sh
script/build
```
This will create the atom application at `$TMPDIR/atom-build/Atom`.
4. Install the `atom` and `apm` commands to `/usr/local/bin` by executing:
```sh
sudo script/grunt install
```
5. *Optionally*, you may generate a `.deb` package at `$TMPDIR/atom-build`:
```sh
script/grunt mkdeb
```
Use the newly installed Atom by fully quitting Atom and then reopening.
## Advanced Options
### Custom install directory
```sh
sudo script/grunt install --install-dir /install/atom/here
```
### Custom build directory
```sh
script/build --build-dir /build/atom/here
```
## Troubleshooting
### Exception: "TypeError: Unable to watch path"
If you get following error with a big traceback right after Atom starts:
@@ -103,27 +56,11 @@ this is the reason for this error you can issue
and restart Atom. If Atom now works fine, you can make this setting permanent:
```sh
echo 32768 | sudo tee -a /proc/sys/fs/inotify/max_user_watches
echo 32768 > /proc/sys/fs/inotify/max_user_watches
```
See also https://github.com/atom/atom/issues/2082.
### /usr/bin/env: node: No such file or directory
If you get this notice when attempting to `script/build`, you either do not
have Node.js installed, or node isn't identified as Node.js on your machine.
If it's the latter, entering `sudo ln -s /usr/bin/nodejs /usr/bin/node` into
your terminal may fix the issue.
#### You can also use Alternatives
On some variants (mostly Debian based distros) it's preferable for you to use
Alternatives so that changes to the binary paths can be fixed or altered easily:
```sh
sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 1 --slave /usr/bin/js js /usr/bin/nodejs
```
### Linux build error reports in atom/atom
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Alinux&type=Issues)
to get a list of reports about build errors on Linux.
+5 -28
Ver Arquivo
@@ -35,14 +35,10 @@
## Why do I have to use GitHub for Windows?
You don't. You can use your existing Git! GitHub for Windows's Git Shell is just
easier to set up.
If you _prefer_ using your existing Git installation, make sure git's cmd directory is in your PATH env variable (e.g. `C:\Program Files (x86)\Git\cmd`) before you open your powershell or command window.
Note that you may have to open your command window as administrator. For powershell that doesn't seem to always be the case, though.
If none of this works, do install Github for Windows and use its Git shell. Makes life easier.
You don't, You can use your existing Git! GitHub for Windows's Git Shell is just
easier to set up. You need to have Posix tools in your `%PATH%` (i.e. `grep`,
`sed`, et al.), which isn't the default configuration when you install Git. To
fix this, you probably need to fiddle with your system PATH.
## Troubleshooting
@@ -66,24 +62,5 @@ If none of this works, do install Github for Windows and use its Git shell. Make
* https://github.com/TooTallNate/node-gyp/issues/297
* https://code.google.com/p/gyp/issues/detail?id=393
* `script/build` stops at installing runas with 'Failed at the runas@0.5.4 install script.'
See the next item.
* `error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset = 'v100') cannot be found.`
* If you're building atom with Visual Studio 2013 try executing the following
command in your Git shell and then re-run `script/build`:
```
$env:GYP_MSVS_VERSION=2013
```
* Other `node-gyp` errors on first build attempt, even though the right node and python versions are installed.
* Do try the build command one more time, as experience shows it often works on second try in many of these cases.
### Windows build error reports in atom/atom
* If all fails, use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Awindows&type=Issues) to get a list of reports about build errors on Windows, and see if yours has already been reported.
* If it hasn't, please open a new issue with your Windows version 32/64bit and a print/screenshot of your build output, incl. the node and python versions.
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Awindows&type=Issues) to get a list of reports about build errors on Windows.
+16 -48
Ver Arquivo
@@ -207,44 +207,36 @@ specific parts of the interface, like adding a file in the tree-view:
```coffeescript
'context-menu':
'.tree-view': [
{label: 'Add file', command: 'tree-view:add-file'}
]
'.workspace': [
{label: 'Inspect Element', command: 'core:inspect'}
]
'.tree-view':
'Add file': 'tree-view:add-file'
'.workspace':
'Inspect Element': 'core:inspect'
```
To add your own item to the application menu simply create a top level
`context-menu` key in any menu configuration file in _menus_. This can be a
JSON or [CSON] file.
Context menus are created by determining which element was selected and then
adding all of the menu items whose selectors match that element (in the order
which they were loaded). The process is then repeated for the elements until
reaching the top of the DOM tree.
Context menus are created by determining which element was selected and
then adding all of the menu items whose selectors match that element (in
the order which they were loaded). The process is then repeated for the
elements until reaching the top of the DOM tree.
In the example above, the `Add file` item will only appear when the focused item
or one of its parents has the `tree-view` class applied to it.
You can also add separators and submenus to your context menus. To add a
submenu, provide a `submenu` key instead of a command. To add a separator, add
an item with a single `type: 'separator'` key/value pair.
submenu, pass in another object instead of a command. To add a separator, use
`-` for the name and command of the item.
```coffeescript
'context-menu':
'.workspace': [
{
label: 'Text'
submenu: [
{label: 'Inspect Element', command: 'core:inspect'}
{type: 'separator'}
{label: 'Selector All', command: 'core:select-all'}
{type: 'separator'}
{label: 'Deleted Selected Text', command: 'core:delete'}
]
}
]
'.workspace':
'Inspect Element': 'core:inspect'
'-': '-'
'Text':
'Select All': 'core:select-all'
'Deleted Selected Text': 'core:delete'
```
## Snippets
@@ -328,29 +320,6 @@ extensions your grammar supports:
]
```
## Adding Configuration Settings
You can support config settings in your package that are editable in the
settings view. Specify a `config` key in your package main:
```coffeescript
module.exports =
# Your config schema!
config:
someInt:
type: 'integer'
default: 23
minimum: 1
activate: (state) -> # ...
# ...
```
To define the configuration, we use [json schema][json-schema] which allows you
to indicate the type your value should be, its default, etc.
See the [Config API Docs](https://atom.io/docs/api/latest/Config) for more
details specifying your configuration.
## Bundle External Resources
It's common to ship external resources like images and fonts in the package, to
@@ -422,4 +391,3 @@ all the other available commands.
[first-package]: your-first-package.html
[convert-bundle]: converting-a-text-mate-bundle.html
[convert-theme]: converting-a-text-mate-theme.html
[json-schema]: http://json-schema.org/
+1 -1
Ver Arquivo
@@ -169,7 +169,7 @@ For example, to change the color of the cursor, you could add the following
rule to your _~/.atom/styles.less_ file:
```less
.editor.is-focused .cursor {
.editor .cursor {
border-color: pink;
}
```
+1 -69
Ver Arquivo
@@ -38,7 +38,7 @@ Atom uses [Jasmine](http://jasmine.github.io/2.0/introduction.html) as its spec
0. Add one or more expectations
The best way to learn about expectations is to read the [jasmine documentation](http://jasmine.github.io/1.3/introduction.html#section-Expectations) about them. Below is a simple example.
The best way to learn about expectations is to read the [jasmine documentation](http://jasmine.github.io/2.0/introduction.html#section-Expectations) about them. Below is a simple example.
```coffee
describe "when a test is written", ->
@@ -47,74 +47,6 @@ Atom uses [Jasmine](http://jasmine.github.io/2.0/introduction.html) as its spec
expect("oranges").not.toEqual("apples")
```
## Asynchronous specs
Writing Asynchronous specs can be tricky at first. Some examples.
0. Promises
Working with promises is rather easy in Atom. You can use our `waitsForPromise` function.
```coffee
describe "when we open a file", ->
it "should be opened in an editor", ->
waitsForPromise ->
atom.workspace.open('c.coffee').then (editor) ->
expect(editor.getPath()).toContain 'c.coffee'
```
This method can be used in the `describe`, `it`, `beforeEach` and `afterEach` functions.
```coffee
describe "when we open a file", ->
beforeEach ->
waitsForPromise ->
atom.workspace.open 'c.coffee'
it "should be opened in an editor", ->
expect(atom.workspace.getActiveEditor().getPath()).toContain 'c.coffee'
```
If you need to wait for multiple promises use a new `waitsForPromise` function for each promise. (Caution: Without `beforeEach` this example will fail!)
```coffee
describe "waiting for the packages to load", ->
beforeEach ->
waitsForPromise ->
atom.workspace.open('sample.js')
waitsForPromise ->
atom.packages.activatePackage('tabs')
waitsForPromise ->
atom.packages.activatePackage('tree-view')
it 'should have waited long enough', ->
expect(atom.packages.isPackageActive('tabs')).toBe true
expect(atom.packages.isPackageActive('tree-view')).toBe true
```
0. Asynchronous functions with callbacks
Specs for asynchronous functions can be done using the `waitsFor` and `runs` functions. A simple example.
```coffee
describe "fs.readdir(path, cb)", ->
it "is async", ->
spy = jasmine.createSpy('fs.readdirSpy')
fs.readdir('/tmp/example', spy)
waitsFor ->
spy.callCount > 0
runs ->
exp = [null, ['example.coffee']]
expect(spy.mostRecentCall.args).toEqual exp
expect(spy).toHaveBeenCalledWith(null, ['example.coffee'])
```
For a more detailed documentation on asynchronous tests please visit the [jasmine documentation](http://jasmine.github.io/1.3/introduction.html#section-Asynchronous_Support).
## Running specs
Most of the time you'll want to run specs by triggering the `window:run-package-specs` command. This command is not only to run package specs, it is also for Atom core specs. This will run all the specs in the current project's spec directory. If you want to run the Atom core specs and **all** the default package specs trigger the `window:run-all-specs` command.
+3 -3
Ver Arquivo
@@ -53,7 +53,7 @@ module.exports =
convert: ->
# This assumes the active pane item is an editor
editor = atom.workspace.getActivePaneItem()
editor = atom.workspace.activePaneItem
editor.insertText('Hello, World!')
```
@@ -131,8 +131,8 @@ inserting 'Hello, World!' convert the selected text to ASCII art.
```coffeescript
convert: ->
# This assumes the active pane item is an editor
editor = atom.workspace.getActivePaneItem()
selection = editor.getLastSelection()
editor = atom.workspace.activePaneItem
selection = editor.getSelection()
figlet = require 'figlet'
figlet selection.getText(), {font: "Larry 3D 2"}, (error, asciiArt) ->
+1 -1
Ver Arquivo
@@ -11,4 +11,4 @@
# atom.workspaceView.eachEditorView (editorView) ->
# editor = editorView.getEditor()
# if path.extname(editor.getPath()) is '.md'
# editor.setSoftWrapped(true)
# editor.setSoftWrap(true)
+1 -4
Ver Arquivo
@@ -13,9 +13,6 @@
# 'enter': 'editor:newline'
#
# '.workspace':
# 'ctrl-shift-p': 'core:move-up'
# 'ctrl-P': 'core:move-up'
# 'ctrl-p': 'core:move-down'
#
# You can find more information about keymaps in these guides:
# * https://atom.io/docs/latest/customizing-atom#customizing-key-bindings
# * https://atom.io/docs/latest/advanced/keymaps
+2 -13
Ver Arquivo
@@ -1,10 +1,9 @@
{Point, Range} = require 'text-buffer'
{deprecate} = require 'grim'
module.exports =
BufferedNodeProcess: require '../src/buffered-node-process'
BufferedProcess: require '../src/buffered-process'
GitRepository: require '../src/git-repository'
Git: require '../src/git'
Point: Point
Range: Range
@@ -16,20 +15,10 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
module.exports.$ = $
module.exports.$$ = $$
module.exports.$$$ = $$$
module.exports.TextEditorView = require '../src/text-editor-view'
module.exports.EditorView = require '../src/editor-view'
module.exports.ScrollView = require '../src/scroll-view'
module.exports.SelectListView = require '../src/select-list-view'
module.exports.Task = require '../src/task'
module.exports.View = View
module.exports.WorkspaceView = require '../src/workspace-view'
module.exports.Workspace = require '../src/workspace'
module.exports.React = require 'react-atom-fork'
module.exports.Reactionary = require 'reactionary-atom-fork'
Object.defineProperty module.exports, 'Git', get: ->
deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`"
module.exports.GitRepository
Object.defineProperty module.exports, 'EditorView', get: ->
deprecate "Please require `TextEditorView` instead of `EditorView`: `{TextEditorView} = require 'atom'`"
module.exports.TextEditorView
+2
Ver Arquivo
@@ -12,6 +12,7 @@
# Sublime Parity
'tab': 'editor:indent'
'enter': 'editor:newline'
'num-enter': 'editor:newline'
'shift-tab': 'editor:outdent-selected-rows'
'ctrl-K': 'editor:delete-line'
@@ -26,6 +27,7 @@
'tab': 'core:focus-next'
'shift-tab': 'core:focus-previous'
'enter': 'native!'
'num-enter': 'native!'
'backspace': 'native!'
'shift-backspace': 'native!'
'delete': 'native!'
+2 -5
Ver Arquivo
@@ -21,6 +21,7 @@
'cmd-O': 'application:open-dev'
'cmd-alt-ctrl-s': 'application:run-all-specs'
'enter': 'core:confirm'
'num-enter': 'core:confirm'
'escape': 'core:cancel'
'up': 'core:move-up'
'down': 'core:move-down'
@@ -68,8 +69,6 @@
'cmd-}': 'pane:show-next-item'
'cmd-alt-left': 'pane:show-previous-item'
'cmd-alt-right': 'pane:show-next-item'
'ctrl-pageup': 'pane:show-previous-item'
'ctrl-pagedown': 'pane:show-next-item'
'ctrl-tab': 'pane:show-next-item'
'ctrl-shift-tab': 'pane:show-previous-item'
'cmd-=': 'window:increase-font-size'
@@ -119,7 +118,7 @@
'cmd-shift-right': 'editor:select-to-end-of-line'
'alt-backspace': 'editor:delete-to-beginning-of-word'
'alt-delete': 'editor:delete-to-end-of-word'
'ctrl-a': 'editor:move-to-first-character-of-line'
'ctrl-a': 'editor:move-to-beginning-of-line'
'ctrl-e': 'editor:move-to-end-of-line'
'ctrl-k': 'editor:cut-to-end-of-line'
@@ -143,8 +142,6 @@
# Sublime Parity
'cmd-enter': 'editor:newline-below'
'cmd-shift-enter': 'editor:newline-above'
'alt-enter': 'editor:newline'
'shift-enter': 'editor:newline'
'cmd-]': 'editor:indent-selected-rows'
'cmd-[': 'editor:outdent-selected-rows'
'ctrl-cmd-up': 'editor:move-line-up'
+3 -8
Ver Arquivo
@@ -1,6 +1,7 @@
'body':
# Atom Specific
'enter': 'core:confirm'
'num-enter': 'core:confirm'
'escape': 'core:cancel'
'up': 'core:move-up'
'down': 'core:move-down'
@@ -10,12 +11,10 @@
'ctrl-shift-i': 'window:toggle-dev-tools'
'ctrl-alt-p': 'window:run-package-specs'
'ctrl-alt-s': 'application:run-all-specs'
'ctrl-alt-o': 'application:open-dev'
'ctrl-shift-o': 'application:open-folder'
'ctrl-shift-o': 'application:open-dev'
'F11': 'window:toggle-full-screen'
# Sublime Parity
'ctrl-,': 'application:show-settings'
'ctrl-N': 'application:new-window'
'ctrl-W': 'window:close'
'ctrl-o': 'application:open-file'
@@ -27,7 +26,6 @@
'ctrl-w': 'core:close'
'ctrl-z': 'core:undo'
'ctrl-y': 'core:redo'
'ctrl-shift-z': 'core:redo'
'ctrl-x': 'core:cut'
'ctrl-c': 'core:copy'
'ctrl-v': 'core:paste'
@@ -40,15 +38,13 @@
'shift-pageup': 'core:select-page-up'
'shift-pagedown': 'core:select-page-down'
'delete': 'core:delete'
'shift-delete': 'core:cut'
'shift-delete': 'core:delete'
'pageup': 'core:page-up'
'pagedown': 'core:page-down'
'backspace': 'core:backspace'
'shift-backspace': 'core:backspace'
'ctrl-tab': 'pane:show-next-item'
'ctrl-shift-tab': 'pane:show-previous-item'
'ctrl-pageup': 'pane:show-previous-item'
'ctrl-pagedown': 'pane:show-next-item'
'ctrl-shift-up': 'core:move-up'
'ctrl-shift-down': 'core:move-down'
'ctrl-=': 'window:increase-font-size'
@@ -97,7 +93,6 @@
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
'ctrl-k ctrl-u': 'editor:upper-case'
'ctrl-k ctrl-l': 'editor:lower-case'
'ctrl-l': 'editor:select-line'
'.workspace .editor:not(.mini)':
# Atom specific
+2 -9
Ver Arquivo
@@ -5,6 +5,7 @@
# Atom Specific
'enter': 'core:confirm'
'num-enter': 'core:confirm'
'escape': 'core:cancel'
'up': 'core:move-up'
'down': 'core:move-down'
@@ -17,7 +18,6 @@
'F11': 'window:toggle-full-screen'
# Sublime Parity
'ctrl-,': 'application:show-settings'
'ctrl-N': 'application:new-window'
'ctrl-W': 'window:close'
'ctrl-o': 'application:open-file'
@@ -25,10 +25,8 @@
'ctrl-n': 'application:new-file'
'ctrl-s': 'core:save'
'ctrl-S': 'core:save-as'
'ctrl-f4': 'core:close'
'ctrl-w': 'core:close'
'ctrl-z': 'core:undo'
'ctrl-shift-z': 'core:redo'
'ctrl-y': 'core:redo'
'ctrl-x': 'core:cut'
'ctrl-c': 'core:copy'
@@ -42,15 +40,13 @@
'shift-pageup': 'core:select-page-up'
'shift-pagedown': 'core:select-page-down'
'delete': 'core:delete'
'shift-delete': 'core:cut'
'shift-delete': 'core:delete'
'pageup': 'core:page-up'
'pagedown': 'core:page-down'
'backspace': 'core:backspace'
'shift-backspace': 'core:backspace'
'ctrl-tab': 'pane:show-next-item'
'ctrl-shift-tab': 'pane:show-previous-item'
'ctrl-pageup': 'pane:show-previous-item'
'ctrl-pagedown': 'pane:show-next-item'
'ctrl-shift-up': 'core:move-up'
'ctrl-shift-down': 'core:move-down'
'ctrl-alt-up': 'editor:add-selection-above'
@@ -84,15 +80,12 @@
'ctrl-delete': 'editor:delete-to-end-of-word'
'ctrl-home': 'core:move-to-top'
'ctrl-end': 'core:move-to-bottom'
'ctrl-shift-home': 'core:select-to-top'
'ctrl-shift-end': 'core:select-to-bottom'
# Sublime Parity
'ctrl-a': 'core:select-all'
'ctrl-alt-shift-p': 'editor:log-cursor-scope'
'ctrl-k ctrl-u': 'editor:upper-case'
'ctrl-k ctrl-l': 'editor:lower-case'
'ctrl-l': 'editor:select-line'
'.workspace .editor:not(.mini)':
# Atom specific
+1 -29
Ver Arquivo
@@ -18,8 +18,6 @@
{ type: 'separator' }
{ label: 'Install Shell Commands', command: 'window:install-shell-commands' }
{ type: 'separator' }
{ label: 'Services', submenu: [] }
{ type: 'separator' }
{ label: 'Hide Atom', command: 'application:hide' }
{ label: 'Hide Others', command: 'application:hide-other-applications' }
{ label: 'Show All', command: 'application:unhide-all-applications' }
@@ -39,7 +37,7 @@
{ label: 'Save As...', command: 'core:save-as' }
{ label: 'Save All', command: 'window:save-all' }
{ type: 'separator' }
{ label: 'Close Tab', command: 'core:close' }
{ label: 'Close Buffer', command: 'core:close' }
{ label: 'Close Pane', command: 'pane:close' }
{ label: 'Close Window', command: 'window:close' }
]
@@ -194,29 +192,3 @@
]
}
]
'context-menu':
'.overlayer': [
{label: 'Undo', command: 'core:undo'}
{label: 'Redo', command: 'core:redo'}
{type: 'separator'}
{label: 'Cut', command: 'core:cut'}
{label: 'Copy', command: 'core:copy'}
{label: 'Paste', command: 'core:paste'}
{label: 'Delete', command: 'core:delete'}
{label: 'Select All', command: 'core:select-all'}
{type: 'separator'}
{label: 'Split Up', command: 'pane:split-up'}
{label: 'Split Down', command: 'pane:split-down'}
{label: 'Split Left', command: 'pane:split-left'}
{label: 'Split Right', command: 'pane:split-right'}
{type: 'separator'}
]
'.pane': [
{type: 'separator'}
{label: 'Split Up', command: 'pane:split-up'}
{label: 'Split Down', command: 'pane:split-down'}
{label: 'Split Left', command: 'pane:split-left'}
{label: 'Split Right', command: 'pane:split-right'}
{type: 'separator'}
]
+14 -36
Ver Arquivo
@@ -8,12 +8,14 @@
{ label: 'Open Folder...', command: 'application:open-folder' }
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
{ type: 'separator' }
{ label: '&Preferences...', command: 'application:show-settings' }
{ type: 'separator' }
{ label: '&Save', command: 'core:save' }
{ label: 'Save &As...', command: 'core:save-as' }
{ label: 'Save A&ll', command: 'window:save-all' }
{ type: 'separator' }
{ label: '&Close Tab', command: 'core:close' }
{ label: 'Close &Pane', command: 'pane:close' }
{ label: '&Close Buffer', command: 'core:close' }
{ label: 'Close All &Buffers', command: 'pane:close' }
{ label: 'Clos&e Window', command: 'window:close' }
{ type: 'separator' }
{ label: 'Quit', command: 'application:quit' }
@@ -78,14 +80,6 @@
{ label: 'Fold Level 9', command: 'editor:fold-at-indent-level-9' }
]
}
{ type: 'separator' }
{ label: '&Preferences', command: 'application:show-settings' }
{ label: 'Open Your Config', command: 'application:open-your-config' }
{ label: 'Open Your Init Script', command: 'application:open-your-init-script' }
{ label: 'Open Your Keymap', command: 'application:open-your-keymap' }
{ label: 'Open Your Snippets', command: 'application:open-your-snippets' }
{ label: 'Open Your Stylesheet', command: 'application:open-your-stylesheet' }
{ type: 'separator' }
]
}
@@ -139,6 +133,16 @@
submenu: []
}
{
label: '&Window'
submenu: [
{ label: 'Mi&nimize', command: 'application:minimize' }
{ label: 'Ma&ximize', command: 'application:zoom' }
{ type: 'separator' }
{ label: 'Bring &All to Front', command: 'application:bring-all-windows-to-front' }
]
}
{
label: '&Help'
submenu: [
@@ -151,29 +155,3 @@
]
}
]
'context-menu':
'.overlayer': [
{label: 'Undo', command: 'core:undo'}
{label: 'Redo', command: 'core:redo'}
{type: 'separator'}
{label: 'Cut', command: 'core:cut'}
{label: 'Copy', command: 'core:copy'}
{label: 'Paste', command: 'core:paste'}
{label: 'Delete', command: 'core:delete'}
{label: 'Select All', command: 'core:select-all'}
{type: 'separator'}
{label: 'Split Up', command: 'pane:split-up'}
{label: 'Split Down', command: 'pane:split-down'}
{label: 'Split Left', command: 'pane:split-left'}
{label: 'Split Right', command: 'pane:split-right'}
{type: 'separator'}
]
'.pane': [
{type: 'separator'}
{label: 'Split Up', command: 'pane:split-up'}
{label: 'Split Down', command: 'pane:split-down'}
{label: 'Split Left', command: 'pane:split-left'}
{label: 'Split Right', command: 'pane:split-right'}
{type: 'separator'}
]
+14 -35
Ver Arquivo
@@ -9,18 +9,13 @@
{ label: 'Reopen Last &Item', command: 'pane:reopen-closed-item' }
{ type: 'separator' }
{ label: 'Se&ttings', command: 'application:show-settings' }
{ label: 'Open Your Config', command: 'application:open-your-config' }
{ label: 'Open Your Init Script', command: 'application:open-your-init-script' }
{ label: 'Open Your Keymap', command: 'application:open-your-keymap' }
{ label: 'Open Your Snippets', command: 'application:open-your-snippets' }
{ label: 'Open Your Stylesheet', command: 'application:open-your-stylesheet' }
{ type: 'separator' }
{ label: '&Save', command: 'core:save' }
{ label: 'Save &As...', command: 'core:save-as' }
{ label: 'Save A&ll', command: 'window:save-all' }
{ type: 'separator' }
{ label: '&Close Tab', command: 'core:close' }
{ label: 'Close &Pane', command: 'pane:close' }
{ label: '&Close Buffer', command: 'core:close' }
{ label: 'Close All &Buffers', command: 'pane:close' }
{ label: 'Clos&e Window', command: 'window:close' }
{ type: 'separator' }
{ label: 'E&xit', command: 'application:quit' }
@@ -33,8 +28,8 @@
{ label: '&Undo', command: 'core:undo' }
{ label: '&Redo', command: 'core:redo' }
{ type: 'separator' }
{ label: 'Cu&t', command: 'core:cut' }
{ label: '&Copy', command: 'core:copy' }
{ label: '&Cut', command: 'core:cut' }
{ label: 'C&opy', command: 'core:copy' }
{ label: 'Copy Pat&h', command: 'editor:copy-path' }
{ label: '&Paste', command: 'core:paste' }
{ label: 'Select &All', command: 'core:select-all' }
@@ -157,6 +152,16 @@
submenu: []
}
{
label: '&Window'
submenu: [
{ label: 'Mi&nimize', command: 'application:minimize' }
{ label: 'Ma&ximize', command: 'application:zoom' }
{ type: 'separator' }
{ label: 'Bring &All to Front', command: 'application:bring-all-windows-to-front' }
]
}
{
label: '&Help'
submenu: [
@@ -169,29 +174,3 @@
]
}
]
'context-menu':
'.overlayer': [
{label: 'Undo', command: 'core:undo'}
{label: 'Redo', command: 'core:redo'}
{type: 'separator'}
{label: 'Cut', command: 'core:cut'}
{label: 'Copy', command: 'core:copy'}
{label: 'Paste', command: 'core:paste'}
{label: 'Delete', command: 'core:delete'}
{label: 'Select All', command: 'core:select-all'}
{type: 'separator'}
{label: 'Split Up', command: 'pane:split-up'}
{label: 'Split Down', command: 'pane:split-down'}
{label: 'Split Left', command: 'pane:split-left'}
{label: 'Split Right', command: 'pane:split-right'}
{type: 'separator'}
]
'.pane': [
{type: 'separator'}
{label: 'Split Up', command: 'pane:split-up'}
{label: 'Split Down', command: 'pane:split-down'}
{label: 'Split Left', command: 'pane:split-left'}
{label: 'Split Right', command: 'pane:split-right'}
{type: 'separator'}
]
+86 -90
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "0.136.0",
"version": "0.107.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -17,129 +17,125 @@
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
}
],
"atomShellVersion": "0.17.1",
"atomShellVersion": "0.13.2",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^2.2.0",
"atom-keymap": "^0.27.0",
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
"clear-cut": "0.4.0",
"coffee-script": "1.7.0",
"coffeestack": "0.7.0",
"delegato": "^1",
"emissary": "^1.3.1",
"event-kit": "0.7.2",
"first-mate": "^2.2.0",
"fs-plus": "^2.3.1",
"emissary": "^1.2.1",
"first-mate": "^1.7",
"fs-plus": "^2.2.3",
"fstream": "0.1.24",
"fuzzaldrin": "^2.1",
"git-utils": "^2.1.5",
"grim": "0.12.0",
"fuzzaldrin": "^1.1",
"git-utils": "^1.3",
"grim": "0.11.0",
"guid": "0.0.10",
"jasmine-tagged": "^1.1.2",
"less-cache": "0.15.0",
"less-cache": "0.12.0",
"mixto": "^1",
"mkdirp": "0.3.5",
"nslog": "^1.0.1",
"oniguruma": "^3.0.4",
"nslog": "0.5.0",
"oniguruma": "^1.0.6",
"optimist": "0.4.0",
"pathwatcher": "^2.1.3",
"pathwatcher": "^1.3.2",
"property-accessors": "^1",
"q": "^1.0.1",
"random-words": "0.0.1",
"react-atom-fork": "^0.11.1",
"reactionary-atom-fork": "^1.0.0",
"runas": "1.0.1",
"scandal": "1.0.2",
"scoped-property-store": "^0.11.0",
"scrollbar-style": "^1.0.2",
"react-atom-fork": "^0.10.0",
"reactionary-atom-fork": "^0.9.0",
"runas": "^0.5",
"scandal": "0.15.3",
"scoped-property-store": "^0.9.0",
"scrollbar-style": "^0.4.0",
"season": "^1.0.2",
"semver": "1.1.4",
"serializable": "^1",
"space-pen": "3.6.1",
"space-pen": "3.2.0",
"temp": "0.7.0",
"text-buffer": "^3.2.8",
"theorist": "^1.0.2",
"underscore-plus": "^1.5.1",
"text-buffer": "^2.4.2",
"theorist": "^1",
"underscore-plus": "^1.5.0",
"vm-compatibility-layer": "0.1.0"
},
"packageDependencies": {
"atom-dark-syntax": "0.19.0",
"atom-dark-ui": "0.35.0",
"atom-light-syntax": "0.20.0",
"atom-light-ui": "0.30.0",
"base16-tomorrow-dark-theme": "0.21.0",
"base16-tomorrow-light-theme": "0.4.0",
"solarized-dark-syntax": "0.22.0",
"solarized-light-syntax": "0.12.0",
"archive-view": "0.37.0",
"autocomplete": "0.32.0",
"autoflow": "0.18.0",
"autosave": "0.18.0",
"background-tips": "0.17.0",
"bookmarks": "0.28.0",
"bracket-matcher": "0.61.0",
"command-palette": "0.27.0",
"deprecation-cop": "0.10.0",
"dev-live-reload": "0.34.0",
"exception-reporting": "0.20.0",
"atom-dark-syntax": "0.17.0",
"atom-dark-ui": "0.29.0",
"atom-light-syntax": "0.18.0",
"atom-light-ui": "0.25.0",
"base16-tomorrow-dark-theme": "0.17.0",
"solarized-dark-syntax": "0.18.0",
"solarized-light-syntax": "0.9.0",
"archive-view": "0.33.0",
"autocomplete": "0.28.0",
"autoflow": "0.17.0",
"autosave": "0.14.0",
"background-tips": "0.14.0",
"bookmarks": "0.25.0",
"bracket-matcher": "0.47.0",
"command-palette": "0.23.0",
"deprecation-cop": "0.7.0",
"dev-live-reload": "0.31.0",
"exception-reporting": "0.18.0",
"feedback": "0.33.0",
"find-and-replace": "0.139.0",
"fuzzy-finder": "0.58.0",
"git-diff": "0.39.0",
"go-to-line": "0.25.0",
"grammar-selector": "0.34.0",
"image-view": "0.37.0",
"incompatible-packages": "0.9.0",
"keybinding-resolver": "0.20.0",
"link": "0.25.0",
"markdown-preview": "0.103.0",
"metrics": "0.36.0",
"open-on-github": "0.30.0",
"find-and-replace": "0.120.0",
"fuzzy-finder": "0.55.0",
"git-diff": "0.34.0",
"go-to-line": "0.23.0",
"grammar-selector": "0.27.0",
"image-view": "0.35.0",
"keybinding-resolver": "0.18.0",
"link": "0.24.0",
"markdown-preview": "0.83.0",
"metrics": "0.32.0",
"open-on-github": "0.28.0",
"package-generator": "0.31.0",
"release-notes": "0.36.0",
"settings-view": "0.149.0",
"snippets": "0.55.0",
"spell-check": "0.42.0",
"status-bar": "0.46.0",
"styleguide": "0.30.0",
"symbols-view": "0.66.0",
"tabs": "0.54.0",
"timecop": "0.22.0",
"tree-view": "0.128.0",
"release-notes": "0.32.0",
"settings-view": "0.128.0",
"snippets": "0.46.0",
"spell-check": "0.38.0",
"status-bar": "0.41.0",
"styleguide": "0.29.0",
"symbols-view": "0.56.0",
"tabs": "0.42.0",
"timecop": "0.19.0",
"tree-view": "0.104.0",
"update-package-dependencies": "0.6.0",
"welcome": "0.18.0",
"whitespace": "0.25.0",
"wrap-guide": "0.22.0",
"language-c": "0.28.0",
"language-coffee-script": "0.35.0",
"language-css": "0.18.0",
"language-gfm": "0.51.0",
"welcome": "0.16.0",
"whitespace": "0.22.0",
"wrap-guide": "0.19.0",
"language-c": "0.21.0",
"language-coffee-script": "0.22.0",
"language-css": "0.17.0",
"language-gfm": "0.40.0",
"language-git": "0.9.0",
"language-go": "0.18.0",
"language-html": "0.26.0",
"language-hyperlink": "0.12.0",
"language-java": "0.11.0",
"language-javascript": "0.40.0",
"language-go": "0.12.0",
"language-html": "0.22.0",
"language-hyperlink": "0.10.0",
"language-java": "0.10.0",
"language-javascript": "0.28.0",
"language-json": "0.8.0",
"language-less": "0.15.0",
"language-make": "0.12.0",
"language-mustache": "0.10.0",
"language-less": "0.9.0",
"language-make": "0.10.0",
"language-objective-c": "0.11.0",
"language-perl": "0.9.0",
"language-php": "0.16.0",
"language-php": "0.15.0",
"language-property-list": "0.7.0",
"language-python": "0.19.0",
"language-ruby": "0.39.0",
"language-ruby-on-rails": "0.18.0",
"language-sass": "0.22.0",
"language-python": "0.18.0",
"language-ruby": "0.30.0",
"language-ruby-on-rails": "0.14.0",
"language-sass": "0.13.0",
"language-shellscript": "0.8.0",
"language-source": "0.8.0",
"language-sql": "0.11.0",
"language-source": "0.7.0",
"language-sql": "0.8.0",
"language-text": "0.6.0",
"language-todo": "0.12.0",
"language-todo": "0.10.0",
"language-toml": "0.12.0",
"language-xml": "0.22.0",
"language-yaml": "0.18.0"
"language-xml": "0.15.0",
"language-yaml": "0.7.0"
},
"private": true,
"scripts": {
+1 -2
Ver Arquivo
@@ -5,5 +5,4 @@ Exec=<%= installDir %>/share/atom/atom %U
Icon=<%= iconName %>
Type=Application
StartupNotify=true
Categories=GNOME;GTK;Utility;TextEditor;Development;
MimeType=text/plain;
Categories=GNOME;GTK;Utility;TextEditor;
+1 -3
Ver Arquivo
@@ -1,10 +1,8 @@
Package: <%= name %>
Version: <%= version %>
Depends: python (>= 2.6), libc6
Section: <%= section %>
Priority: optional
Architecture: <%= arch %>
Installed-Size: <%= installedSize %>
Installed-Size: `du -ks usr|cut -f 1`
Maintainer: <%= maintainer %>
Description: <%= description %>
Atom is a free and open source text editor that is modern, approachable, and hackable to the core.
-7
Ver Arquivo
@@ -1,7 +0,0 @@
atom: arch-dependent-file-in-usr-share
atom: changelog-file-missing-in-native-package
atom: copyright-file-contains-full-apache-2-license
atom: copyright-should-refer-to-common-license-file-for-apache-2
atom: embedded-library
atom: package-installs-python-bytecode
atom: unstripped-binary-or-object
Arquivo binário não exibido.
Arquivo binário não exibido.
+6 -43
Ver Arquivo
@@ -31,7 +31,7 @@ function bootstrap() {
fs.mkdirSync(path.join(apmInstallPath, 'node_modules'));
var apmPath = path.resolve(__dirname, '..', 'apm', 'node_modules', 'atom-package-manager', 'bin', 'apm')
var apmFlags = process.env.JANKY_SHA1 || process.argv.indexOf('--no-color') !== -1 ? ' --no-color' : '';
var apmFlags = process.env.JANKY_SHA1 || process.argv.indexOf('--no-color') !== -1 ? '--no-color' : '';
var npmPath = path.resolve(__dirname, '..', 'build', 'node_modules', '.bin', 'npm');
var initialNpmCommand = fs.existsSync(npmPath) ? npmPath : 'npm';
@@ -39,49 +39,12 @@ function bootstrap() {
var packagesToDedupe = ['fs-plus', 'humanize-plus', 'oniguruma', 'roaster', 'season', 'grim'];
var buildInstallCommand = initialNpmCommand + npmFlags + 'install';
var buildInstallOptions = {cwd: path.resolve(__dirname, '..', 'build')};
var apmInstallCommand = npmPath + npmFlags + 'install';
var apmInstallOptions = {cwd: apmInstallPath};
var moduleInstallCommand = apmPath + ' install' + apmFlags;
var dedupeApmCommand = apmPath + ' dedupe' + apmFlags;
var dedupeNpmCommand = npmPath + npmFlags + 'dedupe';
if (process.argv.indexOf('--no-quiet') === -1) {
buildInstallCommand += ' --quiet';
apmInstallCommand += ' --quiet';
moduleInstallCommand += ' --quiet';
dedupeApmCommand += ' --quiet';
dedupeNpmCommand += ' --quiet';
buildInstallOptions.ignoreStdout = true;
apmInstallOptions.ignoreStdout = true;
}
// apm ships with 32-bit node so make sure its native modules are compiled
// for a 32-bit target architecture
if (process.env.JANKY_SHA1 && process.platform === 'win32')
apmInstallCommand += ' --arch=ia32';
var commands = [
{
command: buildInstallCommand,
message: 'Installing build modules...',
options: buildInstallOptions
},
{
command: apmInstallCommand,
message: 'Installing apm...',
options: apmInstallOptions
},
apmPath + ' clean' + apmFlags,
moduleInstallCommand,
dedupeApmCommand + ' ' + packagesToDedupe.join(' '),
{
command: dedupeNpmCommand + ' request semver',
options: {
cwd: path.resolve(__dirname, '..', 'apm', 'node_modules', 'atom-package-manager')
}
},
{command: initialNpmCommand + npmFlags + 'install --quiet', message: 'Installing build modules...', options: {cwd: path.resolve(__dirname, '..', 'build'), ignoreStdout: true}},
{command: npmPath + npmFlags + 'install --quiet', message: 'Installing apm...', options: {cwd: apmInstallPath, ignoreStdout: true}},
apmPath + ' clean ' + apmFlags,
apmPath + ' install --quiet ' + apmFlags,
apmPath + ' dedupe --quiet ' + apmFlags + ' ' + packagesToDedupe.join(' '),
];
process.chdir(path.dirname(__dirname));
+4 -1
Ver Arquivo
@@ -5,6 +5,9 @@ var path = require('path');
process.chdir(path.dirname(__dirname));
if (process.platform == 'linux')
throw new Error('cibuild can not run on linux yet!');
var homeDir = process.platform == 'win32' ? process.env.USERPROFILE : process.env.HOME;
function loadEnvironmentVariables(filePath) {
@@ -24,7 +27,7 @@ function loadEnvironmentVariables(filePath) {
function readEnvironmentVariables() {
if (process.platform === 'win32')
loadEnvironmentVariables(path.resolve('/jenkins/config/atomcredentials'));
else if (process.platform === 'darwin') {
else {
loadEnvironmentVariables('/var/lib/jenkins/config/atomcredentials');
loadEnvironmentVariables('/var/lib/jenkins/config/xcodekeychain');
}
-13
Ver Arquivo
@@ -1,13 +0,0 @@
#!/bin/bash
set -e
export ATOM_ACCESS_TOKEN=$BUILD_ATOM_LINUX_ACCESS_TOKEN
if [ -d /usr/local/share/nodenv ]; then
export NODENV_ROOT=/usr/local/share/nodenv
export PATH=/usr/local/share/nodenv/bin:/usr/local/share/nodenv/shims:$PATH
export NODENV_VERSION="v0.10.21"
fi
script/cibuild
-1
Ver Arquivo
@@ -24,7 +24,6 @@ var commands = [
[home, '.atom', 'storage'],
[home, '.atom', '.npm'],
[home, '.atom', 'compile-cache'],
[home, '.atom', 'atom-shell'],
[tmpdir, 'atom-build'],
[tmpdir, 'atom-cached-atom-shells'],
];
+7 -19
Ver Arquivo
@@ -13,35 +13,23 @@ CONTROL_FILE="$3"
DESKTOP_FILE="$4"
ICON_FILE="$5"
DEB_PATH="$6"
FILE_MODE=755
TARGET_ROOT="`mktemp -d`"
chmod $FILE_MODE "$TARGET_ROOT"
chmod 755 "$TARGET_ROOT"
TARGET="$TARGET_ROOT/atom-$VERSION-$ARCH"
mkdir -m $FILE_MODE -p "$TARGET/usr"
mkdir -p "$TARGET/usr"
env INSTALL_PREFIX="$TARGET/usr" script/grunt install
mkdir -m $FILE_MODE -p "$TARGET/DEBIAN"
mkdir -p "$TARGET/DEBIAN"
cp "$CONTROL_FILE" "$TARGET/DEBIAN/control"
mkdir -m $FILE_MODE -p "$TARGET/usr/share/applications"
mkdir -p "$TARGET/usr/share/applications"
cp "$DESKTOP_FILE" "$TARGET/usr/share/applications"
mkdir -m $FILE_MODE -p "$TARGET/usr/share/pixmaps"
mkdir -p "$TARGET/usr/share/pixmaps"
cp "$ICON_FILE" "$TARGET/usr/share/pixmaps"
# Copy generated LICENSE.md to /usr/share/doc/atom/copyright
mkdir -m $FILE_MODE -p "$TARGET/usr/share/doc/atom"
cp "$TARGET/usr/share/atom/resources/app/LICENSE.md" "$TARGET/usr/share/doc/atom/copyright"
# Add lintian overrides
mkdir -m $FILE_MODE -p "$TARGET/usr/share/lintian/overrides"
cp "$ROOT/resources/linux/debian/lintian-overrides" "$TARGET/usr/share/lintian/overrides/atom"
# Remove executable bit from .node files
find "$TARGET" -type f -name "*.node" -exec chmod a-x {} \;
fakeroot dpkg-deb -b "$TARGET"
dpkg-deb -b "$TARGET"
mv "$TARGET_ROOT/atom-$VERSION-$ARCH.deb" "$DEB_PATH"
rm -rf "$TARGET_ROOT"
rm -rf $TARGET_ROOT
+1 -1
Ver Arquivo
@@ -31,7 +31,7 @@ function verifyNode(cb) {
var nodeMajorVersion = +versionArray[0];
var nodeMinorVersion = +versionArray[1];
if (nodeMajorVersion === 0 && nodeMinorVersion < 10) {
error = "node v0.10 is required to build Atom, node " + nodeVersion + " is installed.";
error = "node v0.10 is required to build Atom.";
cb(error);
}
else {
+2 -5
Ver Arquivo
@@ -76,9 +76,6 @@ class AtomReporter extends View
@addSpecs(specs)
$(document.body).append this
@on 'click', '.stack-trace', ->
$(this).toggleClass('expanded')
reportRunnerResults: (runner) ->
@updateSpecCounts()
@status.addClass('alert-success').removeClass('alert-info') if @failedCount is 0
@@ -122,14 +119,14 @@ class AtomReporter extends View
grim.clearDeprecations()
handleEvents: ->
$(document).on "click", ".spec-toggle", ({currentTarget}) ->
$(document).on "click", ".spec-toggle", ({currentTarget}) =>
element = $(currentTarget)
specFailures = element.parent().find('.spec-failures')
specFailures.toggle()
element.toggleClass('folded')
false
$(document).on "click", ".deprecation-toggle", ({currentTarget}) ->
$(document).on "click", ".deprecation-toggle", ({currentTarget}) =>
element = $(currentTarget)
deprecationList = $(document).find('.deprecation-list')
deprecationList.toggle()
+518 -35
Ver Arquivo
@@ -6,49 +6,532 @@ ThemeManager = require '../src/theme-manager'
describe "the `atom` global", ->
beforeEach ->
atom.workspaceView = atom.workspace.getView(atom.workspace).__spacePenView
atom.workspaceView = new WorkspaceView
describe 'window sizing methods', ->
describe '::getPosition and ::setPosition', ->
it 'sets the position of the window, and can retrieve the position just set', ->
atom.setPosition(22, 45)
expect(atom.getPosition()).toEqual x: 22, y: 45
describe "package lifecycle methods", ->
describe ".loadPackage(name)", ->
it "continues if the package has an invalid package.json", ->
spyOn(console, 'warn')
atom.config.set("core.disabledPackages", [])
expect(-> atom.packages.loadPackage("package-with-broken-package-json")).not.toThrow()
it "continues if the package has an invalid keymap", ->
atom.config.set("core.disabledPackages", [])
expect(-> atom.packages.loadPackage("package-with-broken-keymap")).not.toThrow()
describe ".unloadPackage(name)", ->
describe "when the package is active", ->
it "throws an error", ->
pack = null
waitsForPromise ->
atom.packages.activatePackage('package-with-main').then (p) -> pack = p
runs ->
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
expect( -> atom.packages.unloadPackage(pack.name)).toThrow()
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
expect(atom.packages.isPackageActive(pack.name)).toBeTruthy()
describe "when the package is not loaded", ->
it "throws an error", ->
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
expect( -> atom.packages.unloadPackage('unloaded')).toThrow()
expect(atom.packages.isPackageLoaded('unloaded')).toBeFalsy()
describe "when the package is loaded", ->
it "no longers reports it as being loaded", ->
pack = atom.packages.loadPackage('package-with-main')
expect(atom.packages.isPackageLoaded(pack.name)).toBeTruthy()
atom.packages.unloadPackage(pack.name)
expect(atom.packages.isPackageLoaded(pack.name)).toBeFalsy()
describe ".activatePackage(id)", ->
describe "atom packages", ->
describe "when called multiple times", ->
it "it only calls activate on the package once", ->
spyOn(Package.prototype, 'activateNow').andCallThrough()
atom.packages.activatePackage('package-with-index')
atom.packages.activatePackage('package-with-index')
waitsForPromise ->
atom.packages.activatePackage('package-with-index')
runs ->
expect(Package.prototype.activateNow.callCount).toBe 1
describe "when the package has a main module", ->
describe "when the metadata specifies a main module path˜", ->
it "requires the module at the specified path", ->
mainModule = require('./fixtures/packages/package-with-main/main-module')
spyOn(mainModule, 'activate')
pack = null
waitsForPromise ->
atom.packages.activatePackage('package-with-main').then (p) -> pack = p
runs ->
expect(mainModule.activate).toHaveBeenCalled()
expect(pack.mainModule).toBe mainModule
describe "when the metadata does not specify a main module", ->
it "requires index.coffee", ->
indexModule = require('./fixtures/packages/package-with-index/index')
spyOn(indexModule, 'activate')
pack = null
waitsForPromise ->
atom.packages.activatePackage('package-with-index').then (p) -> pack = p
runs ->
expect(indexModule.activate).toHaveBeenCalled()
expect(pack.mainModule).toBe indexModule
it "assigns config defaults from the module", ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
waitsForPromise ->
atom.packages.activatePackage('package-with-config-defaults')
runs ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
describe "when the package metadata includes activation events", ->
[mainModule, promise] = []
beforeEach ->
mainModule = require './fixtures/packages/package-with-activation-events/index'
spyOn(mainModule, 'activate').andCallThrough()
spyOn(Package.prototype, 'requireMainModule').andCallThrough()
promise = atom.packages.activatePackage('package-with-activation-events')
it "defers requiring/activating the main module until an activation event bubbles to the root view", ->
expect(promise.isFulfilled()).not.toBeTruthy()
atom.workspaceView.trigger 'activation-event'
waitsForPromise ->
promise
it "triggers the activation event on all handlers registered during activation", ->
waitsForPromise ->
atom.workspaceView.open()
runs ->
editorView = atom.workspaceView.getActiveView()
eventHandler = jasmine.createSpy("activation-event")
editorView.command 'activation-event', eventHandler
editorView.trigger 'activation-event'
expect(mainModule.activate.callCount).toBe 1
expect(mainModule.activationEventCallCount).toBe 1
expect(eventHandler.callCount).toBe 1
editorView.trigger 'activation-event'
expect(mainModule.activationEventCallCount).toBe 2
expect(eventHandler.callCount).toBe 2
expect(mainModule.activate.callCount).toBe 1
it "activates the package immediately when the events are empty", ->
mainModule = require './fixtures/packages/package-with-empty-activation-events/index'
spyOn(mainModule, 'activate').andCallThrough()
waitsForPromise ->
atom.packages.activatePackage('package-with-empty-activation-events')
runs ->
expect(mainModule.activate.callCount).toBe 1
describe "when the package has no main module", ->
it "does not throw an exception", ->
spyOn(console, "error")
spyOn(console, "warn").andCallThrough()
expect(-> atom.packages.activatePackage('package-without-module')).not.toThrow()
expect(console.error).not.toHaveBeenCalled()
expect(console.warn).not.toHaveBeenCalled()
it "passes the activate method the package's previously serialized state if it exists", ->
pack = null
waitsForPromise ->
atom.packages.activatePackage("package-with-serialization").then (p) -> pack = p
runs ->
expect(pack.mainModule.someNumber).not.toBe 77
pack.mainModule.someNumber = 77
atom.packages.deactivatePackage("package-with-serialization")
spyOn(pack.mainModule, 'activate').andCallThrough()
atom.packages.activatePackage("package-with-serialization")
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
it "logs warning instead of throwing an exception if the package fails to load", ->
atom.config.set("core.disabledPackages", [])
spyOn(console, "warn")
expect(-> atom.packages.activatePackage("package-that-throws-an-exception")).not.toThrow()
expect(console.warn).toHaveBeenCalled()
describe "keymap loading", ->
describe "when the metadata does not contain a 'keymaps' manifest", ->
it "loads all the .cson/.json files in the keymaps directory", ->
element1 = $$ -> @div class: 'test-1'
element2 = $$ -> @div class: 'test-2'
element3 = $$ -> @div class: 'test-3'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
atom.packages.activatePackage("package-with-keymaps")
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
describe "when the metadata contains a 'keymaps' manifest", ->
it "loads only the keymaps specified by the manifest, in the specified order", ->
element1 = $$ -> @div class: 'test-1'
element3 = $$ -> @div class: 'test-3'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
atom.packages.activatePackage("package-with-keymaps-manifest")
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
describe "menu loading", ->
beforeEach ->
atom.contextMenu.definitions = []
atom.menu.template = []
describe "when the metadata does not contain a 'menus' manifest", ->
it "loads all the .cson/.json files in the menus directory", ->
element = ($$ -> @div class: 'test-1')[0]
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
atom.packages.activatePackage("package-with-menus")
expect(atom.menu.template.length).toBe 2
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.definitionsForElement(element)[0].label).toBe "Menu item 1"
expect(atom.contextMenu.definitionsForElement(element)[1].label).toBe "Menu item 2"
expect(atom.contextMenu.definitionsForElement(element)[2].label).toBe "Menu item 3"
describe "when the metadata contains a 'menus' manifest", ->
it "loads only the menus specified by the manifest, in the specified order", ->
element = ($$ -> @div class: 'test-1')[0]
expect(atom.contextMenu.definitionsForElement(element)).toEqual []
atom.packages.activatePackage("package-with-menus-manifest")
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.definitionsForElement(element)[0].label).toBe "Menu item 2"
expect(atom.contextMenu.definitionsForElement(element)[1].label).toBe "Menu item 1"
expect(atom.contextMenu.definitionsForElement(element)[2]).toBeUndefined()
describe "stylesheet loading", ->
describe "when the metadata contains a 'stylesheets' manifest", ->
it "loads stylesheets from the stylesheets directory as specified by the manifest", ->
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
one = atom.themes.stringToId(one)
two = atom.themes.stringToId(two)
three = atom.themes.stringToId(three)
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
atom.packages.activatePackage("package-with-stylesheets-manifest")
expect(atom.themes.stylesheetElementForId(one)).toExist()
expect(atom.themes.stylesheetElementForId(two)).toExist()
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
expect($('#jasmine-content').css('font-size')).toBe '1px'
describe "when the metadata does not contain a 'stylesheets' manifest", ->
it "loads all stylesheets from the stylesheets directory", ->
one = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/1.css")
two = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/2.less")
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.css")
one = atom.themes.stringToId(one)
two = atom.themes.stringToId(two)
three = atom.themes.stringToId(three)
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
atom.packages.activatePackage("package-with-stylesheets")
expect(atom.themes.stylesheetElementForId(one)).toExist()
expect(atom.themes.stylesheetElementForId(two)).toExist()
expect(atom.themes.stylesheetElementForId(three)).toExist()
expect($('#jasmine-content').css('font-size')).toBe '3px'
describe "grammar loading", ->
it "loads the package's grammars", ->
waitsForPromise ->
atom.packages.activatePackage('package-with-grammars')
runs ->
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Alot'
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Alittle'
describe "scoped-property loading", ->
it "loads the scoped properties", ->
waitsForPromise ->
atom.packages.activatePackage("package-with-scoped-properties")
runs ->
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
describe "converted textmate packages", ->
it "loads the package's grammars", ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
waitsForPromise ->
atom.packages.activatePackage('language-ruby')
runs ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
it "loads the translated scoped properties", ->
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
waitsForPromise ->
atom.packages.activatePackage('language-ruby')
runs ->
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBe '# '
describe ".deactivatePackage(id)", ->
describe "atom packages", ->
it "calls `deactivate` on the package's main module if activate was successful", ->
pack = null
waitsForPromise ->
atom.packages.activatePackage("package-with-deactivate").then (p) -> pack = p
runs ->
expect(atom.packages.isPackageActive("package-with-deactivate")).toBeTruthy()
spyOn(pack.mainModule, 'deactivate').andCallThrough()
atom.packages.deactivatePackage("package-with-deactivate")
expect(pack.mainModule.deactivate).toHaveBeenCalled()
expect(atom.packages.isPackageActive("package-with-module")).toBeFalsy()
spyOn(console, 'warn')
badPack = null
waitsForPromise ->
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
runs ->
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeTruthy()
spyOn(badPack.mainModule, 'deactivate').andCallThrough()
atom.packages.deactivatePackage("package-that-throws-on-activate")
expect(badPack.mainModule.deactivate).not.toHaveBeenCalled()
expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeFalsy()
it "does not serialize packages that have not been activated called on their main module", ->
spyOn(console, 'warn')
badPack = null
waitsForPromise ->
atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p
runs ->
spyOn(badPack.mainModule, 'serialize').andCallThrough()
atom.packages.deactivatePackage("package-that-throws-on-activate")
expect(badPack.mainModule.serialize).not.toHaveBeenCalled()
it "absorbs exceptions that are thrown by the package module's serialize methods", ->
spyOn(console, 'error')
waitsForPromise ->
atom.packages.activatePackage('package-with-serialize-error')
waitsForPromise ->
atom.packages.activatePackage('package-with-serialization')
runs ->
atom.packages.deactivatePackages()
expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined()
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
expect(console.error).toHaveBeenCalled()
it "removes the package's grammars", ->
waitsForPromise ->
atom.packages.activatePackage('package-with-grammars')
runs ->
atom.packages.deactivatePackage('package-with-grammars')
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Null Grammar'
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar'
it "removes the package's keymaps", ->
waitsForPromise ->
atom.packages.activatePackage('package-with-keymaps')
runs ->
atom.packages.deactivatePackage('package-with-keymaps')
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target: ($$ -> @div class: 'test-1')[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target: ($$ -> @div class: 'test-2')[0])).toHaveLength 0
it "removes the package's stylesheets", ->
waitsForPromise ->
atom.packages.activatePackage('package-with-stylesheets')
runs ->
atom.packages.deactivatePackage('package-with-stylesheets')
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
it "removes the package's scoped-properties", ->
waitsForPromise ->
atom.packages.activatePackage("package-with-scoped-properties")
runs ->
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
atom.packages.deactivatePackage("package-with-scoped-properties")
expect(atom.syntax.getProperty ['.source.omg'], 'editor.increaseIndentPattern').toBeUndefined()
describe "textmate packages", ->
it "removes the package's grammars", ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
waitsForPromise ->
atom.packages.activatePackage('language-ruby')
runs ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
atom.packages.deactivatePackage('language-ruby')
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
it "removes the package's scoped properties", ->
waitsForPromise ->
atom.packages.activatePackage('language-ruby')
runs ->
atom.packages.deactivatePackage('language-ruby')
expect(atom.syntax.getProperty(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
describe ".activate()", ->
packageActivator = null
themeActivator = null
describe '::getSize and ::setSize', ->
originalSize = null
beforeEach ->
originalSize = atom.getSize()
afterEach ->
atom.setSize(originalSize.width, originalSize.height)
spyOn(console, 'warn')
atom.packages.loadPackages()
it 'sets the size of the window, and can retrieve the size just set', ->
atom.setSize(100, 400)
expect(atom.getSize()).toEqual width: 100, height: 400
loadedPackages = atom.packages.getLoadedPackages()
expect(loadedPackages.length).toBeGreaterThan 0
packageActivator = spyOn(atom.packages, 'activatePackages')
themeActivator = spyOn(atom.themes, 'activatePackages')
afterEach ->
atom.packages.unloadPackages()
Syntax = require '../src/syntax'
atom.syntax = window.syntax = new Syntax()
it "activates all the packages, and none of the themes", ->
atom.packages.activate()
expect(packageActivator).toHaveBeenCalled()
expect(themeActivator).toHaveBeenCalled()
packages = packageActivator.mostRecentCall.args[0]
expect(['atom', 'textmate']).toContain(pack.getType()) for pack in packages
themes = themeActivator.mostRecentCall.args[0]
expect(['theme']).toContain(theme.getType()) for theme in themes
describe ".enablePackage() and disablePackage()", ->
describe "with packages", ->
it ".enablePackage() enables a disabled package", ->
packageName = 'package-with-main'
atom.config.pushAtKeyPath('core.disabledPackages', packageName)
atom.packages.observeDisabledPackages()
expect(atom.config.get('core.disabledPackages')).toContain packageName
pack = atom.packages.enablePackage(packageName)
loadedPackages = atom.packages.getLoadedPackages()
activatedPackages = null
waitsFor ->
activatedPackages = atom.packages.getActivePackages()
activatedPackages.length > 0
runs ->
expect(loadedPackages).toContain(pack)
expect(activatedPackages).toContain(pack)
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
it ".disablePackage() disables an enabled package", ->
packageName = 'package-with-main'
waitsForPromise ->
atom.packages.activatePackage(packageName)
runs ->
atom.packages.observeDisabledPackages()
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
pack = atom.packages.disablePackage(packageName)
activatedPackages = atom.packages.getActivePackages()
expect(activatedPackages).not.toContain(pack)
expect(atom.config.get('core.disabledPackages')).toContain packageName
describe "with themes", ->
beforeEach ->
waitsForPromise ->
atom.themes.activateThemes()
afterEach ->
atom.themes.deactivateThemes()
atom.config.unobserve('core.themes')
it ".enablePackage() and .disablePackage() enables and disables a theme", ->
packageName = 'theme-with-package-file'
expect(atom.config.get('core.themes')).not.toContain packageName
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
# enabling of theme
pack = atom.packages.enablePackage(packageName)
waitsFor ->
pack in atom.packages.getActivePackages()
runs ->
expect(atom.config.get('core.themes')).toContain packageName
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
# disabling of theme
pack = atom.packages.disablePackage(packageName)
waitsFor ->
not (pack in atom.packages.getActivePackages())
runs ->
expect(atom.config.get('core.themes')).not.toContain packageName
expect(atom.config.get('core.themes')).not.toContain packageName
expect(atom.config.get('core.disabledPackages')).not.toContain packageName
describe ".isReleasedVersion()", ->
it "returns false if the version is a SHA and true otherwise", ->
version = '0.1.0'
spyOn(atom, 'getVersion').andCallFake -> version
spyOn(atom.constructor, 'getVersion').andCallFake -> version
expect(atom.isReleasedVersion()).toBe true
version = '36b5518'
expect(atom.isReleasedVersion()).toBe false
describe "window:update-available", ->
it "is triggered when the auto-updater sends the update-downloaded event", ->
updateAvailableHandler = jasmine.createSpy("update-available-handler")
atom.workspaceView.on 'window:update-available', updateAvailableHandler
autoUpdater = require('remote').require('auto-updater')
autoUpdater.emit 'update-downloaded', null, "notes", "version"
waitsFor ->
updateAvailableHandler.callCount > 0
runs ->
[event, version, notes] = updateAvailableHandler.mostRecentCall.args
expect(notes).toBe 'notes'
expect(version).toBe 'version'
describe "loading default config", ->
it 'loads the default core config', ->
expect(atom.config.get('core.excludeVcsIgnoredPaths')).toBe true
expect(atom.config.get('editor.showInvisibles')).toBe false
+1 -1
Ver Arquivo
@@ -20,7 +20,7 @@ describe "install(commandPath, callback)", ->
installDone = false
installError = null
installer.createSymlink commandFilePath, false, (error) ->
installer.install commandFilePath, false, (error) ->
installDone = true
installError = error
-191
Ver Arquivo
@@ -1,191 +0,0 @@
CommandRegistry = require '../src/command-registry'
describe "CommandRegistry", ->
[registry, parent, child, grandchild] = []
beforeEach ->
parent = document.createElement("div")
child = document.createElement("div")
grandchild = document.createElement("div")
parent.classList.add('parent')
child.classList.add('child')
grandchild.classList.add('grandchild')
child.appendChild(grandchild)
parent.appendChild(child)
document.querySelector('#jasmine-content').appendChild(parent)
registry = new CommandRegistry(parent)
describe "command dispatch", ->
it "invokes callbacks with selectors matching the target", ->
called = false
registry.add '.grandchild', 'command', (event) ->
expect(this).toBe grandchild
expect(event.type).toBe 'command'
expect(event.eventPhase).toBe Event.BUBBLING_PHASE
expect(event.target).toBe grandchild
expect(event.currentTarget).toBe grandchild
called = true
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(called).toBe true
it "invokes callbacks with selectors matching ancestors of the target", ->
calls = []
registry.add '.child', 'command', (event) ->
expect(this).toBe child
expect(event.target).toBe grandchild
expect(event.currentTarget).toBe child
calls.push('child')
registry.add '.parent', 'command', (event) ->
expect(this).toBe parent
expect(event.target).toBe grandchild
expect(event.currentTarget).toBe parent
calls.push('parent')
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(calls).toEqual ['child', 'parent']
it "orders multiple matching listeners for an element by selector specificity", ->
child.classList.add('foo', 'bar')
calls = []
registry.add '.foo.bar', 'command', -> calls.push('.foo.bar')
registry.add '.foo', 'command', -> calls.push('.foo')
registry.add '.bar', 'command', -> calls.push('.bar') # specificity ties favor commands added later, like CSS
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(calls).toEqual ['.foo.bar', '.bar', '.foo']
it "stops bubbling through ancestors when .stopPropagation() is called on the event", ->
calls = []
registry.add '.parent', 'command', -> calls.push('parent')
registry.add '.child', 'command', -> calls.push('child-2')
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopPropagation()
dispatchedEvent = new CustomEvent('command', bubbles: true)
spyOn(dispatchedEvent, 'stopPropagation')
grandchild.dispatchEvent(dispatchedEvent)
expect(calls).toEqual ['child-1', 'child-2']
expect(dispatchedEvent.stopPropagation).toHaveBeenCalled()
it "stops invoking callbacks when .stopImmediatePropagation() is called on the event", ->
calls = []
registry.add '.parent', 'command', -> calls.push('parent')
registry.add '.child', 'command', -> calls.push('child-2')
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopImmediatePropagation()
dispatchedEvent = new CustomEvent('command', bubbles: true)
spyOn(dispatchedEvent, 'stopImmediatePropagation')
grandchild.dispatchEvent(dispatchedEvent)
expect(calls).toEqual ['child-1']
expect(dispatchedEvent.stopImmediatePropagation).toHaveBeenCalled()
it "forwards .preventDefault() calls from the synthetic event to the original", ->
calls = []
registry.add '.child', 'command', (event) -> event.preventDefault()
dispatchedEvent = new CustomEvent('command', bubbles: true)
spyOn(dispatchedEvent, 'preventDefault')
grandchild.dispatchEvent(dispatchedEvent)
expect(dispatchedEvent.preventDefault).toHaveBeenCalled()
it "allows listeners to be removed via a disposable returned by ::add", ->
calls = []
disposable1 = registry.add '.parent', 'command', -> calls.push('parent')
disposable2 = registry.add '.child', 'command', -> calls.push('child')
disposable1.dispose()
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(calls).toEqual ['child']
calls = []
disposable2.dispose()
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(calls).toEqual []
it "allows multiple commands to be registered under one selector when called with an object", ->
calls = []
disposable = registry.add '.child',
'command-1': -> calls.push('command-1')
'command-2': -> calls.push('command-2')
grandchild.dispatchEvent(new CustomEvent('command-1', bubbles: true))
grandchild.dispatchEvent(new CustomEvent('command-2', bubbles: true))
expect(calls).toEqual ['command-1', 'command-2']
calls = []
disposable.dispose()
grandchild.dispatchEvent(new CustomEvent('command-1', bubbles: true))
grandchild.dispatchEvent(new CustomEvent('command-2', bubbles: true))
expect(calls).toEqual []
describe "::findCommands({target})", ->
it "returns commands that can be invoked on the target or its ancestors", ->
registry.add '.parent', 'namespace:command-1', ->
registry.add '.child', 'namespace:command-2', ->
registry.add '.grandchild', 'namespace:command-3', ->
registry.add '.grandchild.no-match', 'namespace:command-4', ->
expect(registry.findCommands(target: grandchild)[0..2]).toEqual [
{name: 'namespace:command-3', displayName: 'Namespace: Command 3'}
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
]
describe "::dispatch(target, commandName)", ->
it "simulates invocation of the given command ", ->
called = false
registry.add '.grandchild', 'command', (event) ->
expect(this).toBe grandchild
expect(event.type).toBe 'command'
expect(event.eventPhase).toBe Event.BUBBLING_PHASE
expect(event.target).toBe grandchild
expect(event.currentTarget).toBe grandchild
called = true
registry.dispatch(grandchild, 'command')
expect(called).toBe true
it "returns a boolean indicating whether any listeners matched the command", ->
registry.add '.grandchild', 'command', ->
expect(registry.dispatch(grandchild, 'command')).toBe true
expect(registry.dispatch(grandchild, 'bogus')).toBe false
expect(registry.dispatch(parent, 'command')).toBe false
describe "::getSnapshot and ::restoreSnapshot", ->
it "removes all command handlers except for those in the snapshot", ->
registry.add '.parent', 'namespace:command-1', ->
registry.add '.child', 'namespace:command-2', ->
snapshot = registry.getSnapshot()
registry.add '.grandchild', 'namespace:command-3', ->
expect(registry.findCommands(target: grandchild)[0..2]).toEqual [
{name: 'namespace:command-3', displayName: 'Namespace: Command 3'}
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
]
registry.restoreSnapshot(snapshot)
expect(registry.findCommands(target: grandchild)[0..1]).toEqual [
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
]
registry.add '.grandchild', 'namespace:command-3', ->
registry.restoreSnapshot(snapshot)
expect(registry.findCommands(target: grandchild)[0..1]).toEqual [
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
]
+19 -617
Ver Arquivo
@@ -12,7 +12,7 @@ describe "Config", ->
describe ".get(keyPath)", ->
it "allows a key path's value to be read", ->
expect(atom.config.set("foo.bar.baz", 42)).toBe true
expect(atom.config.set("foo.bar.baz", 42)).toBe 42
expect(atom.config.get("foo.bar.baz")).toBe 42
expect(atom.config.get("bogus.key.path")).toBeUndefined()
@@ -23,21 +23,9 @@ describe "Config", ->
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", a: 1, b: 2)
atom.config.set("foo", a: 3)
expect(atom.config.get("foo")).toEqual {a: 3, b: 2}
atom.config.set("foo", 7)
expect(atom.config.get("foo")).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 ".set(keyPath, value)", ->
it "allows a key path's value to be written", ->
expect(atom.config.set("foo.bar.baz", 42)).toBe true
expect(atom.config.set("foo.bar.baz", 42)).toBe 42
expect(atom.config.get("foo.bar.baz")).toBe 42
it "updates observers and saves when a key path is set", ->
@@ -48,7 +36,7 @@ describe "Config", ->
atom.config.set("foo.bar.baz", 42)
expect(atom.config.save).toHaveBeenCalled()
expect(observeHandler).toHaveBeenCalledWith 42
expect(observeHandler).toHaveBeenCalledWith 42, {previous: undefined}
describe "when the value equals the default value", ->
it "does not store the value", ->
@@ -139,7 +127,7 @@ describe "Config", ->
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")
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz"), {previous: ['a']}
describe ".unshiftAtKeyPath(keyPath, value)", ->
it "unshifts the given value to the array at the key path and updates observers", ->
@@ -150,7 +138,7 @@ describe "Config", ->
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")
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz"), {previous: ['b']}
describe ".removeAtKeyPath(keyPath, value)", ->
it "removes the given value from the array at the key path and updates observers", ->
@@ -161,22 +149,16 @@ describe "Config", ->
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")
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz"), {previous: ['a', 'b', 'c']}
describe ".getPositiveInt(keyPath, defaultValue)", ->
it "returns the proper coerced value", ->
it "returns the proper current or default value", ->
atom.config.set('editor.preferredLineLength', 0)
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1
it "returns the proper coerced value", ->
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80
atom.config.set('editor.preferredLineLength', -1234)
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1
it "returns the default value when a string is passed in", ->
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80
atom.config.set('editor.preferredLineLength', 'abcd')
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80
it "returns the default value when null is passed in", ->
atom.config.set('editor.preferredLineLength', null)
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80
@@ -232,54 +214,11 @@ describe "Config", ->
it "emits an updated event", ->
updatedCallback = jasmine.createSpy('updated')
atom.config.onDidChange('foo.bar.baz.a', updatedCallback)
atom.config.observe('foo.bar.baz.a', callNow: false, updatedCallback)
expect(updatedCallback.callCount).toBe 0
atom.config.setDefaults("foo.bar.baz", a: 2)
expect(updatedCallback.callCount).toBe 1
describe ".onDidChange(keyPath)", ->
[observeHandler, observeSubscription] = []
describe 'when a keyPath is specified', ->
beforeEach ->
observeHandler = jasmine.createSpy("observeHandler")
atom.config.set("foo.bar.baz", "value 1")
observeSubscription = 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", ->
observeHandler.reset() # clear the initial call
atom.config.set('foo.bar.baz', "value 2")
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
observeHandler.reset()
atom.config.set('foo.bar.baz', "value 1")
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
describe 'when a keyPath is not specified', ->
beforeEach ->
observeHandler = jasmine.createSpy("observeHandler")
atom.config.set("foo.bar.baz", "value 1")
observeSubscription = 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).toHaveBeenCalledWith({newValue: 'value 2', oldValue: 'value 1', keyPath: 'foo.bar.baz'})
observeHandler.reset()
atom.config.set('foo.bar.baz', "value 1")
expect(observeHandler).toHaveBeenCalledWith({newValue: 'value 1', oldValue: 'value 2', keyPath: 'foo.bar.baz'})
observeHandler.reset()
atom.config.set('foo.bar.int', 1)
expect(observeHandler).toHaveBeenCalledWith({newValue: 1, oldValue: undefined, keyPath: 'foo.bar.int'})
describe ".observe(keyPath)", ->
[observeHandler, observeSubscription] = []
@@ -294,25 +233,26 @@ describe "Config", ->
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")
expect(observeHandler).toHaveBeenCalledWith("value 2", {previous: 'value 1'})
observeHandler.reset()
atom.config.set('foo.bar.baz', "value 1")
expect(observeHandler).toHaveBeenCalledWith("value 1")
expect(observeHandler).toHaveBeenCalledWith("value 1", {previous: 'value 2'})
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)
expect(observeHandler).toHaveBeenCalledWith(undefined, {previous: 'value 1'})
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)
expect(observeHandler).toHaveBeenCalledWith(undefined, {previous: 'value 1'})
observeHandler.reset()
atom.config.set("foo.bar.baz", "i'm back")
expect(observeHandler).toHaveBeenCalledWith("i'm back")
expect(observeHandler).toHaveBeenCalledWith("i'm back", {previous: undefined})
it "does not fire the callback once the observe subscription is off'ed", ->
observeHandler.reset() # clear the initial call
@@ -359,19 +299,11 @@ describe "Config", ->
describe "when the config file contains valid cson", ->
beforeEach ->
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'baz'")
atom.config.loadUserConfig()
it "updates the config data based on the file contents", ->
atom.config.loadUserConfig()
expect(atom.config.get("foo.bar")).toBe 'baz'
it "notifies observers for updated keypaths on load", ->
observeHandler = jasmine.createSpy("observeHandler")
observeSubscription = atom.config.observe "foo.bar", observeHandler
atom.config.loadUserConfig()
expect(observeHandler).toHaveBeenCalledWith 'baz'
describe "when the config file contains invalid cson", ->
beforeEach ->
spyOn(console, 'error')
@@ -390,43 +322,10 @@ describe "Config", ->
expect(fs.existsSync(atom.config.configFilePath)).toBe true
expect(CSON.readFileSync(atom.config.configFilePath)).toEqual {}
describe "when a schema is specified", ->
beforeEach ->
schema =
type: 'object'
properties:
bar:
type: 'string'
default: 'def'
int:
type: 'integer'
default: 12
atom.config.setSchema('foo', schema)
describe "when the config file contains values that do not adhere to the schema", ->
warnSpy = null
beforeEach ->
warnSpy = spyOn console, 'warn'
fs.writeFileSync atom.config.configFilePath, """
foo:
bar: 'baz'
int: 'bad value'
"""
atom.config.loadUserConfig()
it "updates the only the settings that have values matching the schema", ->
expect(atom.config.get("foo.bar")).toBe 'baz'
expect(atom.config.get("foo.int")).toBe 12
expect(warnSpy).toHaveBeenCalled()
expect(warnSpy.mostRecentCall.args[0]).toContain "'foo.int' could not be set"
describe ".observeUserConfig()", ->
updatedHandler = null
beforeEach ->
atom.config.setDefaults('foo', bar: 'def')
atom.config.configDirPath = dotAtomPath
atom.config.configFilePath = path.join(atom.config.configDirPath, "atom.config.cson")
expect(fs.existsSync(atom.config.configDirPath)).toBeFalsy()
@@ -434,7 +333,7 @@ describe "Config", ->
atom.config.loadUserConfig()
atom.config.observeUserConfig()
updatedHandler = jasmine.createSpy("updatedHandler")
atom.config.onDidChange updatedHandler
atom.config.on 'updated', updatedHandler
afterEach ->
atom.config.unobserveUserConfig()
@@ -448,60 +347,6 @@ describe "Config", ->
expect(atom.config.get('foo.bar')).toBe 'quux'
expect(atom.config.get('foo.baz')).toBe 'bar'
it "does not fire a change event for paths that did not change", ->
atom.config.onDidChange 'foo.bar', noChangeSpy = jasmine.createSpy()
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: 'baz', omg: 'ok'}")
waitsFor 'update event', -> updatedHandler.callCount > 0
runs ->
expect(noChangeSpy).not.toHaveBeenCalled()
expect(atom.config.get('foo.bar')).toBe 'baz'
expect(atom.config.get('foo.omg')).toBe 'ok'
describe 'when the default value is a complex value', ->
beforeEach ->
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok']}")
waitsFor 'update event', -> updatedHandler.callCount > 0
runs -> updatedHandler.reset()
it "does not fire a change event for paths that did not change", ->
atom.config.onDidChange 'foo.bar', noChangeSpy = jasmine.createSpy()
fs.writeFileSync(atom.config.configFilePath, "foo: { bar: ['baz', 'ok'], omg: 'another'}")
waitsFor 'update event', -> updatedHandler.callCount > 0
runs ->
expect(noChangeSpy).not.toHaveBeenCalled()
expect(atom.config.get('foo.bar')).toEqual ['baz', 'ok']
expect(atom.config.get('foo.omg')).toBe 'another'
describe "when the config file changes to omit a setting with a default", ->
it "resets the setting back to the default", ->
fs.writeFileSync(atom.config.configFilePath, "foo: { baz: 'new'}")
waitsFor 'update event', -> updatedHandler.callCount > 0
runs ->
expect(atom.config.get('foo.bar')).toBe 'def'
expect(atom.config.get('foo.baz')).toBe 'new'
describe "when the config file changes to be empty", ->
beforeEach ->
fs.writeFileSync(atom.config.configFilePath, "")
waitsFor 'update event', -> updatedHandler.callCount > 0
it "resets all settings back to the defaults", ->
expect(updatedHandler.callCount).toBe 1
expect(atom.config.get('foo.bar')).toBe 'def'
atom.config.set("hair", "blonde") # trigger a save
expect(atom.config.save).toHaveBeenCalled()
describe "when the config file subsequently changes again to contain configuration", ->
beforeEach ->
updatedHandler.reset()
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'newVal'")
waitsFor 'update event', -> updatedHandler.callCount > 0
it "sets the setting to the value specified in the config file", ->
expect(atom.config.get('foo.bar')).toBe 'newVal'
describe "when the config file changes to contain invalid cson", ->
beforeEach ->
spyOn(console, 'error')
@@ -516,452 +361,9 @@ describe "Config", ->
describe "when the config file subsequently changes again to contain valid cson", ->
beforeEach ->
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'newVal'")
fs.writeFileSync(atom.config.configFilePath, "foo: bar: 'baz'")
waitsFor 'update event', -> updatedHandler.callCount > 0
it "updates the config data and resumes saving", ->
atom.config.set("hair", "blonde")
expect(atom.config.save).toHaveBeenCalled()
describe "when a schema is specified", ->
schema = null
describe '.setSchema(keyPath, schema)', ->
it 'creates a properly nested schema', ->
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', ->
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
it 'can set a non-object schema', ->
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
describe '.getSchema(keyPath)', ->
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
describe 'when the value has an "integer" type', ->
beforeEach ->
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 ->
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 ->
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 ->
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 ->
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 ->
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 ->
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 ->
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'
describe 'when the value has an "object" type', ->
beforeEach ->
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 an "array" type', ->
beforeEach ->
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]
describe 'when the `enum` key is used', ->
beforeEach ->
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']
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']
describe "scoped settings", ->
describe ".get(scopeDescriptor, keyPath)", ->
it "returns the property with the most specific scope selector", ->
atom.config.addScopedSettings(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
atom.config.addScopedSettings(".source", foo: bar: baz: 11)
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
expect(atom.config.get([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
expect(atom.config.get([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
expect(atom.config.get([".text"], "foo.bar.baz")).toBeUndefined()
it "favors the most recently added properties in the event of a specificity tie", ->
atom.config.addScopedSettings(".source.coffee .string.quoted.single", foo: bar: baz: 42)
atom.config.addScopedSettings(".source.coffee .string.quoted.double", foo: bar: baz: 22)
expect(atom.config.get([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
expect(atom.config.get([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).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([".source.coffee", ".string.quoted.single"], "foo.hasDefault")).toBe 'ok'
describe ".set(scope, keyPath, value)", ->
it "sets the value and overrides the others", ->
atom.config.addScopedSettings(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
atom.config.addScopedSettings(".source", foo: bar: baz: 11)
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
expect(atom.config.set(".source.coffee .string.quoted.double.coffee", "foo.bar.baz", 100)).toBe true
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 100
describe ".removeScopedSettingsForName(name)", ->
it "allows properties to be removed by name", ->
disposable1 = atom.config.addScopedSettings("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
disposable2 = atom.config.addScopedSettings("b", ".source .string.quoted.double", foo: bar: baz: 22)
disposable2.dispose()
expect(atom.config.get([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
expect(atom.config.get([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
describe ".observe(scopeDescriptor, keyPath)", ->
it 'calls the supplied callback when the value at the descriptor/keypath changes', ->
atom.config.observe [".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz", changeSpy = jasmine.createSpy()
expect(changeSpy).toHaveBeenCalledWith(undefined)
changeSpy.reset()
atom.config.set("foo.bar.baz", 12)
expect(changeSpy).toHaveBeenCalledWith(12)
changeSpy.reset()
disposable1 = atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
expect(changeSpy).toHaveBeenCalledWith(22)
changeSpy.reset()
disposable2 = atom.config.addScopedSettings("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
expect(changeSpy).toHaveBeenCalledWith(42)
changeSpy.reset()
disposable2.dispose()
expect(changeSpy).toHaveBeenCalledWith(22)
changeSpy.reset()
disposable1.dispose()
expect(changeSpy).toHaveBeenCalledWith(12)
changeSpy.reset()
atom.config.set("foo.bar.baz", undefined)
expect(changeSpy).toHaveBeenCalledWith(undefined)
changeSpy.reset()
describe ".onDidChange(scopeDescriptor, keyPath)", ->
it 'calls the supplied callback when the value at the descriptor/keypath changes', ->
keyPath = "foo.bar.baz"
atom.config.onDidChange [".source.coffee", ".string.quoted.double.coffee"], keyPath, changeSpy = jasmine.createSpy()
atom.config.set("foo.bar.baz", 12)
expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12, keyPath})
changeSpy.reset()
disposable1 = atom.config.addScopedSettings(".source .string.quoted.double", foo: bar: baz: 22)
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: 22, keyPath})
changeSpy.reset()
disposable2 = atom.config.addScopedSettings("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 42, keyPath})
changeSpy.reset()
disposable2.dispose()
expect(changeSpy).toHaveBeenCalledWith({oldValue: 42, newValue: 22, keyPath})
changeSpy.reset()
disposable1.dispose()
expect(changeSpy).toHaveBeenCalledWith({oldValue: 22, newValue: 12, keyPath})
changeSpy.reset()
atom.config.set("foo.bar.baz", undefined)
expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined, keyPath})
changeSpy.reset()
+113 -150
Ver Arquivo
@@ -3,172 +3,135 @@
ContextMenuManager = require '../src/context-menu-manager'
describe "ContextMenuManager", ->
[contextMenu, parent, child, grandchild] = []
[contextMenu] = []
beforeEach ->
{resourcePath} = atom.getLoadSettings()
contextMenu = new ContextMenuManager({resourcePath})
contextMenu = new ContextMenuManager
parent = document.createElement("div")
child = document.createElement("div")
grandchild = document.createElement("div")
parent.classList.add('parent')
child.classList.add('child')
grandchild.classList.add('grandchild')
child.appendChild(grandchild)
parent.appendChild(child)
describe "adding definitions", ->
it 'loads', ->
contextMenu.add 'file-path',
'.selector':
'label': 'command'
describe "::add(itemsBySelector)", ->
it "can add top-level menu items that can be removed with the returned disposable", ->
disposable = contextMenu.add
'.parent': [{label: 'A', command: 'a'}]
'.child': [{label: 'B', command: 'b'}]
'.grandchild': [{label: 'C', command: 'c'}]
expect(contextMenu.definitions['.selector'][0].label).toEqual 'label'
expect(contextMenu.definitions['.selector'][0].command).toEqual 'command'
expect(contextMenu.templateForElement(grandchild)).toEqual [
{label: 'C', command: 'c'}
{label: 'B', command: 'b'}
{label: 'A', command: 'a'}
]
it "loads submenus", ->
contextMenu.add 'file-path',
'.selector':
'parent':
'child-1': 'child-1:trigger'
'child-2': 'child-2:trigger'
'parent-2': 'parent-2:trigger'
disposable.dispose()
expect(contextMenu.templateForElement(grandchild)).toEqual []
expect(contextMenu.definitions['.selector'].length).toBe 2
expect(contextMenu.definitions['.selector'][0].label).toEqual 'parent'
expect(contextMenu.definitions['.selector'][0].submenu.length).toBe 2
expect(contextMenu.definitions['.selector'][0].submenu[0].label).toBe 'child-1'
expect(contextMenu.definitions['.selector'][0].submenu[0].command).toBe 'child-1:trigger'
expect(contextMenu.definitions['.selector'][0].submenu[1].label).toBe 'child-2'
expect(contextMenu.definitions['.selector'][0].submenu[1].command).toBe 'child-2:trigger'
it "can add submenu items to existing menus that can be removed with the returned disposable", ->
disposable1 = contextMenu.add
'.grandchild': [{label: 'A', submenu: [{label: 'B', command: 'b'}]}]
disposable2 = contextMenu.add
'.grandchild': [{label: 'A', submenu: [{label: 'C', command: 'c'}]}]
describe 'dev mode', ->
it 'loads', ->
contextMenu.add 'file-path',
'.selector':
'label': 'command'
, devMode: true
expect(contextMenu.templateForElement(grandchild)).toEqual [{
label: 'A',
submenu: [
{label: 'B', command: 'b'}
{label: 'C', command: 'c'}
expect(contextMenu.devModeDefinitions['.selector'][0].label).toEqual 'label'
expect(contextMenu.devModeDefinitions['.selector'][0].command).toEqual 'command'
describe "building a menu template", ->
beforeEach ->
contextMenu.definitions = {
'.parent':[
label: 'parent'
command: 'command-p'
]
'.child': [
label: 'child'
command: 'command-c'
]
}]
disposable2.dispose()
expect(contextMenu.templateForElement(grandchild)).toEqual [{
label: 'A',
submenu: [
{label: 'B', command: 'b'}
]
}]
disposable1.dispose()
expect(contextMenu.templateForElement(grandchild)).toEqual []
it "favors the most specific / recently added item in the case of a duplicate label", ->
grandchild.classList.add('foo')
disposable1 = contextMenu.add
'.grandchild': [{label: 'A', command: 'a'}]
disposable2 = contextMenu.add
'.grandchild.foo': [{label: 'A', command: 'b'}]
disposable3 = contextMenu.add
'.grandchild': [{label: 'A', command: 'c'}]
disposable4 = contextMenu.add
'.child': [{label: 'A', command: 'd'}]
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'b'}]
disposable2.dispose()
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'c'}]
disposable3.dispose()
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'a'}]
disposable1.dispose()
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'd'}]
it "allows multiple separators, but not adjacent to each other", ->
contextMenu.add
'.grandchild': [
{label: 'A', command: 'a'},
{type: 'separator'},
{type: 'separator'},
{label: 'B', command: 'b'},
{type: 'separator'},
{type: 'separator'},
{label: 'C', command: 'c'}
]
expect(contextMenu.templateForElement(grandchild)).toEqual [
{label: 'A', command: 'a'},
{type: 'separator'},
{label: 'B', command: 'b'},
{type: 'separator'},
{label: 'C', command: 'c'}
]
it "excludes items marked for display in devMode unless in dev mode", ->
disposable1 = contextMenu.add
'.grandchild': [{label: 'A', command: 'a', devMode: true}, {label: 'B', command: 'b', devMode: false}]
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'B', command: 'b'}]
contextMenu.devMode = true
expect(contextMenu.templateForElement(grandchild)).toEqual [{label: 'A', command: 'a'}, {label: 'B', command: 'b'}]
it "allows items to be associated with `created` hooks which are invoked on template construction with the item and event", ->
createdEvent = null
item = {
label: 'A',
command: 'a',
created: (event) ->
@command = 'b'
createdEvent = event
}
contextMenu.add('.grandchild': [item])
contextMenu.devModeDefinitions =
'.parent': [
label: 'dev-label'
command: 'dev-command'
]
dispatchedEvent = {target: grandchild}
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual [{label: 'A', command: 'b'}]
expect(item.command).toBe 'a' # doesn't modify original item template
expect(createdEvent).toBe dispatchedEvent
describe "on a single element", ->
[element] = []
it "allows items to be associated with `shouldDisplay` hooks which are invoked on construction to determine whether the item should be included", ->
shouldDisplayEvent = null
shouldDisplay = true
beforeEach ->
element = ($$ -> @div class: 'parent')[0]
item = {
label: 'A',
command: 'a',
shouldDisplay: (event) ->
@foo = 'bar'
shouldDisplayEvent = event
shouldDisplay
}
contextMenu.add('.grandchild': [item])
it "creates a menu with a single item", ->
menu = contextMenu.combinedMenuTemplateForElement(element)
dispatchedEvent = {target: grandchild}
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual [{label: 'A', command: 'a'}]
expect(item.foo).toBeUndefined() # doesn't modify original item template
expect(shouldDisplayEvent).toBe dispatchedEvent
expect(menu[0].label).toEqual 'parent'
expect(menu[0].command).toEqual 'command-p'
expect(menu[1]).toBeUndefined()
shouldDisplay = false
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual []
describe "in devMode", ->
beforeEach -> contextMenu.devMode = true
it "allows items to be specified in the legacy format for now", ->
contextMenu.add '.parent':
'A': 'a'
'Separator 1': '-'
'B':
'C': 'c'
'Separator 2': '-'
'D': 'd'
it "creates a menu with development items", ->
menu = contextMenu.combinedMenuTemplateForElement(element)
expect(contextMenu.templateForElement(parent)).toEqual [
{label: 'A', command: 'a'}
{type: 'separator'}
{
label: 'B'
submenu: [
{label: 'C', command: 'c'}
{type: 'separator'}
{label: 'D', command: 'd'}
]
}
expect(menu[0].label).toEqual 'parent'
expect(menu[0].command).toEqual 'command-p'
expect(menu[1].type).toEqual 'separator'
expect(menu[2].label).toEqual 'dev-label'
expect(menu[2].command).toEqual 'dev-command'
describe "on multiple elements", ->
[element] = []
beforeEach ->
element = $$ ->
@div class: 'parent', =>
@div class: 'child'
element = element.find('.child')[0]
it "creates a menu with a two items", ->
menu = contextMenu.combinedMenuTemplateForElement(element)
expect(menu[0].label).toEqual 'child'
expect(menu[0].command).toEqual 'command-c'
expect(menu[1].label).toEqual 'parent'
expect(menu[1].command).toEqual 'command-p'
expect(menu[2]).toBeUndefined()
describe "in devMode", ->
beforeEach -> contextMenu.devMode = true
xit "creates a menu with development items", ->
menu = contextMenu.combinedMenuTemplateForElement(element)
expect(menu[0].label).toEqual 'child'
expect(menu[0].command).toEqual 'command-c'
expect(menu[1].label).toEqual 'parent'
expect(menu[1].command).toEqual 'command-p'
expect(menu[2].label).toEqual 'dev-label'
expect(menu[2].command).toEqual 'dev-command'
expect(menu[3]).toBeUndefined()
describe "executeBuildHandlers", ->
menuTemplate = [
label: 'label'
executeAtBuild: ->
]
event =
target: null
it 'should invoke the executeAtBuild fn', ->
buildFn = spyOn(menuTemplate[0], 'executeAtBuild')
contextMenu.executeBuildHandlers(event, menuTemplate)
expect(buildFn).toHaveBeenCalled()
expect(buildFn.mostRecentCall.args[0]).toBe event
+20 -31
Ver Arquivo
@@ -1,44 +1,33 @@
DeserializerManager = require '../src/deserializer-manager'
describe "DeserializerManager", ->
manager = null
describe ".deserialize(state)", ->
deserializer = null
class Foo
@deserialize: ({name}) -> new Foo(name)
constructor: (@name) ->
beforeEach ->
manager = new DeserializerManager
deserializer = new DeserializerManager()
deserializer.add(Foo)
describe "::add(deserializer)", ->
it "returns a disposable that can be used to remove the manager", ->
disposable = manager.add(Foo)
expect(manager.deserialize({deserializer: 'Foo', name: 'Bar'})).toBeDefined()
disposable.dispose()
spyOn(console, 'warn')
expect(manager.deserialize({deserializer: 'Foo', name: 'Bar'})).toBeUndefined()
it "calls deserialize on the deserializer for the given state object, or returns undefined if one can't be found", ->
spyOn(console, 'warn')
object = deserializer.deserialize({ deserializer: 'Foo', name: 'Bar' })
expect(object.name).toBe 'Bar'
expect(deserializer.deserialize({ deserializer: 'Bogus' })).toBeUndefined()
describe "::deserialize(state)", ->
describe "when the deserializer has a version", ->
beforeEach ->
manager.add(Foo)
Foo.version = 2
it "calls deserialize on the manager for the given state object, or returns undefined if one can't be found", ->
spyOn(console, 'warn')
object = manager.deserialize({deserializer: 'Foo', name: 'Bar'})
expect(object.name).toBe 'Bar'
expect(manager.deserialize({deserializer: 'Bogus'})).toBeUndefined()
describe "when the deserialized state has a matching version", ->
it "attempts to deserialize the state", ->
object = deserializer.deserialize({ deserializer: 'Foo', version: 2, name: 'Bar' })
expect(object.name).toBe 'Bar'
describe "when the manager has a version", ->
beforeEach ->
Foo.version = 2
describe "when the deserialized state has a matching version", ->
it "attempts to deserialize the state", ->
object = manager.deserialize({deserializer: 'Foo', version: 2, name: 'Bar'})
expect(object.name).toBe 'Bar'
describe "when the deserialized state has a non-matching version", ->
it "returns undefined", ->
expect(manager.deserialize({deserializer: 'Foo', version: 3, name: 'Bar'})).toBeUndefined()
expect(manager.deserialize({deserializer: 'Foo', version: 1, name: 'Bar'})).toBeUndefined()
expect(manager.deserialize({deserializer: 'Foo', name: 'Bar'})).toBeUndefined()
describe "when the deserialized state has a non-matching version", ->
it "returns undefined", ->
expect(deserializer.deserialize({ deserializer: 'Foo', version: 3, name: 'Bar' })).toBeUndefined()
expect(deserializer.deserialize({ deserializer: 'Foo', version: 1, name: 'Bar' })).toBeUndefined()
expect(deserializer.deserialize({ deserializer: 'Foo', name: 'Bar' })).toBeUndefined()
+128 -267
Ver Arquivo
@@ -9,7 +9,7 @@ describe "DisplayBuffer", ->
buffer = atom.project.bufferForPathSync('sample.js')
displayBuffer = new DisplayBuffer({buffer, tabLength})
changeHandler = jasmine.createSpy 'changeHandler'
displayBuffer.onDidChange changeHandler
displayBuffer.on 'changed', changeHandler
waitsForPromise ->
atom.packages.activatePackage('language-javascript')
@@ -47,18 +47,9 @@ describe "DisplayBuffer", ->
buffer.insert([0,0], oneHundredLines)
expect(displayBuffer.getLineCount()).toBe 100 + originalLineCount
it "reassigns the scrollTop if it exceeds the max possible value after lines are removed", ->
displayBuffer.manageScrollPosition = true
displayBuffer.setHeight(50)
displayBuffer.setLineHeightInPixels(10)
displayBuffer.setScrollTop(80)
buffer.delete([[8, 0], [10, 0]])
expect(displayBuffer.getScrollTop()).toBe 60
describe "soft wrapping", ->
beforeEach ->
displayBuffer.setSoftWrapped(true)
displayBuffer.setSoftWrap(true)
displayBuffer.setEditorWidthInChars(50)
changeHandler.reset()
@@ -67,48 +58,48 @@ describe "DisplayBuffer", ->
it "uses the preferred line length as the soft wrap column when it is less than the configured soft wrap column", ->
atom.config.set('editor.preferredLineLength', 100)
atom.config.set('editor.softWrapAtPreferredLineLength', true)
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
expect(displayBuffer.lineForRow(10).text).toBe ' return '
atom.config.set('editor.preferredLineLength', 5)
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe 'funct'
expect(displayBuffer.lineForRow(10).text).toBe 'funct'
atom.config.set('editor.softWrapAtPreferredLineLength', false)
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
expect(displayBuffer.lineForRow(10).text).toBe ' return '
describe "when the line is shorter than the max line length", ->
it "renders the line unchanged", ->
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe buffer.lineForRow(0)
expect(displayBuffer.lineForRow(0).text).toBe buffer.lineForRow(0)
describe "when the line is empty", ->
it "renders the empty line", ->
expect(displayBuffer.tokenizedLineForScreenRow(13).text).toBe ''
expect(displayBuffer.lineForRow(13).text).toBe ''
describe "when there is a non-whitespace character at the max length boundary", ->
describe "when there is whitespace before the boundary", ->
it "wraps the line at the end of the first whitespace preceding the boundary", ->
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' return '
expect(displayBuffer.tokenizedLineForScreenRow(11).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
expect(displayBuffer.lineForRow(10).text).toBe ' return '
expect(displayBuffer.lineForRow(11).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
describe "when there is no whitespace before the boundary", ->
it "wraps the line exactly at the boundary since there's no more graceful place to wrap it", ->
buffer.setTextInRange([[0, 0], [1, 0]], 'abcdefghijklmnopqrstuvwxyz\n')
displayBuffer.setEditorWidthInChars(10)
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe 'abcdefghij'
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe 'klmnopqrst'
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe 'uvwxyz'
expect(displayBuffer.lineForRow(0).text).toBe 'abcdefghij'
expect(displayBuffer.lineForRow(1).text).toBe 'klmnopqrst'
expect(displayBuffer.lineForRow(2).text).toBe 'uvwxyz'
describe "when there is a whitespace character at the max length boundary", ->
it "wraps the line at the first non-whitespace character following the boundary", ->
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe ' var pivot = items.shift(), current, left = [], '
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe 'right = [];'
expect(displayBuffer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = [], '
expect(displayBuffer.lineForRow(4).text).toBe 'right = [];'
describe "when there are hard tabs", ->
beforeEach ->
buffer.setText(buffer.getText().replace(new RegExp(' ', 'g'), '\t'))
it "correctly tokenizes the hard tabs", ->
expect(displayBuffer.tokenizedLineForScreenRow(3).tokens[0].isHardTab).toBeTruthy()
expect(displayBuffer.tokenizedLineForScreenRow(3).tokens[1].isHardTab).toBeTruthy()
expect(displayBuffer.lineForRow(3).tokens[0].isHardTab).toBeTruthy()
expect(displayBuffer.lineForRow(3).tokens[1].isHardTab).toBeTruthy()
describe "when the buffer changes", ->
describe "when buffer lines are updated", ->
@@ -121,57 +112,57 @@ describe "DisplayBuffer", ->
describe "when the update makes a soft-wrapped line shorter than the max line length", ->
it "rewraps the line and emits a change event", ->
buffer.delete([[6, 24], [6, 42]])
expect(displayBuffer.tokenizedLineForScreenRow(7).text).toBe ' current < pivot ? : right.push(current);'
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toBe ' }'
expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot ? : right.push(current);'
expect(displayBuffer.lineForRow(8).text).toBe ' }'
expect(changeHandler).toHaveBeenCalled()
[[event]]= changeHandler.argsForCall
expect(event).toEqual(start: 7, end: 8, screenDelta: -1, bufferDelta: 0)
describe "when the update causes a line to soft wrap an additional time", ->
describe "when the update causes a line to softwrap an additional time", ->
it "rewraps the line and emits a change event", ->
buffer.insert([6, 28], '1234567890')
expect(displayBuffer.tokenizedLineForScreenRow(7).text).toBe ' current < pivot ? '
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toBe 'left1234567890.push(current) : '
expect(displayBuffer.tokenizedLineForScreenRow(9).text).toBe 'right.push(current);'
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe ' }'
expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot ? '
expect(displayBuffer.lineForRow(8).text).toBe 'left1234567890.push(current) : '
expect(displayBuffer.lineForRow(9).text).toBe 'right.push(current);'
expect(displayBuffer.lineForRow(10).text).toBe ' }'
expect(changeHandler).toHaveBeenCalledWith(start: 7, end: 8, screenDelta: 1, bufferDelta: 0)
describe "when buffer lines are inserted", ->
it "inserts / updates wrapped lines and emits a change event", ->
buffer.insert([6, 21], '1234567890 abcdefghij 1234567890\nabcdefghij')
expect(displayBuffer.tokenizedLineForScreenRow(7).text).toBe ' current < pivot1234567890 abcdefghij '
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toBe '1234567890'
expect(displayBuffer.tokenizedLineForScreenRow(9).text).toBe 'abcdefghij ? left.push(current) : '
expect(displayBuffer.tokenizedLineForScreenRow(10).text).toBe 'right.push(current);'
expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot1234567890 abcdefghij '
expect(displayBuffer.lineForRow(8).text).toBe '1234567890'
expect(displayBuffer.lineForRow(9).text).toBe 'abcdefghij ? left.push(current) : '
expect(displayBuffer.lineForRow(10).text).toBe 'right.push(current);'
expect(changeHandler).toHaveBeenCalledWith(start: 7, end: 8, screenDelta: 2, bufferDelta: 1)
describe "when buffer lines are removed", ->
it "removes lines and emits a change event", ->
buffer.setTextInRange([[3, 21], [7, 5]], ';')
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe ' var pivot = items;'
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe ' return '
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toBe ' };'
expect(displayBuffer.lineForRow(3).text).toBe ' var pivot = items;'
expect(displayBuffer.lineForRow(4).text).toBe ' return '
expect(displayBuffer.lineForRow(5).text).toBe 'sort(left).concat(pivot).concat(sort(right));'
expect(displayBuffer.lineForRow(6).text).toBe ' };'
expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 9, screenDelta: -6, bufferDelta: -4)
describe "when a newline is inserted, deleted, and re-inserted at the end of a wrapped line (regression)", ->
it "correctly renders the original wrapped line", ->
buffer = atom.project.buildBufferSync(null, '')
displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrapped: true})
displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrap: true})
buffer.insert([0, 0], "the quick brown fox jumps over the lazy dog.")
buffer.insert([0, Infinity], '\n')
buffer.delete([[0, Infinity], [1, 0]])
buffer.insert([0, Infinity], '\n')
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "the quick brown fox jumps over "
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "the lazy dog."
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe ""
expect(displayBuffer.lineForRow(0).text).toBe "the quick brown fox jumps over "
expect(displayBuffer.lineForRow(1).text).toBe "the lazy dog."
expect(displayBuffer.lineForRow(2).text).toBe ""
describe "position translation", ->
it "translates positions accounting for wrapped lines", ->
@@ -204,9 +195,9 @@ describe "DisplayBuffer", ->
describe ".setEditorWidthInChars(length)", ->
it "changes the length at which lines are wrapped and emits a change event for all screen lines", ->
displayBuffer.setEditorWidthInChars(40)
expect(tokensText displayBuffer.tokenizedLineForScreenRow(4).tokens).toBe 'left = [], right = [];'
expect(tokensText displayBuffer.tokenizedLineForScreenRow(5).tokens).toBe ' while(items.length > 0) {'
expect(tokensText displayBuffer.tokenizedLineForScreenRow(12).tokens).toBe 'sort(left).concat(pivot).concat(sort(rig'
expect(tokensText displayBuffer.lineForRow(4).tokens).toBe 'left = [], right = [];'
expect(tokensText displayBuffer.lineForRow(5).tokens).toBe ' while(items.length > 0) {'
expect(tokensText displayBuffer.lineForRow(12).tokens).toBe 'sort(left).concat(pivot).concat(sort(rig'
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 15, screenDelta: 3, bufferDelta: 0)
it "only allows positive widths to be assigned", ->
@@ -215,26 +206,13 @@ describe "DisplayBuffer", ->
displayBuffer.setEditorWidthInChars(-1)
expect(displayBuffer.editorWidthInChars).not.toBe -1
it "sets ::scrollLeft to 0 and keeps it there when soft wrapping is enabled", ->
displayBuffer.setDefaultCharWidth(10)
displayBuffer.setWidth(50)
displayBuffer.manageScrollPosition = true
displayBuffer.setSoftWrapped(false)
displayBuffer.setScrollLeft(Infinity)
expect(displayBuffer.getScrollLeft()).toBeGreaterThan 0
displayBuffer.setSoftWrapped(true)
expect(displayBuffer.getScrollLeft()).toBe 0
displayBuffer.setScrollLeft(10)
expect(displayBuffer.getScrollLeft()).toBe 0
describe "primitive folding", ->
beforeEach ->
displayBuffer.destroy()
buffer.release()
buffer = atom.project.bufferForPathSync('two-hundred.txt')
displayBuffer = new DisplayBuffer({buffer, tabLength})
displayBuffer.onDidChange changeHandler
displayBuffer.on 'changed', changeHandler
describe "when folds are created and destroyed", ->
describe "when a fold spans multiple lines", ->
@@ -242,7 +220,7 @@ describe "DisplayBuffer", ->
fold = displayBuffer.createFold(4, 7)
expect(fold).toBeDefined()
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
[line4, line5] = displayBuffer.linesForRows(4, 5)
expect(line4.fold).toBe fold
expect(line4.text).toMatch /^4-+/
expect(line5.text).toBe '8'
@@ -251,7 +229,7 @@ describe "DisplayBuffer", ->
changeHandler.reset()
fold.destroy()
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
[line4, line5] = displayBuffer.linesForRows(4, 5)
expect(line4.fold).toBeUndefined()
expect(line4.text).toMatch /^4-+/
expect(line5.text).toBe '5'
@@ -262,7 +240,7 @@ describe "DisplayBuffer", ->
it "renders a fold placeholder for the folded line but does not skip any lines", ->
fold = displayBuffer.createFold(4, 4)
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
[line4, line5] = displayBuffer.linesForRows(4, 5)
expect(line4.fold).toBe fold
expect(line4.text).toMatch /^4-+/
expect(line5.text).toBe '5'
@@ -275,7 +253,7 @@ describe "DisplayBuffer", ->
fold.destroy()
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
[line4, line5] = displayBuffer.linesForRows(4, 5)
expect(line4.fold).toBeUndefined()
expect(line4.text).toMatch /^4-+/
expect(line5.text).toBe '5'
@@ -287,13 +265,13 @@ describe "DisplayBuffer", ->
innerFold = displayBuffer.createFold(6, 7)
outerFold = displayBuffer.createFold(4, 8)
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
[line4, line5] = displayBuffer.linesForRows(4, 5)
expect(line4.fold).toBe outerFold
expect(line4.text).toMatch /4-+/
expect(line5.text).toMatch /9-+/
outerFold.destroy()
[line4, line5, line6, line7] = displayBuffer.tokenizedLinesForScreenRows(4, 7)
[line4, line5, line6, line7] = displayBuffer.linesForRows(4, 7)
expect(line4.fold).toBeUndefined()
expect(line4.text).toMatch /^4-+/
expect(line5.text).toBe '5'
@@ -305,7 +283,7 @@ describe "DisplayBuffer", ->
innerFold = displayBuffer.createFold(4, 6)
outerFold = displayBuffer.createFold(4, 8)
[line4, line5] = displayBuffer.tokenizedLinesForScreenRows(4, 5)
[line4, line5] = displayBuffer.linesForRows(4, 5)
expect(line4.fold).toBe outerFold
expect(line4.text).toMatch /4-+/
expect(line5.text).toMatch /9-+/
@@ -326,25 +304,17 @@ describe "DisplayBuffer", ->
innerFold = displayBuffer.createFold(2, 5)
expect(changeHandler).not.toHaveBeenCalled()
[line0, line1] = displayBuffer.tokenizedLinesForScreenRows(0, 1)
[line0, line1] = displayBuffer.linesForRows(0, 1)
expect(line0.fold).toBe outerFold
expect(line1.fold).toBeUndefined()
changeHandler.reset()
innerFold.destroy()
expect(changeHandler).not.toHaveBeenCalled()
[line0, line1] = displayBuffer.tokenizedLinesForScreenRows(0, 1)
[line0, line1] = displayBuffer.linesForRows(0, 1)
expect(line0.fold).toBe outerFold
expect(line1.fold).toBeUndefined()
describe "when a fold ends where another fold begins", ->
it "continues to hide the lines inside the second fold", ->
fold2 = displayBuffer.createFold(4, 9)
fold1 = displayBuffer.createFold(0, 4)
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toMatch /^0/
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toMatch /^10/
describe "when there is another display buffer pointing to the same buffer", ->
it "does not create folds in the other display buffer", ->
otherDisplayBuffer = new DisplayBuffer({buffer, tabLength})
@@ -363,19 +333,19 @@ describe "DisplayBuffer", ->
buffer.setTextInRange([[1, 0], [5, 1]], 'party!')
it "removes the fold and replaces the selection with the new text", ->
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "0"
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "party!"
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold2
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch /^9-+/
expect(displayBuffer.lineForRow(0).text).toBe "0"
expect(displayBuffer.lineForRow(1).text).toBe "party!"
expect(displayBuffer.lineForRow(2).fold).toBe fold2
expect(displayBuffer.lineForRow(3).text).toMatch /^9-+/
expect(changeHandler).toHaveBeenCalledWith(start: 1, end: 3, screenDelta: -2, bufferDelta: -4)
describe "when the changes is subsequently undone", ->
xit "restores destroyed folds", ->
buffer.undo()
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe '5'
expect(displayBuffer.lineForRow(2).text).toBe '2'
expect(displayBuffer.lineForRow(2).fold).toBe fold1
expect(displayBuffer.lineForRow(3).text).toBe '5'
describe "when the old range surrounds two nested folds", ->
it "removes both folds and replaces the selection with the new text", ->
@@ -384,9 +354,9 @@ describe "DisplayBuffer", ->
buffer.setTextInRange([[1, 0], [10, 0]], 'goodbye')
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "0"
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "goodbye10"
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "11"
expect(displayBuffer.lineForRow(0).text).toBe "0"
expect(displayBuffer.lineForRow(1).text).toBe "goodbye10"
expect(displayBuffer.lineForRow(2).text).toBe "11"
expect(changeHandler).toHaveBeenCalledWith(start: 1, end: 3, screenDelta: -2, bufferDelta: -9)
@@ -403,42 +373,42 @@ describe "DisplayBuffer", ->
it "updates the buffer and re-positions subsequent folds", ->
buffer.setTextInRange([[0, 0], [1, 1]], 'abc')
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "abc"
expect(displayBuffer.tokenizedLineForScreenRow(1).fold).toBe fold1
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "5"
expect(displayBuffer.tokenizedLineForScreenRow(3).fold).toBe fold2
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toMatch /^9-+/
expect(displayBuffer.lineForRow(0).text).toBe "abc"
expect(displayBuffer.lineForRow(1).fold).toBe fold1
expect(displayBuffer.lineForRow(2).text).toBe "5"
expect(displayBuffer.lineForRow(3).fold).toBe fold2
expect(displayBuffer.lineForRow(4).text).toMatch /^9-+/
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 1, screenDelta: -1, bufferDelta: -1)
changeHandler.reset()
fold1.destroy()
expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe "abc"
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "2"
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch /^4-+/
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe "5"
expect(displayBuffer.tokenizedLineForScreenRow(5).fold).toBe fold2
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toMatch /^9-+/
expect(displayBuffer.lineForRow(0).text).toBe "abc"
expect(displayBuffer.lineForRow(1).text).toBe "2"
expect(displayBuffer.lineForRow(3).text).toMatch /^4-+/
expect(displayBuffer.lineForRow(4).text).toBe "5"
expect(displayBuffer.lineForRow(5).fold).toBe fold2
expect(displayBuffer.lineForRow(6).text).toMatch /^9-+/
expect(changeHandler).toHaveBeenCalledWith(start: 1, end: 1, screenDelta: 2, bufferDelta: 0)
describe "when the old range straddles the beginning of a fold", ->
it "destroys the fold", ->
buffer.setTextInRange([[1, 1], [3, 0]], "a\nb\nc\nd\n")
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe '1a'
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe 'b'
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBeUndefined()
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe 'c'
expect(displayBuffer.lineForRow(1).text).toBe '1a'
expect(displayBuffer.lineForRow(2).text).toBe 'b'
expect(displayBuffer.lineForRow(2).fold).toBeUndefined()
expect(displayBuffer.lineForRow(3).text).toBe 'c'
describe "when the old range follows a fold", ->
it "re-positions the screen ranges for the change event based on the preceding fold", ->
buffer.setTextInRange([[10, 0], [11, 0]], 'abc')
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe "5"
expect(displayBuffer.tokenizedLineForScreenRow(4).fold).toBe fold2
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toMatch /^9-+/
expect(displayBuffer.lineForRow(1).text).toBe "1"
expect(displayBuffer.lineForRow(2).fold).toBe fold1
expect(displayBuffer.lineForRow(3).text).toBe "5"
expect(displayBuffer.lineForRow(4).fold).toBe fold2
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
expect(changeHandler).toHaveBeenCalledWith(start: 6, end: 7, screenDelta: -1, bufferDelta: -1)
@@ -449,12 +419,12 @@ describe "DisplayBuffer", ->
expect(fold1.getStartRow()).toBe 2
expect(fold1.getEndRow()).toBe 5
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "2"
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch "5"
expect(displayBuffer.tokenizedLineForScreenRow(4).fold).toBe fold2
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toMatch /^9-+/
expect(displayBuffer.lineForRow(1).text).toBe "1"
expect(displayBuffer.lineForRow(2).text).toBe "2"
expect(displayBuffer.lineForRow(2).fold).toBe fold1
expect(displayBuffer.lineForRow(3).text).toMatch "5"
expect(displayBuffer.lineForRow(4).fold).toBe fold2
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
expect(changeHandler).toHaveBeenCalledWith(start: 2, end: 2, screenDelta: 0, bufferDelta: 1)
@@ -464,12 +434,12 @@ describe "DisplayBuffer", ->
expect(fold1.getStartRow()).toBe 2
expect(fold1.getEndRow()).toBe 7
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe "2"
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch "5"
expect(displayBuffer.tokenizedLineForScreenRow(4).fold).toBe fold2
expect(displayBuffer.tokenizedLineForScreenRow(5).text).toMatch /^9-+/
expect(displayBuffer.lineForRow(1).text).toBe "1"
expect(displayBuffer.lineForRow(2).text).toBe "2"
expect(displayBuffer.lineForRow(2).fold).toBe fold1
expect(displayBuffer.lineForRow(3).text).toMatch "5"
expect(displayBuffer.lineForRow(4).fold).toBe fold2
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
expect(changeHandler).toHaveBeenCalledWith(start: 2, end: 2, screenDelta: 0, bufferDelta: 3)
@@ -478,21 +448,21 @@ describe "DisplayBuffer", ->
it "destroys the fold", ->
fold2.destroy()
buffer.setTextInRange([[3, 0], [6, 0]], 'a\n')
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBeUndefined()
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe 'a'
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe '6'
expect(displayBuffer.lineForRow(2).text).toBe '2'
expect(displayBuffer.lineForRow(2).fold).toBeUndefined()
expect(displayBuffer.lineForRow(3).text).toBe 'a'
expect(displayBuffer.lineForRow(4).text).toBe '6'
describe "when the old range is contained to a single line in-between two folds", ->
it "re-renders the line with the placeholder and re-positions the second fold", ->
buffer.insert([5, 0], 'abc\n')
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe "1"
expect(displayBuffer.tokenizedLineForScreenRow(2).fold).toBe fold1
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toMatch "abc"
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe "5"
expect(displayBuffer.tokenizedLineForScreenRow(5).fold).toBe fold2
expect(displayBuffer.tokenizedLineForScreenRow(6).text).toMatch /^9-+/
expect(displayBuffer.lineForRow(1).text).toBe "1"
expect(displayBuffer.lineForRow(2).fold).toBe fold1
expect(displayBuffer.lineForRow(3).text).toMatch "abc"
expect(displayBuffer.lineForRow(4).text).toBe "5"
expect(displayBuffer.lineForRow(5).fold).toBe fold2
expect(displayBuffer.lineForRow(6).text).toMatch /^9-+/
expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 3, screenDelta: 1, bufferDelta: 1)
@@ -545,15 +515,15 @@ describe "DisplayBuffer", ->
displayBuffer.createFold(1, 9)
displayBuffer.createFold(11, 12)
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe '1'
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '10'
expect(displayBuffer.lineForRow(1).text).toBe '1'
expect(displayBuffer.lineForRow(2).text).toBe '10'
displayBuffer.unfoldBufferRow(2)
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe '1'
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
expect(displayBuffer.tokenizedLineForScreenRow(7).fold).toBeDefined()
expect(displayBuffer.tokenizedLineForScreenRow(8).text).toMatch /^9-+/
expect(displayBuffer.tokenizedLineForScreenRow(10).fold).toBeDefined()
expect(displayBuffer.lineForRow(1).text).toBe '1'
expect(displayBuffer.lineForRow(2).text).toBe '2'
expect(displayBuffer.lineForRow(7).fold).toBeDefined()
expect(displayBuffer.lineForRow(8).text).toMatch /^9-+/
expect(displayBuffer.lineForRow(10).fold).toBeDefined()
describe ".outermostFoldsInBufferRowRange(startRow, endRow)", ->
it "returns the outermost folds entirely contained in the given row range, exclusive of end row", ->
@@ -568,7 +538,7 @@ describe "DisplayBuffer", ->
describe "::clipScreenPosition(screenPosition, wrapBeyondNewlines: false, wrapAtSoftNewlines: false, skipAtomicTokens: false)", ->
beforeEach ->
displayBuffer.setSoftWrapped(true)
displayBuffer.setSoftWrap(true)
displayBuffer.setEditorWidthInChars(50)
it "allows valid positions", ->
@@ -643,7 +613,7 @@ describe "DisplayBuffer", ->
it "correctly translates positions on soft wrapped lines containing tabs", ->
buffer.setText('\t\taa bb cc dd ee ff gg')
displayBuffer.setSoftWrapped(true)
displayBuffer.setSoftWrap(true)
displayBuffer.setEditorWidthInChars(10)
expect(displayBuffer.screenPositionForBufferPosition([0, 10], wrapAtSoftNewlines: true)).toEqual [1, 0]
expect(displayBuffer.bufferPositionForScreenPosition([1, 0])).toEqual [0, 10]
@@ -654,19 +624,6 @@ describe "DisplayBuffer", ->
buffer.delete([[6, 0], [6, 65]])
expect(displayBuffer.getMaxLineLength()).toBe 62
it "correctly updates the location of the longest screen line when changes occur", ->
expect(displayBuffer.getLongestScreenRow()).toBe 6
buffer.delete([[0, 0], [2, 0]])
expect(displayBuffer.getLongestScreenRow()).toBe 4
buffer.delete([[4, 0], [5, 0]])
expect(displayBuffer.getLongestScreenRow()).toBe 1
expect(displayBuffer.getMaxLineLength()).toBe 62
buffer.delete([[2, 0], [4, 0]])
expect(displayBuffer.getLongestScreenRow()).toBe 1
expect(displayBuffer.getMaxLineLength()).toBe 62
describe "::destroy()", ->
it "unsubscribes all display buffer markers from their underlying buffer marker (regression)", ->
marker = displayBuffer.markBufferPosition([12, 2])
@@ -686,7 +643,7 @@ describe "DisplayBuffer", ->
expect(marker2.getScreenRange()).toEqual [[5, 4], [5, 10]]
it "emits a 'marker-created' event on the DisplayBuffer whenever a marker is created", ->
displayBuffer.onDidCreateMarker markerCreatedHandler = jasmine.createSpy("markerCreatedHandler")
displayBuffer.on 'marker-created', markerCreatedHandler = jasmine.createSpy("markerCreatedHandler")
marker1 = displayBuffer.markScreenRange([[5, 4], [5, 10]])
expect(markerCreatedHandler).toHaveBeenCalledWith(marker1)
@@ -722,7 +679,7 @@ describe "DisplayBuffer", ->
beforeEach ->
marker = displayBuffer.markScreenRange([[5, 4], [5, 10]])
marker.onDidChange markerChangedHandler = jasmine.createSpy("markerChangedHandler")
marker.on 'changed', markerChangedHandler = jasmine.createSpy("markerChangedHandler")
it "triggers the 'changed' event whenever the markers head's screen position changes in the buffer or on screen", ->
marker.setHeadScreenPosition([8, 20])
@@ -859,8 +816,8 @@ describe "DisplayBuffer", ->
it "updates markers before emitting buffer change events, but does not notify their observers until the change event", ->
marker2 = displayBuffer.markBufferRange([[8, 1], [8, 1]])
marker2.onDidChange marker2ChangedHandler = jasmine.createSpy("marker2ChangedHandler")
displayBuffer.onDidChange changeHandler = jasmine.createSpy("changeHandler").andCallFake -> onDisplayBufferChange()
marker2.on 'changed', marker2ChangedHandler = jasmine.createSpy("marker2ChangedHandler")
displayBuffer.on 'changed', changeHandler = jasmine.createSpy("changeHandler").andCallFake -> onDisplayBufferChange()
# New change ----
@@ -886,7 +843,7 @@ describe "DisplayBuffer", ->
marker2ChangedHandler.reset()
marker3 = displayBuffer.markBufferRange([[8, 1], [8, 2]])
marker3.onDidChange marker3ChangedHandler = jasmine.createSpy("marker3ChangedHandler")
marker3.on 'changed', marker3ChangedHandler = jasmine.createSpy("marker3ChangedHandler")
onDisplayBufferChange = ->
# calls change handler first
@@ -932,7 +889,7 @@ describe "DisplayBuffer", ->
expect(marker3ChangedHandler).toHaveBeenCalled()
it "updates the position of markers before emitting change events that aren't caused by a buffer change", ->
displayBuffer.onDidChange changeHandler = jasmine.createSpy("changeHandler").andCallFake ->
displayBuffer.on 'changed', changeHandler = jasmine.createSpy("changeHandler").andCallFake ->
# calls change handler first
expect(markerChangedHandler).not.toHaveBeenCalled()
# but still updates the markers
@@ -998,20 +955,20 @@ describe "DisplayBuffer", ->
expect(marker.isValid()).toBeFalsy()
expect(displayBuffer.getMarker(marker.id)).toBeUndefined()
it "notifies ::onDidDestroy observers when markers are destroyed", ->
it "emits 'destroyed' events when markers are destroyed", ->
destroyedHandler = jasmine.createSpy("destroyedHandler")
marker = displayBuffer.markScreenRange([[5, 4], [5, 10]])
marker.onDidDestroy destroyedHandler
marker.on 'destroyed', destroyedHandler
marker.destroy()
expect(destroyedHandler).toHaveBeenCalled()
destroyedHandler.reset()
marker2 = displayBuffer.markScreenRange([[5, 4], [5, 10]])
marker2.onDidDestroy destroyedHandler
marker2.on 'destroyed', destroyedHandler
buffer.getMarker(marker2.id).destroy()
expect(destroyedHandler).toHaveBeenCalled()
describe "Marker::copy(attributes)", ->
describe "DisplayBufferMarker::copy(attributes)", ->
it "creates a copy of the marker with the given attributes merged in", ->
initialMarkerCount = displayBuffer.getMarkerCount()
marker1 = displayBuffer.markScreenRange([[5, 4], [5, 10]], a: 1, b: 2)
@@ -1020,65 +977,31 @@ describe "DisplayBuffer", ->
marker2 = marker1.copy(b: 3)
expect(marker2.getBufferRange()).toEqual marker1.getBufferRange()
expect(displayBuffer.getMarkerCount()).toBe initialMarkerCount + 2
expect(marker1.getProperties()).toEqual a: 1, b: 2
expect(marker2.getProperties()).toEqual a: 1, b: 3
expect(marker1.getAttributes()).toEqual a: 1, b: 2
expect(marker2.getAttributes()).toEqual a: 1, b: 3
describe "Marker::getPixelRange()", ->
describe "DisplayBufferMarker::getPixelRange()", ->
it "returns the start and end positions of the marker based on the line height and character widths assigned to the DisplayBuffer", ->
marker = displayBuffer.markScreenRange([[5, 10], [6, 4]])
displayBuffer.setLineHeightInPixels(20)
displayBuffer.setDefaultCharWidth(10)
for char in ['r', 'e', 't', 'u', 'r', 'n']
displayBuffer.setScopedCharWidth(["source.js", "keyword.control.js"], char, 11)
displayBuffer.setScopedCharWidths(["source.js", "keyword.control.js"], r: 11, e: 11, t: 11, u: 11, n: 11)
{start, end} = marker.getPixelRange()
expect(start.top).toBe 5 * 20
expect(start.left).toBe (4 * 10) + (6 * 11)
describe 'when there are multiple DisplayBuffers for a buffer', ->
describe 'when a marker is created', ->
it 'the second display buffer will not emit a marker-created event when the marker has been deleted in the first marker-created event', ->
displayBuffer2 = new DisplayBuffer({buffer, tabLength})
displayBuffer.onDidCreateMarker markerCreated1 = jasmine.createSpy().andCallFake (marker) -> marker.destroy()
displayBuffer2.onDidCreateMarker markerCreated2 = jasmine.createSpy()
displayBuffer.markBufferRange([[0, 0], [1, 5]], {})
expect(markerCreated1).toHaveBeenCalled()
expect(markerCreated2).not.toHaveBeenCalled()
describe "decorations", ->
[marker, decoration, decorationProperties] = []
beforeEach ->
marker = displayBuffer.markBufferRange([[2, 13], [3, 15]])
decorationProperties = {type: 'gutter', class: 'one'}
decoration = displayBuffer.decorateMarker(marker, decorationProperties)
it "can add decorations associated with markers and remove them", ->
expect(decoration).toBeDefined()
expect(decoration.getProperties()).toBe decorationProperties
expect(displayBuffer.decorationForId(decoration.id)).toBe decoration
decoration = {type: 'gutter', class: 'one'}
marker = displayBuffer.markBufferRange([[2, 13], [3, 15]])
displayBuffer.addDecorationForMarker(marker, decoration)
expect(displayBuffer.decorationsForScreenRowRange(2, 3)[marker.id][0]).toBe decoration
decoration.destroy()
displayBuffer.removeDecorationForMarker(marker, decoration)
expect(displayBuffer.decorationsForScreenRowRange(2, 3)[marker.id]).not.toBeDefined()
expect(displayBuffer.decorationForId(decoration.id)).not.toBeDefined()
it "will not fail if the decoration is removed twice", ->
decoration.destroy()
decoration.destroy()
expect(displayBuffer.decorationForId(decoration.id)).not.toBeDefined()
describe "when a decoration is updated via Decoration::update()", ->
it "emits an 'updated' event containing the new and old params", ->
decoration.onDidChangeProperties updatedSpy = jasmine.createSpy()
decoration.setProperties type: 'gutter', class: 'two'
{oldProperties, newProperties} = updatedSpy.mostRecentCall.args[0]
expect(oldProperties).toEqual decorationProperties
expect(newProperties).toEqual type: 'gutter', class: 'two', id: decoration.id
describe "::setScrollTop", ->
beforeEach ->
@@ -1100,33 +1023,6 @@ describe "DisplayBuffer", ->
expect(displayBuffer.setScrollTop(maxScrollTop + 50)).toBe maxScrollTop
expect(displayBuffer.getScrollTop()).toBe maxScrollTop
describe "editor.scrollPastEnd", ->
describe "when editor.scrollPastEnd is false", ->
beforeEach ->
atom.config.set("editor.scrollPastEnd", false)
displayBuffer.manageScrollPosition = true
displayBuffer.setLineHeightInPixels(10)
it "does not add the height of the view to the scroll height", ->
lineHeight = displayBuffer.getLineHeightInPixels()
originalScrollHeight = displayBuffer.getScrollHeight()
displayBuffer.setHeight(50)
expect(displayBuffer.getScrollHeight()).toBe originalScrollHeight
describe "when editor.scrollPastEnd is true", ->
beforeEach ->
atom.config.set("editor.scrollPastEnd", true)
displayBuffer.manageScrollPosition = true
displayBuffer.setLineHeightInPixels(10)
it "adds the height of the view to the scroll height", ->
lineHeight = displayBuffer.getLineHeightInPixels()
originalScrollHeight = displayBuffer.getScrollHeight()
displayBuffer.setHeight(50)
expect(displayBuffer.getScrollHeight()).toEqual(originalScrollHeight + displayBuffer.height - (lineHeight * 3))
describe "::setScrollLeft", ->
beforeEach ->
displayBuffer.manageScrollPosition = true
@@ -1171,38 +1067,3 @@ describe "DisplayBuffer", ->
it "does not scroll vertically if the position is already in view", ->
displayBuffer.scrollToScreenPosition([4, 20], center: true)
expect(displayBuffer.getScrollTop()).toBe 0
describe "scroll width", ->
cursorWidth = 1
beforeEach ->
displayBuffer.setDefaultCharWidth(10)
it "recomputes the scroll width when the default character width changes", ->
expect(displayBuffer.getScrollWidth()).toBe 10 * 65 + cursorWidth
displayBuffer.setDefaultCharWidth(12)
expect(displayBuffer.getScrollWidth()).toBe 12 * 65 + cursorWidth
it "recomputes the scroll width when the max line length changes", ->
buffer.insert([6, 12], ' ')
expect(displayBuffer.getScrollWidth()).toBe 10 * 66 + cursorWidth
buffer.delete([[6, 10], [6, 12]], ' ')
expect(displayBuffer.getScrollWidth()).toBe 10 * 64 + cursorWidth
it "recomputes the scroll width when the scoped character widths change", ->
operatorWidth = 20
displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '<', operatorWidth)
expect(displayBuffer.getScrollWidth()).toBe 10 * 64 + operatorWidth + cursorWidth
it "recomputes the scroll width when the scoped character widths change in a batch", ->
operatorWidth = 20
displayBuffer.onDidChangeCharacterWidths changedSpy = jasmine.createSpy()
displayBuffer.batchCharacterMeasurement ->
displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '<', operatorWidth)
displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '?', operatorWidth)
expect(displayBuffer.getScrollWidth()).toBe 10 * 63 + operatorWidth * 2 + cursorWidth
expect(changedSpy.callCount).toBe 1
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 392 B

+1
Ver Arquivo
@@ -0,0 +1 @@
this tests files with no extensions
@@ -1,4 +0,0 @@
module.exports =
activate: ->
deactivate: -> throw new Error('Top that')
serialize: ->
@@ -1,13 +0,0 @@
module.exports =
activateCallCount: 0
activationCommandCallCount: 0
legacyActivationCommandCallCount: 0
activate: ->
@activateCallCount++
atom.commands.add '.workspace', 'activation-command', =>
@activationCommandCallCount++
atom.workspaceView.getActiveView()?.command 'activation-command', =>
@legacyActivationCommandCallCount++
@@ -1,2 +0,0 @@
'activationCommands':
'.workspace': 'activation-command'
@@ -0,0 +1,13 @@
class Foo
atom.deserializers.add(this)
@deserialize: ({data}) -> new Foo(data)
constructor: (@data) ->
module.exports =
activateCallCount: 0
activationEventCallCount: 0
activate: ->
@activateCallCount++
atom.workspaceView.getActiveView()?.command 'activation-event', =>
@activationEventCallCount++
@@ -0,0 +1 @@
'activationEvents': ['activation-event']
@@ -1,13 +0,0 @@
module.exports =
config:
numbers:
type: 'object'
properties:
one:
type: 'integer'
default: 1
two:
type: 'integer'
default: 2
activate: -> # no-op
@@ -1,5 +1,5 @@
{
"name": "no events",
"version": "0.1.0",
"activationCommands": {".workspace": []}
"activationEvents": []
}
@@ -1 +0,0 @@
throw new Error("this simulates a native module's failure to load")
@@ -1,4 +0,0 @@
{
"name": "native-module",
"main": "./main.js"
}
@@ -1,5 +0,0 @@
{
"name": "package-with-incompatible-native-module",
"version": "1.0",
"main": "./main.js"
}
@@ -0,0 +1,18 @@
'fileTypes': ['package-with-infinite-loop-grammar']
'name': 'package-with-infinite-loop-grammar'
'scopeName': 'source.package-with-infinite-loop-grammar'
# This grammar should loop forever if the line contains an `a`
'patterns': [
{
'name': 'start'
'begin': '^'
'end': '$'
'patterns': [
{
name: 'negative-look-ahead'
match: "(?!a)"
}
]
}
]
+3 -4
Ver Arquivo
@@ -1,8 +1,7 @@
'menu': [
{'label': 'Second to Last'}
{ 'label': 'Second to Last' }
]
'context-menu':
'.test-1': [
{label: 'Menu item 1', command: 'command-1'}
]
'.test-1':
'Menu item 1': 'command-1'
+2 -3
Ver Arquivo
@@ -3,6 +3,5 @@
]
'context-menu':
'.test-1': [
{label: 'Menu item 2', command: 'command-2'}
]
'.test-1':
'Menu item 2': 'command-2'
+2 -3
Ver Arquivo
@@ -3,6 +3,5 @@
]
'context-menu':
'.test-1': [
{label: 'Menu item 3', command: 'command-3'}
]
'.test-1':
'Menu item 3': 'command-3'
@@ -0,0 +1 @@
This is a hidden file. Don't even try to load it as a snippet
@@ -0,0 +1 @@
This file isn't CSON, but shouldn't be a big deal
@@ -0,0 +1,4 @@
".test":
"Test Snippet":
prefix: "test"
body: "testing 123"
@@ -1,4 +0,0 @@
{
"theme": "ui",
"stylesheets": ["editor.less"]
}
@@ -1,10 +0,0 @@
@import "ui-variables";
.editor {
padding-top: @component-padding;
padding-right: @component-padding;
padding-bottom: @component-padding;
color: @input-background-color;
background-color: @background-color-info; // From the fallback variables, not overridden
}
@@ -1,3 +0,0 @@
// This does not contain all of the ui-variables available.
@app-background-color: #00f; // Changed
@input-background-color: #f00; // Changed

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais