guardian-angel 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/guardian-angel +13 -0
- data/bin/xctestfile +12 -0
- data/lib/ga_configuration.rb +94 -0
- data/lib/ga_loader.rb +87 -0
- data/lib/ga_logger.rb +32 -0
- data/lib/ga_runner.rb +74 -0
- data/lib/guardian_angel.rb +42 -0
- metadata +80 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b756688b60516c6856da9c1cff4576f846f52056
|
4
|
+
data.tar.gz: d896fceb43a6d3291435f69fab862f073c3f1a4e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 61cea12f91402ba6a541d27a2d8aaa606deea1c2bc954dd0b17f9179cee9ee633179d466283b9428e030156ebb3f0e07087fe708a33369f1304952d3ab7a20b2
|
7
|
+
data.tar.gz: 58148addf0594055fd9a76ccff0b8502781bf72f21ee24f8913d69633adad37a8c308cb1f3bc24688d9bd633dd78276f5e1f4ac1961b182f6059bc06a5d77b0c
|
data/bin/guardian-angel
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ga_loader'
|
4
|
+
require 'guardian_angel'
|
5
|
+
require 'ga_logger'
|
6
|
+
|
7
|
+
trap("INT") { exit }
|
8
|
+
|
9
|
+
configuration = GALoader.readConfiguration()
|
10
|
+
|
11
|
+
watcher = GuardianAngel.new(configuration)
|
12
|
+
watcher.buildTests()
|
13
|
+
watcher.watch()
|
data/bin/xctestfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ga_loader'
|
4
|
+
require 'ga_runner'
|
5
|
+
|
6
|
+
trap("INT") { exit }
|
7
|
+
|
8
|
+
fileToTest = GALoader.getFileFromArgv(ARGV)
|
9
|
+
configuration = GALoader.readConfiguration()
|
10
|
+
|
11
|
+
runner = GARunner.new(configuration, fileToTest)
|
12
|
+
runner.test()
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# @author Vittorio Monaco
|
2
|
+
class GAConfiguration
|
3
|
+
GAConfigurationScheme = "scheme"
|
4
|
+
GAConfigurationWorkspace = "workspace"
|
5
|
+
GAConfigurationTarget = "target"
|
6
|
+
GAConfigurationSuffix = "suffix"
|
7
|
+
GAConfigurationReporter = "reporter"
|
8
|
+
GAConfigurationXctoolPath = "xctool"
|
9
|
+
|
10
|
+
# @return the configured xcode scheme
|
11
|
+
def scheme
|
12
|
+
@scheme
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return the configured xcode workspace
|
16
|
+
def workspace
|
17
|
+
@workspace
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return the configured suffix for tests files
|
21
|
+
def suffix
|
22
|
+
@suffix
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return the configured xcode tests target
|
26
|
+
def target
|
27
|
+
@target
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return the configured xctool reporter
|
31
|
+
def reporter
|
32
|
+
@reporter
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return the configured xctool executable path
|
36
|
+
def xctool_path
|
37
|
+
@xctool_path
|
38
|
+
end
|
39
|
+
|
40
|
+
# Prints the configuration instance
|
41
|
+
# @return a [String] representation of the instance
|
42
|
+
def to_s
|
43
|
+
hashForOutput = {
|
44
|
+
GAConfigurationScheme => @scheme,
|
45
|
+
GAConfigurationWorkspace => @workspace,
|
46
|
+
GAConfigurationTarget => @target,
|
47
|
+
GAConfigurationSuffix => @suffix,
|
48
|
+
GAConfigurationReporter => @reporter,
|
49
|
+
GAConfigurationXctoolPath => @xctool_path
|
50
|
+
}
|
51
|
+
|
52
|
+
return hashForOutput.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
# Creates an instance with the given configuration, or uses a default one if not provided
|
56
|
+
# @param configuration [GAConfiguration]
|
57
|
+
#
|
58
|
+
# @note by default the #suffix is implied as "Test", the #reporter as "pretty" and the #xctool_path as "xctool"
|
59
|
+
def initialize(configuration = { GAConfigurationSuffix => "Test", GAConfigurationReporter => "pretty", GAConfigurationXctoolPath => "xctool" })
|
60
|
+
@scheme = configuration[GAConfigurationScheme]
|
61
|
+
@workspace = configuration[GAConfigurationWorkspace]
|
62
|
+
@target = configuration[GAConfigurationTarget]
|
63
|
+
@suffix = configuration[GAConfigurationSuffix]
|
64
|
+
@reporter = configuration[GAConfigurationReporter]
|
65
|
+
@xctool_path = configuration[GAConfigurationXctoolPath]
|
66
|
+
end
|
67
|
+
|
68
|
+
# Merges two GAConfiguration instances
|
69
|
+
#
|
70
|
+
# @param other [GAConfiguration] another instance of GAConfiguration you want to merge
|
71
|
+
# @note nil values will not overwrite valid values of self
|
72
|
+
def merge(other)
|
73
|
+
unless other.scheme.nil?
|
74
|
+
@scheme = other.scheme
|
75
|
+
end
|
76
|
+
unless other.workspace.nil?
|
77
|
+
@workspace = other.workspace
|
78
|
+
end
|
79
|
+
unless other.target.nil?
|
80
|
+
@target = other.target
|
81
|
+
end
|
82
|
+
unless other.suffix.nil?
|
83
|
+
@suffix = other.suffix
|
84
|
+
end
|
85
|
+
unless other.reporter.nil?
|
86
|
+
@reporter = other.reporter
|
87
|
+
end
|
88
|
+
unless other.xctool_path.nil?
|
89
|
+
@xctool_path = other.xctool_path
|
90
|
+
end
|
91
|
+
|
92
|
+
return self
|
93
|
+
end
|
94
|
+
end
|
data/lib/ga_loader.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'ga_logger'
|
3
|
+
require 'ga_configuration'
|
4
|
+
|
5
|
+
CONFIG_FILENAME = 'guardian_angel.json'
|
6
|
+
|
7
|
+
# @author Vittorio Monaco
|
8
|
+
class GALoader
|
9
|
+
# Reads the configuration from the file guardian_angel.json
|
10
|
+
#
|
11
|
+
# @note if the file is not found, it will try to build with default values instead
|
12
|
+
# @note this also outputs the final GAConfiguration built on the console
|
13
|
+
# (see #GAConfiguration)
|
14
|
+
def self.readConfiguration()
|
15
|
+
GALogger.log("Reading #{CONFIG_FILENAME}...")
|
16
|
+
|
17
|
+
configuration = GAConfiguration.new
|
18
|
+
|
19
|
+
begin
|
20
|
+
jsonDictionary = JSON.parse(File.read(CONFIG_FILENAME))
|
21
|
+
configurationMerge = GAConfiguration.new(jsonDictionary)
|
22
|
+
configuration = configuration.merge(configurationMerge)
|
23
|
+
rescue
|
24
|
+
#Find workspace, scheme and target
|
25
|
+
#merge and return
|
26
|
+
GALogger.log("#{CONFIG_FILENAME} not found, using defaults", :Warning)
|
27
|
+
end
|
28
|
+
|
29
|
+
validateConfiguration(configuration)
|
30
|
+
outputConfiguration(configuration)
|
31
|
+
|
32
|
+
return configuration
|
33
|
+
end
|
34
|
+
|
35
|
+
# Validates a given configuration
|
36
|
+
#
|
37
|
+
# @param configuration [GAConfiguration] the configuration to validate
|
38
|
+
# @note required attributes are workspace, scheme and target
|
39
|
+
# @note the method will also make sure that the configured xctool executable can be found, or aborts otherwise
|
40
|
+
def self.validateConfiguration(configuration)
|
41
|
+
if configuration.workspace.nil?
|
42
|
+
GALogger.log("workspace was not specified, exiting", :Error)
|
43
|
+
abort
|
44
|
+
end
|
45
|
+
if configuration.scheme.nil?
|
46
|
+
GALogger.log("scheme was not specified, exiting", :Error)
|
47
|
+
abort
|
48
|
+
end
|
49
|
+
if configuration.target.nil?
|
50
|
+
GALogger.log("target was not specified, exiting", :Error)
|
51
|
+
abort
|
52
|
+
end
|
53
|
+
|
54
|
+
xctoolExists = system("which #{configuration.xctool_path} > /dev/null")
|
55
|
+
if !xctoolExists
|
56
|
+
GALogger.log(configuration.xctool_path + " can't be found. Aborting.", :Error)
|
57
|
+
abort
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Outputs a given configuration on the console
|
62
|
+
#
|
63
|
+
# @param [GAConfiguration] the configuration you want to print
|
64
|
+
def self.outputConfiguration(configuration)
|
65
|
+
puts configuration.to_s
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns a filename from a given array
|
69
|
+
#
|
70
|
+
# @param argv [Array<String>] an array of strings
|
71
|
+
#
|
72
|
+
# @note the method will take the last element of the array
|
73
|
+
# @note the method will take only the filename if the element of the array is a file, removing the extension and the path
|
74
|
+
def self.getFileFromArgv(argv)
|
75
|
+
fileToTest = nil
|
76
|
+
argv.each do|a|
|
77
|
+
fileToTest = File.basename(a, ".*")
|
78
|
+
end
|
79
|
+
|
80
|
+
if fileToTest.nil?
|
81
|
+
GALogger.log('Failed to get file', :Error)
|
82
|
+
abort
|
83
|
+
end
|
84
|
+
|
85
|
+
return fileToTest
|
86
|
+
end
|
87
|
+
end
|
data/lib/ga_logger.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# @author Vittorio Monaco
|
2
|
+
class GALogger
|
3
|
+
:Error
|
4
|
+
:Warning
|
5
|
+
:Success
|
6
|
+
:Default
|
7
|
+
|
8
|
+
# Logs a message on the console
|
9
|
+
#
|
10
|
+
# @param message [String] a string to log
|
11
|
+
# @param type [Symbol] specifies the type of message. This can be :Error, :Warning, :Success or :Default
|
12
|
+
# @note depending on the message type, a different color will be used to print the message on the console
|
13
|
+
def self.log(message, type = :Default)
|
14
|
+
puts sequenceForType(type) + '### ' + message + ' ###' + sequenceForType(:Default)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the character code to print with the right color given a message type
|
18
|
+
#
|
19
|
+
# @param type [Symbol] the message type. This can be :Error, :Warning, :Success or :Default
|
20
|
+
def self.sequenceForType(type)
|
21
|
+
case type
|
22
|
+
when :Success
|
23
|
+
return "\033[32m"
|
24
|
+
when :Error
|
25
|
+
return "\033[31m"
|
26
|
+
when :Warning
|
27
|
+
return "\033[33m"
|
28
|
+
else
|
29
|
+
return "\033[0m"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/ga_runner.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'ga_logger'
|
2
|
+
require 'guardian_angel'
|
3
|
+
|
4
|
+
# @author Vittorio Monaco
|
5
|
+
class GARunner
|
6
|
+
# Creates a new instance given a GAConfiguration object and a filename to run tests
|
7
|
+
#
|
8
|
+
# @param configuration [GAConfiguration] the configuration you want to use to run the tests (see #GAConfiguration)
|
9
|
+
# @param filename [String] the name of the file you want to run the tests for
|
10
|
+
# @note filename can also be a tests file
|
11
|
+
def initialize(configuration, filename)
|
12
|
+
@configuration=configuration
|
13
|
+
@filename=filename
|
14
|
+
end
|
15
|
+
|
16
|
+
# Runs unit tests for the given filename, if a tests file exists
|
17
|
+
#
|
18
|
+
# @param filename [String] the file you want to run tests for
|
19
|
+
# @note filename must be a code file, not a tests file. If you're not sure whether the file is a tests file or not, use #test instead
|
20
|
+
# @note if a corresponding tests file cannot be found, outputs a warning line
|
21
|
+
def testIfAvailable(filename)
|
22
|
+
workspace = @configuration.workspace
|
23
|
+
scheme = @configuration.scheme
|
24
|
+
target = @configuration.target
|
25
|
+
suffix = @configuration.suffix
|
26
|
+
reporter = @configuration.reporter
|
27
|
+
xctool = @configuration.xctool_path
|
28
|
+
|
29
|
+
fileExists = system('find . | grep ' + filename + suffix + ' > /dev/null')
|
30
|
+
if !fileExists
|
31
|
+
GALogger.log(filename + " doesn't seem to have associated tests. You may think about it.", :Warning)
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
GALogger.log("Running tests for file " + filename + '...')
|
36
|
+
system(xctool + ' -workspace -workspace ' + workspace + '.xcworkspace' +
|
37
|
+
' -scheme ' + scheme +
|
38
|
+
' -sdk iphonesimulator' +
|
39
|
+
' run-tests' +
|
40
|
+
' -reporter ' + reporter
|
41
|
+
' only ' + target + ':' + filename + suffix, out: $stdout, err: :out)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Tries to run unit tests for the filename setup during initialization
|
45
|
+
#
|
46
|
+
# @note if the filename is a tests file, this method strips the tests suffix and runs the tests for the right file instead, after having built the tests project first
|
47
|
+
# (see #buildIfNeeded)
|
48
|
+
# (see #testIfAvailable)
|
49
|
+
def test()
|
50
|
+
filename = @filename
|
51
|
+
suffix = @configuration.suffix
|
52
|
+
|
53
|
+
buildIfNeeded()
|
54
|
+
if isTest()
|
55
|
+
filename = @filename.slice(/(?<file>.*)#{suffix}$/, "file")
|
56
|
+
end
|
57
|
+
|
58
|
+
testIfAvailable(filename)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return true if the filename is a tests file
|
62
|
+
def isTest()
|
63
|
+
return @filename.end_with? @configuration.suffix
|
64
|
+
end
|
65
|
+
|
66
|
+
# This method builds the tests project if the filename setup during initialization is a tests file
|
67
|
+
# (see #isTest)
|
68
|
+
def buildIfNeeded()
|
69
|
+
if isTest()
|
70
|
+
GALogger.log(@filename + ' is a test, building all the tests...')
|
71
|
+
GuardianAngel.buildWithConfiguration(@configuration)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'ga_logger'
|
2
|
+
|
3
|
+
# @author Vittorio Monaco
|
4
|
+
class GuardianAngel
|
5
|
+
# Creates a new instance given a GAConfiguration object
|
6
|
+
#
|
7
|
+
# @param configuration [GAConfiguration] the configuration you want to use to run the tests (see #GAConfiguration)
|
8
|
+
def initialize(configuration)
|
9
|
+
@configuration=configuration
|
10
|
+
end
|
11
|
+
|
12
|
+
# Convenience method to build tests in a stand-alone fashion
|
13
|
+
#
|
14
|
+
# @param configuration [GAConfiguration] the configuration you want to use to run the tests (see #GAConfiguration)
|
15
|
+
def self.buildWithConfiguration(configuration)
|
16
|
+
watcher = GuardianAngel.new(configuration)
|
17
|
+
watcher.buildTests()
|
18
|
+
end
|
19
|
+
|
20
|
+
# Builds the tests target through xctool
|
21
|
+
#
|
22
|
+
# @note a configuration must be already setup for this method to work
|
23
|
+
def buildTests()
|
24
|
+
workspace = @configuration.workspace
|
25
|
+
scheme = @configuration.scheme
|
26
|
+
xctool = @configuration.xctool_path
|
27
|
+
|
28
|
+
GALogger.log("Building workspace " + workspace + " with scheme " + scheme + "...")
|
29
|
+
system(xctool + ' -workspace ' + workspace + '.xcworkspace' +
|
30
|
+
' -scheme ' + scheme +
|
31
|
+
' -sdk iphonesimulator' +
|
32
|
+
' build-tests', out: $stdout, err: :out)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Starts watching for changes to .m or .swift files in the caller directory
|
36
|
+
#
|
37
|
+
# @note this uses the gem filewatcher
|
38
|
+
def watch()
|
39
|
+
GALogger.log("Watching...")
|
40
|
+
system("filewatcher '*.{m,swift}' 'xctestfile $FILENAME'", out: $stdout, err: :out)
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: guardian-angel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vittorio Monaco
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: filewatcher
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.8'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.8'
|
41
|
+
description: A file watcher that runs tests for the modified files
|
42
|
+
email: vittorio.monaco1@gmail.com
|
43
|
+
executables:
|
44
|
+
- guardian-angel
|
45
|
+
- xctestfile
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- bin/guardian-angel
|
50
|
+
- bin/xctestfile
|
51
|
+
- lib/ga_configuration.rb
|
52
|
+
- lib/ga_loader.rb
|
53
|
+
- lib/ga_logger.rb
|
54
|
+
- lib/ga_runner.rb
|
55
|
+
- lib/guardian_angel.rb
|
56
|
+
homepage: http://vittoriomonaco.it
|
57
|
+
licenses:
|
58
|
+
- MIT
|
59
|
+
metadata: {}
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 2.2.1
|
77
|
+
signing_key:
|
78
|
+
specification_version: 4
|
79
|
+
summary: Guardian Angel
|
80
|
+
test_files: []
|