From 45b12dfb7c06d63af666cc801a01264223fa5f4b Mon Sep 17 00:00:00 2001 From: jubianchi Date: Tue, 19 Jan 2016 01:21:13 +0100 Subject: [PATCH] Refactor view Should additionaly fix #4 --- lib/decorator.coffee | 4 +- lib/runner.coffee | 37 ++++++++++------- lib/views/panel.coffee | 5 ++- lib/views/report-treeview-branch.coffee | 31 +++++++++++++++ lib/views/report-treeview-leaf.coffee | 15 +++++++ lib/views/report-treeview.coffee | 49 +++++++++++++++++++++++ lib/views/report.coffee | 5 ++- lib/views/result-button.coffee | 27 +++++++++++++ lib/views/result.coffee | 43 ++++++++++++++++++++ lib/views/toolbar.coffee | 53 +++++++++---------------- spec/views/toolbar-spec.coffee | 17 -------- styles/atoum-plugin.less | 6 +++ 12 files changed, 221 insertions(+), 71 deletions(-) create mode 100644 lib/views/report-treeview-branch.coffee create mode 100644 lib/views/report-treeview-leaf.coffee create mode 100644 lib/views/report-treeview.coffee create mode 100644 lib/views/result-button.coffee create mode 100644 lib/views/result.coffee diff --git a/lib/decorator.coffee b/lib/decorator.coffee index bb5e9ac..9412483 100644 --- a/lib/decorator.coffee +++ b/lib/decorator.coffee @@ -40,7 +40,7 @@ class AtoumDecorator @decorateCoverage editor, file decorateCoverage: (editor, file) -> - return unless @markers['coverage'][file] + return unless @markers['coverage'] and @markers['coverage'][file] gutter = editor.gutterWithName 'atoum-coverage' @@ -65,7 +65,7 @@ class AtoumDecorator @markers['coverage'][file].lines.splice index, 1 unless event.isValid decorateTest: (editor, file) -> - return unless @markers['test'][file] + return unless @markers['test'] and @markers['test'][file] gutter = editor.gutterWithName 'atoum-test' diff --git a/lib/runner.coffee b/lib/runner.coffee index ca46d28..4f57edc 100644 --- a/lib/runner.coffee +++ b/lib/runner.coffee @@ -42,12 +42,19 @@ class AtoumRunner extends Emitter start: -> out = (data) => @emit 'output', data + @emit 'start' + + unless @target + @emit 'error', 'Nothing to run. Please select a file or directory to run.\n' + @didExit 255 + + return false + if fs.statSync(@target).isDirectory() cwd = @target else cwd = path.dirname @target - @emit 'start' args = @configurator.getArguments @target if not args @@ -64,19 +71,21 @@ class AtoumRunner extends Emitter stdout: out stderr: (data) => @emit 'error', data exit: (code) => - returun unless code is 0 - - out @config.phpPath + ' \'' + args.join('\' \'') + '\'\n' - out 'in ' + cwd - - @process = new BufferedProcess - command: @config.phpPath - args: args - options: - cwd: cwd - stdout: out - stderr: (data) => @emit 'error', data - exit: (code) => @didExit code + unless code is 0 + @didExit code + + if code is 0 + out @config.phpPath + ' \'' + args.join('\' \'') + '\'\n' + out 'in ' + cwd + + @process = new BufferedProcess + command: @config.phpPath + args: args + options: + cwd: cwd + stdout: out + stderr: (data) => @emit 'error', data + exit: (code) => @didExit code true diff --git a/lib/views/panel.coffee b/lib/views/panel.coffee index 31a8ba9..18fa29a 100644 --- a/lib/views/panel.coffee +++ b/lib/views/panel.coffee @@ -4,7 +4,7 @@ process = require 'child_process' { View } = require 'atom-space-pen-views' AtoumToolbarView = require './toolbar' AtoumProgressView = require './progress' -AtoumRunner = require '../runner' +AtoumResultView = require './result' module.exports = class AtoumPanelView extends View @@ -17,7 +17,8 @@ class AtoumPanelView extends View @subview 'progress', new AtoumProgressView @section class: 'panel-body padded', => - @subview 'toolbar', new AtoumToolbarView @model, @runner + @subview 'toolbar', new AtoumToolbarView @runner, + result: new AtoumResultView @model initialize: (@model, @runner) -> diff --git a/lib/views/report-treeview-branch.coffee b/lib/views/report-treeview-branch.coffee new file mode 100644 index 0000000..e156604 --- /dev/null +++ b/lib/views/report-treeview-branch.coffee @@ -0,0 +1,31 @@ +{ CompositeDisposable } = require 'atom' +{ View, $ } = require 'atom-space-pen-views' +AtoumReportTreeviewLeafView = require './report-treeview-leaf' + +module.exports = +class AtoumReportTreeviewBranchView extends View + @icons: + 'ok': 'icon-check text-success' + 'skip': 'icon-arrow-right text-warning' + 'void': 'icon-primitive-dot text-info' + 'not ok': 'icon-flame text-danger' + + @content: (@test) -> + @li 'data-class': @test.class.replace(/\\/g, '/'), class: 'entry list-nested-item collapsed', => + @div outlet: 'header', class: 'header list-item', click: 'toggle', => + @i outlet: 'icon', class: 'icon ' + @icons[@test.status] + @span class: 'name', @test.class + @ol outlet: 'leafs', class: 'entries list-tree' + + toggle: -> + @header.toggleClass('collapsed').toggleClass('expanded') + + testDidFinish: (test) -> + if test.status isnt 'ok' and not @icon.hasClass(icons['not ok']) + @icon + .removeClass(icons['ok']) + .removeClass(icons['skip']) + .removeClass(icons['void']) + .addClass(icons[test.status]) + + @leafs.append new AtoumReportTreeviewLeafView test diff --git a/lib/views/report-treeview-leaf.coffee b/lib/views/report-treeview-leaf.coffee new file mode 100644 index 0000000..6721d3f --- /dev/null +++ b/lib/views/report-treeview-leaf.coffee @@ -0,0 +1,15 @@ +{ CompositeDisposable } = require 'atom' +{ View, $ } = require 'atom-space-pen-views' + +module.exports = +class AtoumReportTreeviewBranchView extends View + @icons: + 'ok': 'icon-check text-success' + 'skip': 'icon-arrow-right text-warning' + 'void': 'icon-primitive-dot text-info' + 'not ok': 'icon-flame text-danger' + + @content: (@test) -> + @li class: 'entry list-item', => + @i outlet: 'icon', class: 'icon ' + @icons[@test.status] + @span class: 'name', @test.method diff --git a/lib/views/report-treeview.coffee b/lib/views/report-treeview.coffee new file mode 100644 index 0000000..773b577 --- /dev/null +++ b/lib/views/report-treeview.coffee @@ -0,0 +1,49 @@ +{ CompositeDisposable } = require 'atom' +{ View, $ } = require 'atom-space-pen-views' +AtoumReportTreeviewBranchView = require './report-treeview-branch' + +module.exports = +class AtoumReportTreeviewView extends View + @content: -> + @ol outlet: 'treeView', class: 'tree-view list-tree has-collapsable-children focusable-panel' + + runnerDidStart: -> + @reset() + + testDidFinish: (test) -> + icons = + 'ok': 'icon-check text-success' + 'skip': 'icon-arrow-right text-warning' + 'void': 'icon-primitive-dot text-info' + 'not ok': 'icon-flame text-danger' + colors = + true: 'text-info' + classId = test.class.replace(/\\/g, '/') + + if @treeView.find('[data-class="' + classId + '"]').size() is 0 + @treeView.append new AtoumReportTreeviewBranchView test + + @treeView.find('[data-class="' + classId + '"]').get(0).view().testDidFinish test + + if test.status isnt 'ok' + @treeView.find('[data-class="' + classId + '"] .entries .entry:last').on 'click', (event, elem) => + @treeView.find('.selected').removeClass 'selected' + $(event.delegateTarget).addClass 'selected' + @treeView.siblings('div').find('.background-message').hide() + @treeView.siblings('div').find('pre').html test.diag + + if test.file and not test.line + @treeView.siblings('div').find('a').html test.file + @treeView.siblings('div').find('a').on 'click', -> + atom.workspace.open test.file, searchAllPanes: true + + if test.file and test.line + @treeView.siblings('div').find('a').html test.file + ':' + test.line + @treeView.siblings('div').find('a').on 'click', -> + atom.workspace.open test.file, initialLine: test.line - 1, searchAllPanes: true + + reset: -> + @treeView.html '' + @treeView.siblings('div').find('pre').html '' + @treeView.siblings('div').find('.background-message').css 'display', '' + @treeView.siblings('div').find('a').html '' diff --git a/lib/views/report.coffee b/lib/views/report.coffee index 0699559..54ee1a6 100644 --- a/lib/views/report.coffee +++ b/lib/views/report.coffee @@ -1,11 +1,12 @@ { CompositeDisposable } = require 'atom' { View, $ } = require 'atom-space-pen-views' +AtoumReportTreeviewView = require './report-treeview' module.exports = class AtoumReportView extends View @content: -> - @div outlet: 'report', class: 'report', => - @ol outlet: 'treeView', class: 'tree-view list-tree has-collapsable-children focusable-panel' + @div class: 'report', => + @subview 'treeView', new AtoumReportTreeviewView @div => @ul class: 'background-message centered', => diff --git a/lib/views/result-button.coffee b/lib/views/result-button.coffee new file mode 100644 index 0000000..618293d --- /dev/null +++ b/lib/views/result-button.coffee @@ -0,0 +1,27 @@ +{ View } = require 'atom-space-pen-views' +AtoumConsoleView = require './console' +AtoumReportView = require './report' + +module.exports = +class AtoumResultButtonView extends View + @content: (@model) -> + @a click: 'toggleView', => + @i outlet: 'viewButton', class: 'icon icon-list-unordered' + + initialize: (@model) -> + @displayView() + + toggleView: -> + if @model.view is 'report' + @model.view = 'console' + else + @model.view = 'report' + + @displayView() + + displayView: -> + if @model.view is 'console' + @viewButton.addClass('icon-list-unordered').removeClass('icon-terminal') + + if @model.view is 'report' or not @model.view + @viewButton.addClass('icon-terminal').removeClass('icon-list-unordered') diff --git a/lib/views/result.coffee b/lib/views/result.coffee new file mode 100644 index 0000000..adaf163 --- /dev/null +++ b/lib/views/result.coffee @@ -0,0 +1,43 @@ +{ View } = require 'atom-space-pen-views' +AtoumConsoleView = require './console' +AtoumReportView = require './report' +AtoumResultButtonView = require './result-button' + +module.exports = +class AtoumResultView extends View + @content: (@model) -> + @div => + @subview 'console', new AtoumConsoleView + @subview 'report', new AtoumReportView + + initialize: (@model) -> + @displayView() + + button: -> + @button = new AtoumResultButtonView @model + @button.on 'click', => @displayView() + + runnerDidStart: -> + @console.runnerDidStart() + @report.runnerDidStart() + + runnerDidProduceOutput: (data) -> + @console.runnerDidProduceOutput data + + runnerDidProduceError: (data) -> + @console.runnerDidProduceError data + + runnerDidStop: -> + @console.runnerDidStop() + + testDidFinish: (test) -> + @report.testDidFinish test + + displayView: -> + if @model.view is 'console' + @console.css('display', '') + @report.hide() + + if @model.view is 'report' or not @model.view + @report.css('display', '') + @console.hide() diff --git a/lib/views/toolbar.coffee b/lib/views/toolbar.coffee index 9afbe37..b06f075 100644 --- a/lib/views/toolbar.coffee +++ b/lib/views/toolbar.coffee @@ -1,22 +1,20 @@ { CompositeDisposable } = require 'atom' { View } = require 'atom-space-pen-views' -AtoumConsoleView = require './console' -AtoumReportView = require './report' module.exports = class AtoumToolbarView extends View - @content: -> + @content: (@runner, @subviews) -> @div => @div class: 'toolbar', => @a click: 'startStop', => @i outlet: 'startStopButton', class: 'icon icon-triangle-right' - @a click: 'toggleView', => - @i outlet: 'viewButton', class: 'icon icon-terminal' - @subview 'console', new AtoumConsoleView - @subview 'report', new AtoumReportView + for name, view of @subviews + @subview name + 'Button', view.button() - initialize: (@model, @runner) -> - @displayView() + for name, view of @subviews + @subview name, view + + initialize: (@runner, @subviews) -> startStop: -> if @running @@ -27,42 +25,29 @@ class AtoumToolbarView extends View runnerDidStart: -> @running = true - @console.runnerDidStart() - @report.runnerDidStart() + for name, view of @subviews + view.runnerDidStart() + @startStopButton.addClass 'icon-circle-slash' @startStopButton.removeClass 'icon-triangle-right' runnerDidProduceOutput: (data) -> - @console.runnerDidProduceOutput data + for name, view of @subviews + view.runnerDidProduceOutput data runnerDidProduceError: (data) -> - @console.runnerDidProduceError data + for name, view of @subviews + view.runnerDidProduceError data runnerDidStop: -> @running = false - @console.runnerDidStop() + for name, view of @subviews + view.runnerDidStop() + @startStopButton.addClass 'icon-triangle-right' @startStopButton.removeClass 'icon-circle-slash' testDidFinish: (test) -> - @report.testDidFinish test - - toggleView: -> - if @model.view is 'console' - @model.view = 'report' - else - @model.view = 'console' - - @displayView() - - displayView: -> - if @model.view is 'console' - @viewButton.addClass('icon-list-unordered').removeClass('icon-terminal') - @console.css('display', '') - @report.hide() - - if @model.view is 'report' or not @model.view - @viewButton.addClass('icon-terminal').removeClass('icon-list-unordered') - @report.css('display', '') - @console.hide() + for name, view of @subviews + view.testDidFinish test diff --git a/spec/views/toolbar-spec.coffee b/spec/views/toolbar-spec.coffee index 1aaa85b..613611e 100644 --- a/spec/views/toolbar-spec.coffee +++ b/spec/views/toolbar-spec.coffee @@ -10,23 +10,6 @@ describe 'AtoumToolbarView', -> it 'has a start/stop button', -> expect(view.startStopButton).not.toBe undefined - it 'has a view switch button', -> - expect(view.viewButton).not.toBe undefined - - describe 'When a model is provided with console view', -> - beforeEach -> - view = new AtoumToolbarView view: 'console' - - it 'has a view switch button to display the report view', -> - expect(view.viewButton.is('.icon.icon-list-unordered')).toBe true - - describe 'When a model is provided with report view', -> - beforeEach -> - view = new AtoumToolbarView view: 'report' - - it 'has a view switch button to display the report view', -> - expect(view.viewButton.is('.icon.icon-terminal')).toBe true - describe 'When a runner is set', -> it 'should subscribe to start event', -> view.runnerDidStart() diff --git a/styles/atoum-plugin.less b/styles/atoum-plugin.less index ed5cb16..b294aa7 100644 --- a/styles/atoum-plugin.less +++ b/styles/atoum-plugin.less @@ -56,6 +56,12 @@ a + a { margin-top: @component-padding / 2; } + + & + div { + display: flex; + flex-direction: row; + flex: 100 1 16px; + } } .console, .report {