diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..3b45561a0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +# Specs depend on character counts, if we don't specify the line endings the +# fixtures will vary depending on platform +spec/fixtures/**/*.js text eol=lf +spec/fixtures/**/*.coffee text eol=lf +spec/fixtures/**/*.less text eol=lf +spec/fixtures/**/*.css text eol=lf +spec/fixtures/**/*.txt text eol=lf +spec/fixtures/dir/**/* text eol=lf diff --git a/docs/building-atom.md b/docs/building-atom.md index 14bdf82d1..46046048b 100644 --- a/docs/building-atom.md +++ b/docs/building-atom.md @@ -17,13 +17,13 @@ atom][download]. * Install the [latest 32bit Node 0.10.x][win-node] * Install the [latest Python 2.7.x][win-python] * Install [Github for Windows][win-github] -* Clone [atom/atom][atom-git] to `C:\Users\\Documents\GitHub\atom\` -* Add `C:\Python27;C:\Program Files\nodejs;C:\Users\\Documents\GitHub\atom\node_modules\` +* Clone [atom/atom][atom-git] to `C:\Users\\github\atom\` +* Add `C:\Python27;C:\Program Files\nodejs;C:\Users\\github\atom\node_modules\` to your PATH * Set ATOM_ACCESS_TOKEN to your oauth2 credentials (run `security -q find-generic-password -ws 'GitHub API Token'` on OSX to get your credentials). -* Use the Windows GitHub shell and cd into `C:\Users\\Documents\GitHub\atom` +* Use the Windows GitHub shell and cd into `C:\Users\\github\atom` * Run `node script/bootstrap` [download]: http://www.atom.io diff --git a/package.json b/package.json index a348a1bf2..15a0b0d06 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "mkdirp": "0.3.5", "less-cache": "0.9.0", "nslog": "0.1.0", - "oniguruma": "0.22.0", + "oniguruma": "0.23.0", "optimist": "0.4.0", "pathwatcher": "0.9.0", "pegjs": "0.7.0", @@ -58,6 +58,7 @@ "json-front-matter": "~0.1.3", "grunt-shell": "~0.3.1", "jasmine-node": "git://github.com/kevinsawicki/jasmine-node.git#short-stacks", + "jasmine-tagged": "0.2.0", "request": "~2.27.0", "unzip": "~0.1.9", "rcedit": "~0.1.1" @@ -114,7 +115,7 @@ "language-coffee-script": "0.3.0", "language-css": "0.2.0", "language-gfm": "0.8.0", - "language-git": "0.2.0", + "language-git": "0.3.0", "language-go": "0.2.0", "language-html": "0.2.0", "language-hyperlink": "0.3.0", diff --git a/spec/atom-spec.coffee b/spec/atom-spec.coffee index 981036868..eaa958965 100644 --- a/spec/atom-spec.coffee +++ b/spec/atom-spec.coffee @@ -200,6 +200,11 @@ describe "the `atom` global", -> 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() @@ -216,6 +221,12 @@ describe "the `atom` global", -> 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() diff --git a/spec/command-installer-spec.coffee b/spec/command-installer-spec.coffee index 0e1ef7789..c6b8ee321 100644 --- a/spec/command-installer-spec.coffee +++ b/spec/command-installer-spec.coffee @@ -14,22 +14,23 @@ describe "install(commandPath, callback)", -> fs.removeSync(directory) if fs.existsSync(directory) - it "symlinks the command and makes it executable", -> - fs.writeFileSync(commandPath, 'test') - expect(fs.isFileSync(commandPath)).toBeTruthy() - expect(fs.isExecutableSync(commandPath)).toBeFalsy() - expect(fs.isFileSync(destinationPath)).toBeFalsy() + describe "on #darwin", -> + it "symlinks the command and makes it executable", -> + fs.writeFileSync(commandPath, 'test') + expect(fs.isFileSync(commandPath)).toBeTruthy() + expect(fs.isExecutableSync(commandPath)).toBeFalsy() + expect(fs.isFileSync(destinationPath)).toBeFalsy() - installDone = false - installError = null - installer.install commandPath, (error) -> - installDone = true - installError = error + installDone = false + installError = null + installer.install commandPath, (error) -> + installDone = true + installError = error - waitsFor -> installDone + waitsFor -> installDone - runs -> - expect(installError).toBeNull() - expect(fs.isFileSync(destinationPath)).toBeTruthy() - expect(fs.realpathSync(destinationPath)).toBe fs.realpathSync(commandPath) - expect(fs.isExecutableSync(destinationPath)).toBeTruthy() + runs -> + expect(installError).toBeNull() + expect(fs.isFileSync(destinationPath)).toBeTruthy() + expect(fs.realpathSync(destinationPath)).toBe fs.realpathSync(commandPath) + expect(fs.isExecutableSync(destinationPath)).toBeTruthy() diff --git a/spec/directory-spec.coffee b/spec/directory-spec.coffee index 56b40fe05..c611a7b05 100644 --- a/spec/directory-spec.coffee +++ b/spec/directory-spec.coffee @@ -66,32 +66,45 @@ describe "Directory", -> waits 20 runs -> expect(changeHandler.callCount).toBe 0 - it "includes symlink information about entries", -> - entries = directory.getEntries() - for entry in entries - name = entry.getBaseName() - if name is 'symlink-to-dir' or name is 'symlink-to-file' - expect(entry.symlink).toBeTruthy() - else - expect(entry.symlink).toBeFalsy() + describe "on #darwin or #linux", -> + it "includes symlink information about entries", -> + entries = directory.getEntries() + for entry in entries + name = entry.getBaseName() + if name is 'symlink-to-dir' or name is 'symlink-to-file' + expect(entry.symlink).toBeTruthy() + else + expect(entry.symlink).toBeFalsy() describe ".relativize(path)", -> - it "returns a relative path based on the directory's path", -> - absolutePath = directory.getPath() - expect(directory.relativize(absolutePath)).toBe '' - expect(directory.relativize(path.join(absolutePath, "b"))).toBe "b" - expect(directory.relativize(path.join(absolutePath, "b/file.coffee"))).toBe "b/file.coffee" - expect(directory.relativize(path.join(absolutePath, "file.coffee"))).toBe "file.coffee" + describe "on #darwin or #linux", -> + it "returns a relative path based on the directory's path", -> + absolutePath = directory.getPath() + expect(directory.relativize(absolutePath)).toBe '' + expect(directory.relativize(path.join(absolutePath, "b"))).toBe "b" + expect(directory.relativize(path.join(absolutePath, "b/file.coffee"))).toBe "b/file.coffee" + expect(directory.relativize(path.join(absolutePath, "file.coffee"))).toBe "file.coffee" - it "returns a relative path based on the directory's symlinked source path", -> - symlinkPath = path.join(__dirname, 'fixtures', 'symlink-to-dir') - symlinkDirectory = new Directory(symlinkPath) - realFilePath = require.resolve('./fixtures/dir/a') - expect(symlinkDirectory.relativize(symlinkPath)).toBe '' - expect(symlinkDirectory.relativize(realFilePath)).toBe 'a' + it "returns a relative path based on the directory's symlinked source path", -> + symlinkPath = path.join(__dirname, 'fixtures', 'symlink-to-dir') + symlinkDirectory = new Directory(symlinkPath) + realFilePath = require.resolve('./fixtures/dir/a') + expect(symlinkDirectory.relativize(symlinkPath)).toBe '' + expect(symlinkDirectory.relativize(realFilePath)).toBe 'a' - it "returns the full path if the directory's path is not a prefix of the path", -> - expect(directory.relativize('/not/relative')).toBe '/not/relative' + it "returns the full path if the directory's path is not a prefix of the path", -> + expect(directory.relativize('/not/relative')).toBe '/not/relative' + + describe "on #win32", -> + it "returns a relative path based on the directory's path", -> + absolutePath = directory.getPath() + expect(directory.relativize(absolutePath)).toBe '' + expect(directory.relativize(path.join(absolutePath, "b"))).toBe "b" + expect(directory.relativize(path.join(absolutePath, "b/file.coffee"))).toBe "b\\file.coffee" + expect(directory.relativize(path.join(absolutePath, "file.coffee"))).toBe "file.coffee" + + it "returns the full path if the directory's path is not a prefix of the path", -> + expect(directory.relativize('/not/relative')).toBe "\\not\\relative" describe ".contains(path)", -> it "returns true if the path is a child of the directory's path", -> @@ -100,11 +113,12 @@ describe "Directory", -> expect(directory.contains(path.join(absolutePath, "b", "file.coffee"))).toBe true expect(directory.contains(path.join(absolutePath, "file.coffee"))).toBe true - it "returns true if the path is a child of the directory's symlinked source path", -> - symlinkPath = path.join(__dirname, 'fixtures', 'symlink-to-dir') - symlinkDirectory = new Directory(symlinkPath) - realFilePath = require.resolve('./fixtures/dir/a') - expect(symlinkDirectory.contains(realFilePath)).toBe true - it "returns false if the directory's path is not a prefix of the path", -> expect(directory.contains('/not/relative')).toBe false + + describe "on #darwin or #linux", -> + it "returns true if the path is a child of the directory's symlinked source path", -> + symlinkPath = path.join(__dirname, 'fixtures', 'symlink-to-dir') + symlinkDirectory = new Directory(symlinkPath) + realFilePath = require.resolve('./fixtures/dir/a') + expect(symlinkDirectory.contains(realFilePath)).toBe true diff --git a/spec/editor-spec.coffee b/spec/editor-spec.coffee index ce9c64572..170dcce05 100644 --- a/spec/editor-spec.coffee +++ b/spec/editor-spec.coffee @@ -296,20 +296,28 @@ describe "Editor", -> expect(editor.css('font-family')).toBe '' describe "when the font family changes", -> + [fontFamily] = [] + + beforeEach -> + if process.platform is 'darwin' + fontFamily = "PCMyungjo" + else + fontFamily = "Consolas" + it "updates the font family of editors and recalculates dimensions critical to cursor positioning", -> editor.attachToDom(12) lineHeightBefore = editor.lineHeight charWidthBefore = editor.charWidth editor.setCursorScreenPosition [5, 6] - config.set("editor.fontFamily", "PCMyungjo") - expect(editor.css('font-family')).toBe 'PCMyungjo' + config.set("editor.fontFamily", fontFamily) + expect(editor.css('font-family')).toBe fontFamily expect(editor.charWidth).not.toBe charWidthBefore expect(editor.getCursorView().position()).toEqual { top: 5 * editor.lineHeight, left: 6 * editor.charWidth } newEditor = new Editor(editor.activeEditSession.copy()) newEditor.attachToDom() - expect(newEditor.css('font-family')).toBe 'PCMyungjo' + expect(newEditor.css('font-family')).toBe fontFamily describe "font size", -> beforeEach -> @@ -914,11 +922,19 @@ describe "Editor", -> beforeEach -> editor.setFontFamily('sans-serif') - it "correctly positions the cursor", -> - editor.setCursorBufferPosition([3, 30]) - expect(editor.getCursorView().position()).toEqual {top: 3 * editor.lineHeight, left: 178} - editor.setCursorBufferPosition([3, Infinity]) - expect(editor.getCursorView().position()).toEqual {top: 3 * editor.lineHeight, left: 353} + describe "on #darwin or #linux", -> + it "correctly positions the cursor", -> + editor.setCursorBufferPosition([3, 30]) + expect(editor.getCursorView().position()).toEqual {top: 3 * editor.lineHeight, left: 178} + editor.setCursorBufferPosition([3, Infinity]) + expect(editor.getCursorView().position()).toEqual {top: 3 * editor.lineHeight, left: 353} + + describe "on #win32", -> + it "correctly positions the cursor", -> + editor.setCursorBufferPosition([3, 30]) + expect(editor.getCursorView().position()).toEqual {top: 3 * editor.lineHeight, left: 175} + editor.setCursorBufferPosition([3, Infinity]) + expect(editor.getCursorView().position()).toEqual {top: 3 * editor.lineHeight, left: 346} describe "autoscrolling", -> it "only autoscrolls when the last cursor is moved", -> diff --git a/spec/jasmine-helper.coffee b/spec/jasmine-helper.coffee index b7e70b607..3d84e9d46 100644 --- a/spec/jasmine-helper.coffee +++ b/spec/jasmine-helper.coffee @@ -3,6 +3,7 @@ module.exports.runSpecSuite = (specSuite, logErrors=true) -> window[key] = value for key, value of require '../vendor/jasmine' require 'jasmine-focused' + require 'jasmine-tagged' TimeReporter = require './time-reporter' timeReporter = new TimeReporter() @@ -27,6 +28,7 @@ module.exports.runSpecSuite = (specSuite, logErrors=true) -> jasmineEnv = jasmine.getEnv() jasmineEnv.addReporter(reporter) jasmineEnv.addReporter(timeReporter) + jasmineEnv.setIncludedTags([process.platform]) $('body').append $$ -> @div id: 'jasmine-content' diff --git a/spec/keymap-spec.coffee b/spec/keymap-spec.coffee index 015a822d5..2e9616856 100644 --- a/spec/keymap-spec.coffee +++ b/spec/keymap-spec.coffee @@ -1,3 +1,5 @@ +path = require 'path' + Keymap = require '../src/keymap' {$, $$, RootView} = require 'atom' @@ -351,7 +353,7 @@ describe "Keymap", -> describe ".getAllKeyMappings", -> it "returns the all bindings", -> - keymap.bindKeys '~/.atom/packages/dummy/keymaps/a.cson', '.command-mode', 'k': 'c' + keymap.bindKeys path.join('~', '.atom', 'packages', 'dummy', 'keymaps', 'a.cson'), '.command-mode', 'k': 'c' mappings = keymap.getAllKeyMappings() expect(mappings.length).toBe 1 @@ -363,20 +365,20 @@ describe "Keymap", -> describe ".determineSource", -> describe "for a package", -> it "returns ''", -> - expect(keymap.determineSource('~/.atom/packages/dummy/keymaps/a.cson')).toEqual 'dummy' + expect(keymap.determineSource(path.join('~', '.atom', 'packages', 'dummy', 'keymaps', 'a.cson'))).toEqual 'dummy' describe "for a linked package", -> it "returns ''", -> - expect(keymap.determineSource('/Users/john/github/dummy/keymaps/a.cson')).toEqual 'dummy' + expect(keymap.determineSource(path.join('Users', 'john', 'github', 'dummy', 'keymaps', 'a.cson'))).toEqual 'dummy' describe "for a user defined keymap", -> it "returns 'User'", -> - expect(keymap.determineSource('~/.atom/keymaps/a.cson')).toEqual 'User' + expect(keymap.determineSource(path.join('~', '.atom', 'keymaps', 'a.cson'))).toEqual 'User' describe "for a core keymap", -> it "returns 'Core'", -> - expect(keymap.determineSource('/Applications/Atom.app/.../node_modules/dummy/keymaps/a.cson')).toEqual 'Core' + expect(keymap.determineSource(path.join('Applications', 'Atom.app', '..', 'node_modules', 'dummy', 'keymaps', 'a.cson'))).toEqual 'Core' describe "for a linked core keymap", -> it "returns 'Core'", -> - expect(keymap.determineSource('/Users/john/github/atom/keymaps/a.cson')).toEqual 'Core' + expect(keymap.determineSource(path.join('Users', 'john', 'github', 'atom', 'keymaps', 'a.cson'))).toEqual 'Core' diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index fc48ca191..ba00de225 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -406,7 +406,7 @@ describe "Project", -> paths = [] matches = [] waitsForPromise -> - project.scan /aaa/, paths: ['a-dir/'], (result) -> + project.scan /aaa/, paths: ["a-dir#{path.sep}"], (result) -> paths.push(result.filePath) matches = matches.concat(result.matches) diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 36ff7f235..39a086e0d 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -279,6 +279,3 @@ $.fn.textInput = (data) -> event.initTextEvent('textInput', true, true, window, data) event = $.event.fix(event) $(this).trigger(event) - -unless fs.md5ForPath(require.resolve('./fixtures/sample.js')) == "dd38087d0d7e3e4802a6d3f9b9745f2b" - throw new Error("Sample.js is modified") diff --git a/spec/theme-manager-spec.coffee b/spec/theme-manager-spec.coffee index 0c7adfbeb..1f7638e43 100644 --- a/spec/theme-manager-spec.coffee +++ b/spec/theme-manager-spec.coffee @@ -85,7 +85,7 @@ describe "ThemeManager", -> expect($('head style').length).toBe lengthBefore + 1 element = $('head style[id*="css.css"]') - expect(element.attr('id')).toBe cssPath + expect(element.attr('id')).toBe themeManager.stringToId(cssPath) expect(element.text()).toBe fs.readFileSync(cssPath, 'utf8') # doesn't append twice @@ -101,7 +101,7 @@ describe "ThemeManager", -> expect($('head style').length).toBe lengthBefore + 1 element = $('head style[id*="sample.less"]') - expect(element.attr('id')).toBe lessPath + expect(element.attr('id')).toBe themeManager.stringToId(lessPath) expect(element.text()).toBe """ #header { color: #4d926f; @@ -119,9 +119,9 @@ describe "ThemeManager", -> it "supports requiring css and less stylesheets without an explicit extension", -> themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'css') - expect($('head style[id*="css.css"]').attr('id')).toBe project.resolve('css.css') + expect($('head style[id*="css.css"]').attr('id')).toBe themeManager.stringToId(project.resolve('css.css')) themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'sample') - expect($('head style[id*="sample.less"]').attr('id')).toBe project.resolve('sample.less') + expect($('head style[id*="sample.less"]').attr('id')).toBe themeManager.stringToId(project.resolve('sample.less')) $('head style[id*="css.css"]').remove() $('head style[id*="sample.less"]').remove() diff --git a/src/text-mate-grammar.coffee b/src/text-mate-grammar.coffee index bb520af2b..8cedf4c19 100644 --- a/src/text-mate-grammar.coffee +++ b/src/text-mate-grammar.coffee @@ -6,7 +6,7 @@ path = require 'path' {Emitter} = require 'emissary' {ScopeSelector} = require 'first-mate' -pathSplitRegex = new RegExp("[#{path.sep}.]") +pathSplitRegex = new RegExp("[#{_.escapeRegExp(path.sep)}.]") ### Internal ### diff --git a/src/theme-manager.coffee b/src/theme-manager.coffee index ac0192dbc..9993cf5aa 100644 --- a/src/theme-manager.coffee +++ b/src/theme-manager.coffee @@ -159,19 +159,23 @@ class ThemeManager #{e.message} """ + # Internal-only: + stringToId: (string) -> + string.replace(/\\/g, '/') + # Internal-only: removeStylesheet: (stylesheetPath) -> unless fullPath = @resolveStylesheet(stylesheetPath) throw new Error("Could not find a file at path '#{stylesheetPath}'") - @stylesheetElementForId(fullPath).remove() + @stylesheetElementForId(@stringToId(fullPath)).remove() # Internal-only: - applyStylesheet: (id, text, ttype = 'bundled') -> - styleElement = @stylesheetElementForId(id) + applyStylesheet: (path, text, ttype = 'bundled') -> + styleElement = @stylesheetElementForId(@stringToId(path)) if styleElement.length styleElement.text(text) else if $("head style.#{ttype}").length - $("head style.#{ttype}:last").after "" + $("head style.#{ttype}:last").after "" else - $("head").append "" + $("head").append "" diff --git a/src/window.coffee b/src/window.coffee index 6f7ec2d0a..c8254cf76 100644 --- a/src/window.coffee +++ b/src/window.coffee @@ -42,8 +42,9 @@ window.setUpDefaultEvents = -> # This method is only called when opening a real application window window.startEditorWindow = -> - installAtomCommand() - installApmCommand() + if process.platform is 'darwin' + installAtomCommand() + installApmCommand() windowEventHandler = new WindowEventHandler restoreDimensions()