guard-unity 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'guard/unity/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'guard-unity'
8
+ spec.version = Guard::UnityVersion::VERSION
9
+ spec.authors = ['Thomas Muntaner']
10
+ spec.email = ['thomas.muntaner@gmail.com']
11
+ spec.description = %q{Guard gem for Unity3D Test Tools}
12
+ spec.summary = %q{guard-unity automatically runs Unity Test Tools on file changes}
13
+ spec.homepage = 'https://github.com/rubyrainbows/guard-unity-test'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'guard', '~> 2.0'
21
+ spec.add_dependency 'nokogiri', '~> 1.6'
22
+ spec.add_dependency 'formatador', '~> 0.2'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.3'
25
+ spec.add_development_dependency 'rake', '~> 10.1'
26
+ spec.add_development_dependency 'rspec', '~> 2.14'
27
+ spec.add_development_dependency 'rspec-core', '~> 2.14'
28
+ spec.add_development_dependency 'rspec-mocks', '~> 2.14'
29
+ end
@@ -0,0 +1,45 @@
1
+ require 'guard'
2
+ require 'guard/plugin'
3
+
4
+ module Guard
5
+ class Unity < Plugin
6
+
7
+ require 'guard/unity/runner'
8
+ require 'guard/unity/options'
9
+
10
+ attr_accessor :runner, :options
11
+
12
+ def initialize(options = {})
13
+ super
14
+ @options = Options.with_defaults(options)
15
+ @runner = Runner.new(@options)
16
+ end
17
+
18
+ def start
19
+ _show_start_message
20
+ puts runner.run if _should_test_on_start?
21
+ end
22
+
23
+ def run_on_modifications(paths)
24
+ puts runner.run
25
+ end
26
+
27
+ def reload
28
+ end
29
+
30
+ def run_all
31
+ puts runner.run
32
+ end
33
+
34
+ private
35
+
36
+ def _show_start_message
37
+ ::Guard::UI::info 'Guard::Unity is running'
38
+ end
39
+
40
+ def _should_test_on_start?
41
+ options[:test_on_start]
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,24 @@
1
+ module Guard
2
+ class Unity
3
+ class Notifier
4
+
5
+ require 'guard/unity/notifier/alert'
6
+ require 'guard/unity/notifier/cli'
7
+
8
+ TITLE = 'Unity Tests Results'
9
+
10
+ attr_accessor :alert, :cli
11
+
12
+ def initialize(options={})
13
+ @alert = options[:alert] || Guard::Unity::Notifier::Alert.new
14
+ @cli = options[:cli] || Guard::Unity::Notifier::CLI.new
15
+ end
16
+
17
+ def notify(results)
18
+ alert.notify(results, TITLE)
19
+ cli.notify(results)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ module Guard
2
+ class Unity
3
+ class Notifier
4
+ class Alert
5
+
6
+ def notify(results, title)
7
+ image = _image(results)
8
+ message = _message(results)
9
+ ::Guard::Notifier::notify(message, {title: title, image: image})
10
+ end
11
+
12
+ private
13
+
14
+ def _image(results)
15
+ return :failed if results[:failures] > 0
16
+ return :failed if results[:errors] > 0
17
+ :success
18
+ end
19
+
20
+ def _message(results)
21
+ message = "#{results[:tests]} tests\n"
22
+ message << "#{results[:failures]} failures\n" if results[:failures]
23
+ message << "#{results[:errors]} errors\n" if results[:errors]
24
+ message << "#{results[:ignored]} ignored\n" if results[:ignored]
25
+ message << "#{results[:skipped]} skipped\n" if results[:skipped]
26
+ message << "#{results[:inconclusive]} inconclusive\n" if results[:inconclusive]
27
+ message << "#{results[:invalid]} invalid\n" if results[:invalid]
28
+ message << "#{results[:not_run]} not run\n" if results[:not_run]
29
+ message
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,79 @@
1
+ module Guard
2
+ class Unity
3
+ class Notifier
4
+ class CLI
5
+
6
+ require 'formatador'
7
+
8
+ attr_accessor :formatador
9
+
10
+ SEPARATOR = '-'*100
11
+
12
+ def initialize(options={})
13
+ @formatador = options[:formatador] || Formatador.new
14
+ end
15
+
16
+ def notify(results={})
17
+ cases = results[:test_cases] || []
18
+ table = []
19
+ errors = []
20
+
21
+ cases.each do |test_case|
22
+ table << _row(test_case)
23
+ errors << _error(test_case) if test_case[:failed]
24
+ end
25
+ _display_results results
26
+ _display_table table
27
+ _display_errors errors
28
+ end
29
+
30
+ private
31
+
32
+ def _display_results(results)
33
+ table = [{
34
+ 'Tests' => results[:tests],
35
+ 'Failures' => results[:failures],
36
+ 'Errors' => results[:errors],
37
+ 'Ignored' => results[:ignored],
38
+ 'Skipped' => results[:skipped],
39
+ 'Inconclusive' => results[:inconclusive],
40
+ 'Invalid' => results[:invalid],
41
+ 'Not Run' => results[:not_run]
42
+ }]
43
+ formatador.display_table table, ['Tests', 'Failures', 'Errors', 'Ignored', 'Skipped', 'Inconclusive', 'Invalid', 'Not Run']
44
+ formatador.display_line
45
+ end
46
+
47
+ def _display_table(table)
48
+ formatador.display_table table
49
+ end
50
+
51
+ def _display_errors(errors)
52
+ formatador.display_line
53
+ formatador.display_line SEPARATOR
54
+ formatador.display_line "| [red]Failures[/]"
55
+ formatador.display_line SEPARATOR
56
+ count = 1
57
+ errors.each do |error|
58
+ formatador.display_line
59
+ formatador.display_line "#{count}: #{error[:name]}:\n"
60
+ formatador.display_line "[red]#{error[:message]}[/]\n" unless error[:message] == ""
61
+ formatador.display_line "[red]#{error[:stack]}[/]\n" unless error[:stack] == ""
62
+ formatador.display_line SEPARATOR
63
+ count = count + 1
64
+ end
65
+ end
66
+
67
+ def _row(test_case)
68
+ success = (test_case[:failed]) ? '[red]Failed[/]' : '[green]Success[/]'
69
+ {name: test_case[:name], success: success}
70
+ end
71
+
72
+ def _error(test_case)
73
+ {name: test_case[:name], message: test_case[:message], stack: test_case[:stack]}
74
+ end
75
+
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,26 @@
1
+ module Guard
2
+ class Unity
3
+ module Options
4
+
5
+ DEFAULTS = {
6
+ test_on_start: true,
7
+ project_path: Dir.pwd,
8
+ unity: '/Applications/Unity/Unity.app/Contents/MacOS/Unity',
9
+ results_path: Dir.pwd + '/UnitTestResults.xml'
10
+ }
11
+
12
+ class << self
13
+ def with_defaults(options={})
14
+ opts = DEFAULTS.merge(options)
15
+ opts[:project_path] = clean_directory(opts[:project_path]) # needs to be formatted for cli
16
+ opts
17
+ end
18
+
19
+ def clean_directory(dir)
20
+ dir.gsub(' ', '\ ')
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,64 @@
1
+ module Guard
2
+ class Unity
3
+ class Parser
4
+
5
+ require 'nokogiri'
6
+
7
+ attr_accessor :options, :doc
8
+
9
+ def initialize(options={})
10
+ @options = options
11
+ @doc = nil
12
+ end
13
+
14
+ def parse()
15
+ {
16
+ tests: _get('total'),
17
+ failures: _get('failures'),
18
+ errors: _get('errors'),
19
+ ignored: _get('ignored'),
20
+ not_run: _get('not-run'),
21
+ inconclusive: _get('inconclusive'),
22
+ invalid: _get('invalid'),
23
+ skipped: _get('skipped'),
24
+ test_cases: _testCases
25
+ }
26
+ end
27
+
28
+ private
29
+
30
+ def _get (find)
31
+ doc ||= _getXMLFile
32
+ node = doc.at_xpath("/test-results/@" + find)
33
+ (node == nil) ? 0 : node.value.to_i
34
+ end
35
+
36
+ def _testCases()
37
+ doc ||= _getXMLFile
38
+ nodes = doc.xpath("test-results/test-suite/results/test-case")
39
+ cases = []
40
+
41
+ nodes.each do |node|
42
+ message = node.at_xpath('failure/message') || node.at_xpath('reason/message')
43
+ stack = node.at_xpath('failure/stack-trace') || node.at_xpath('reason/stack-trace')
44
+ cases << {
45
+ name: node['name'],
46
+ failed: (node['success'] == 'False') ? true : false,
47
+ message: (message) ? message.text.gsub("\n",'').strip : "",
48
+ stack: (stack) ? stack.text.gsub("\n",'').strip : ""
49
+ }
50
+ end
51
+
52
+ cases
53
+ end
54
+
55
+ def _getXMLFile()
56
+ f = File.open(options[:results_path])
57
+ doc = Nokogiri::XML(f)
58
+ f.close
59
+ doc
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,45 @@
1
+ module Guard
2
+ class Unity
3
+ class Runner
4
+
5
+ require 'guard/unity/parser'
6
+ require 'guard/unity/notifier'
7
+
8
+ attr_accessor :options, :parser, :notifier
9
+
10
+ def initialize(options = {})
11
+ @options = options
12
+ @parser = options[:parser] || Guard::Unity::Parser.new(options)
13
+ @notifier = options[:notifier] || Guard::Unity::Notifier.new
14
+ end
15
+
16
+ def run
17
+ _run
18
+ end
19
+
20
+ private
21
+
22
+ def _run
23
+ UI.info 'Guard::Unity - Starting Tests. Results will be displayed when finished testing.'
24
+ output = _execute_command _command
25
+ notifier.notify(parser.parse) if $?.success?
26
+ output
27
+ end
28
+
29
+ def _command
30
+ cmd = []
31
+
32
+ cmd << options[:unity]
33
+ cmd << '-projectPath ' + options[:project_path]
34
+ cmd << '-batchmode -executeMethod UnityTest.UnitTestView.RunAllTestsBatch'
35
+
36
+ cmd.join ' '
37
+ end
38
+
39
+ def _execute_command(command)
40
+ %x{#{command}}
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ guard :unity do
2
+ watch(%r{^.*\.cs$})
3
+ end
@@ -0,0 +1,5 @@
1
+ module Guard
2
+ module UnityVersion
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,32 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!--This file represents the results of running a test suite-->
3
+ <test-results name="Unity Tests" total="21" errors="1" failures="2" not-run="2" inconclusive="4" ignored="1" skipped="1" invalid="0">
4
+ <environment />
5
+ <culture-info current-culture="" current-uiculture="" />
6
+ <test-suite name="Unit Tests" type="Assembly" executed="True" result="Failure" success="False" time="0.400">
7
+ <results>
8
+ <test-case name="test 1" executed="True" result="Success" success="True">
9
+ </test-case>
10
+ <test-case name="test 2" executed="True" result="Skipped" success="False">
11
+ <reason>
12
+ <message>
13
+ Message
14
+ </message>
15
+ <stack-trace>
16
+ foo
17
+ </stack-trace>
18
+ </reason>
19
+ </test-case>
20
+ <test-case name="test 3" executed="True" result="Failure" success="False">
21
+ <failure>
22
+ <message>
23
+ Message
24
+ </message>
25
+ <stack-trace>
26
+ foo
27
+ </stack-trace>
28
+ </failure>
29
+ </test-case>
30
+ </results>
31
+ </test-suite>
32
+ </test-results>
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Guard::Unity::Notifier do
4
+
5
+ let (:results) {
6
+ {
7
+ tests: 100,
8
+ errors: 0,
9
+ failures: 0
10
+ }
11
+ }
12
+ let (:subject) { Guard::Unity::Notifier::Alert.new}
13
+
14
+ describe '#notify' do
15
+
16
+ it 'should give a success message' do
17
+ @results = results
18
+ ::Guard::Notifier::should_receive(:notify).with(message(@results), {image: :success, title: Guard::Unity::Notifier::TITLE})
19
+ subject.notify(@results, Guard::Unity::Notifier::TITLE)
20
+ end
21
+
22
+ it 'should give failed message' do
23
+ @results = results.merge(failures: 1)
24
+ ::Guard::Notifier::should_receive(:notify).with(message(@results), {image: :failed, title: Guard::Unity::Notifier::TITLE})
25
+ subject.notify(@results, Guard::Unity::Notifier::TITLE)
26
+ end
27
+
28
+ it 'should give error message' do
29
+ @results = results.merge(errors: 1)
30
+ ::Guard::Notifier::should_receive(:notify).with(message(@results), {image: :failed, title: Guard::Unity::Notifier::TITLE})
31
+ subject.notify(@results, Guard::Unity::Notifier::TITLE)
32
+ end
33
+
34
+ end
35
+
36
+ # taken from the class to make testing easier
37
+ def message(results)
38
+ message = "#{results[:tests]} tests\n"
39
+ message << "#{results[:failures]} failures\n"
40
+ message << "#{results[:errors]} errors\n"
41
+ message
42
+ end
43
+
44
+ end