diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ade14b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +npm-debug.log +node_modules diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e5b7652 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2 @@ +## 0.1.0 - First Release +* Allows to jump between a module and its tests diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..8886bd4 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2017 Valentin Mihov + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..426a17d --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# elixir-jump-around package + +A plugin which allows to jump between the module and its tests in a mix project. By default the keybinding for the toggle is with `Alt-G Alt-T` (mnemonic of "Go To Test"). diff --git a/keymaps/elixir-jump-around.json b/keymaps/elixir-jump-around.json new file mode 100644 index 0000000..2ec4417 --- /dev/null +++ b/keymaps/elixir-jump-around.json @@ -0,0 +1,5 @@ +{ + "atom-text-editor[data-grammar='source elixir']": { + "alt-g alt-t": "elixir-jump-around:toggle-test-file" + } +} diff --git a/lib/elixir-jump-around.js b/lib/elixir-jump-around.js new file mode 100644 index 0000000..038ba59 --- /dev/null +++ b/lib/elixir-jump-around.js @@ -0,0 +1,49 @@ +'use babel'; + +import { CompositeDisposable } from 'atom'; +const path = require('path'); + +export default { + + subscriptions: null, + + activate(state) { + // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable + this.subscriptions = new CompositeDisposable(); + + // Register command that toggles this view + this.subscriptions.add(atom.commands.add("atom-text-editor[data-grammar='source elixir']", { + 'elixir-jump-around:toggle-test-file': () => this.toggle_test_file() + })); + }, + + deactivate() { + this.subscriptions.dispose(); + }, + + toggle_test_file() { + currentFilePath = atom.workspace.getActiveTextEditor().getPath(); + if (this.isTestFilePath(currentFilePath)) { + return atom.workspace.open(this.getModulePath(currentFilePath)); + } else { + return atom.workspace.open(this.getTestPath(currentFilePath)); + } + }, + + isTestFilePath(filePath) { + return atom.project.getPaths().find((rootPath) => { + console.log(rootPath); + relativePath = path.relative(rootPath, filePath); + console.log(`${relativePath} is the relative of ${filePath}`) + return relativePath.match(/^test\/.+_test\.exs$/); + }); + }, + + getModulePath(filePath) { + return filePath.replace("test", "lib").replace(/_test\.exs$/, ".ex"); + }, + + getTestPath(filePath) { + return filePath.replace("lib", "test").replace(/\.ex$/, "_test.exs"); + } +}; diff --git a/menus/elixir-jump-around.json b/menus/elixir-jump-around.json new file mode 100644 index 0000000..3b74011 --- /dev/null +++ b/menus/elixir-jump-around.json @@ -0,0 +1,26 @@ +{ + "context-menu": { + "atom-text-editor": [ + { + "label": "Toggle test file and the module definiton", + "command": "elixir-jump-around:toggle-test-file" + } + ] + }, + "menu": [ + { + "label": "Packages", + "submenu": [ + { + "label": "elixir-jump-around", + "submenu": [ + { + "label": "Toggle Test File", + "command": "elixir-jump-around:toggle-test-file" + } + ] + } + ] + } + ] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6cd27c8 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "elixir-jump-around", + "main": "./lib/elixir-jump-around", + "version": "0.1.0", + "description": "Jump between modules and tests in an elixir mix projects", + "keywords": [ + ], + "activationCommands": { + "atom-workspace": "elixir-jump-around:toggle-test-file" + }, + "repository": "https://github.com/valo/elixir-jump-around", + "license": "MIT", + "engines": { + "atom": ">=1.0.0 <2.0.0" + }, + "dependencies": { + } +} diff --git a/spec/elixir-jump-around-spec.js b/spec/elixir-jump-around-spec.js new file mode 100644 index 0000000..78a0141 --- /dev/null +++ b/spec/elixir-jump-around-spec.js @@ -0,0 +1,43 @@ +'use babel'; + +import ElixirJumpAround from '../lib/elixir-jump-around'; + +// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. +// +// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit` +// or `fdescribe`). Remove the `f` to unfocus the block. + +const path = require('path'); +const fs = require('fs'); +const PROJECT_ROOT = fs.mkdtempSync("/tmp/elixir-jump-around-"); + +describe('ElixirJumpAround', () => { + let workspaceElement, activationPromise; + + beforeEach(() => { + atom.project.setPaths([PROJECT_ROOT]) + + workspaceElement = atom.views.getView(atom.workspace); + activationPromise = atom.packages.activatePackage('elixir-jump-around'); + }); + + describe('isTestFilePath', () => { + it('returns if the file is a test or not', () => { + expect(ElixirJumpAround.isTestFilePath(path.join(PROJECT_ROOT, "/lib/foo.ex"))).toBeFalsy(); + expect(ElixirJumpAround.isTestFilePath(path.join(PROJECT_ROOT, "/lib/foo.ex"))).toBeFalsy(); + expect(ElixirJumpAround.isTestFilePath(path.join(PROJECT_ROOT, "/test/foo_test.exs"))).toBeTruthy(); + }); + }); + + describe('getModulePath', () => { + it('returns the correct module path of a test file', () => { + expect(ElixirJumpAround.getModulePath(path.join(PROJECT_ROOT, "/test/foo_test.exs"))).toEqual(path.join(PROJECT_ROOT, "/lib/foo.ex")); + }); + }); + + describe('getTestPath', () => { + it('returns the correct test path of a test file', () => { + expect(ElixirJumpAround.getTestPath(path.join(PROJECT_ROOT, "/lib/foo.ex"))).toEqual(path.join(PROJECT_ROOT, "/test/foo_test.exs")); + }); + }); +});