guard-unity 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +99 -0
- data/Rakefile +6 -0
- data/guard-unity-test.sublime-workspace +455 -0
- data/guard-unity.gemspec +29 -0
- data/lib/guard/unity.rb +45 -0
- data/lib/guard/unity/notifier.rb +24 -0
- data/lib/guard/unity/notifier/alert.rb +35 -0
- data/lib/guard/unity/notifier/cli.rb +79 -0
- data/lib/guard/unity/options.rb +26 -0
- data/lib/guard/unity/parser.rb +64 -0
- data/lib/guard/unity/runner.rb +45 -0
- data/lib/guard/unity/templates/Guardfile +3 -0
- data/lib/guard/unity/version.rb +5 -0
- data/spec/fixtures/UnitTestResults.xml +32 -0
- data/spec/guard/unity-test/notifier/alert_spec.rb +44 -0
- data/spec/guard/unity-test/notifier/cli_spec.rb +25 -0
- data/spec/guard/unity-test/notifier_spec.rb +25 -0
- data/spec/guard/unity-test/options_spec.rb +17 -0
- data/spec/guard/unity-test/parser_spec.rb +17 -0
- data/spec/guard/unity-test/runner_spec.rb +38 -0
- data/spec/guard/unity_test_spec.rb +110 -0
- data/spec/spec_helper.rb +24 -0
- metadata +192 -0
data/guard-unity.gemspec
ADDED
@@ -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
|
data/lib/guard/unity.rb
ADDED
@@ -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,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
|