guardian-angel 0.0.1

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.
@@ -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
@@ -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()
@@ -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
@@ -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
@@ -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
@@ -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: []