calasmash 0.0.10 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ script: bundle exec rspec spec
5
+ notifications:
6
+ email:
7
+ - fish@ustwo.co.uk
data/Gemfile.lock CHANGED
@@ -1,12 +1,52 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- calasmash (0.0.1)
4
+ calasmash (1.0.0)
5
+ CFPropertyList
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
10
+ CFPropertyList (2.2.4)
11
+ coderay (1.0.9)
12
+ diff-lcs (1.2.5)
13
+ ffi (1.9.0)
14
+ formatador (0.2.4)
15
+ guard (1.8.0)
16
+ formatador (>= 0.2.4)
17
+ listen (>= 1.0.0)
18
+ lumberjack (>= 1.0.2)
19
+ pry (>= 0.9.10)
20
+ thor (>= 0.14.6)
21
+ guard-rspec (3.0.0)
22
+ guard (>= 1.8)
23
+ rspec (~> 2.13)
24
+ listen (1.1.6)
25
+ rb-fsevent (>= 0.9.3)
26
+ rb-inotify (>= 0.9)
27
+ rb-kqueue (>= 0.2)
28
+ lumberjack (1.0.3)
29
+ method_source (0.8.1)
30
+ pry (0.9.12.2)
31
+ coderay (~> 1.0.5)
32
+ method_source (~> 0.8)
33
+ slop (~> 3.4)
9
34
  rake (10.1.0)
35
+ rb-fsevent (0.9.3)
36
+ rb-inotify (0.9.0)
37
+ ffi (>= 0.5.0)
38
+ rb-kqueue (0.2.0)
39
+ ffi (>= 0.5.0)
40
+ rspec (2.14.1)
41
+ rspec-core (~> 2.14.0)
42
+ rspec-expectations (~> 2.14.0)
43
+ rspec-mocks (~> 2.14.0)
44
+ rspec-core (2.14.7)
45
+ rspec-expectations (2.14.4)
46
+ diff-lcs (>= 1.1.3, < 2.0)
47
+ rspec-mocks (2.14.4)
48
+ slop (3.4.4)
49
+ thor (0.18.1)
10
50
 
11
51
  PLATFORMS
12
52
  ruby
@@ -14,4 +54,6 @@ PLATFORMS
14
54
  DEPENDENCIES
15
55
  bundler (~> 1.3)
16
56
  calasmash!
57
+ guard-rspec
17
58
  rake
59
+ rspec
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec, :cli => '--color --format doc' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
1
  calasmash
2
2
  =========
3
3
 
4
- A hacky gem to compile a calabash ios target, set some settings bundle values then run cucumber tests
4
+ [![Gem Version](https://badge.fury.io/rb/calasmash.png)](http://badge.fury.io/rb/calasmash)
5
+ [![Build Status](https://travis-ci.org/ustwo/calasmash.png?branch=master)](https://travis-ci.org/ustwo/calasmash)
6
+
7
+ Calasmash provides an interface to run a suite of calabash-ios tests against an iOS application using a mocked backend.
5
8
 
6
9
  ## Installation
7
10
 
@@ -11,26 +14,37 @@ Add this line to your application's Gemfile:
11
14
 
12
15
  And then execute:
13
16
 
14
- $ bundle
15
-
16
- Or install it yourself as:
17
-
18
- $ gem install calasmash
17
+ $ bundle install
19
18
 
20
19
  ## Usage
21
20
 
22
- Simply run the command below and pass valid options, workspace and scheme are required.
21
+ Simply run the command below with your preferred arguments.
23
22
 
24
23
  calasmash
25
24
 
26
25
  ### Options
27
26
 
28
- -t, --tags TAGS the cucumber tags to test against
29
- -w, --workspace WORKSPACE the workspace to build
30
- -s, --scheme SCHEME the scheme to build
31
- -h, --help help
27
+ --tags -t the tags to pass to Cucumber, for multiple tags pass one -t option per tag
28
+ --scheme -s the Xcode scheme to build
29
+ --ios -i the iOS version to build with
30
+ --output -o The output directory for the test report
31
+ --format -f The format of the test report
32
+
33
+ ## Configuration
34
+
35
+ Your cucumber tests will need to start a Sinatra server before running with the launch `Before` step.
36
+
37
+ The iOS application should contain a `server_config.plist` file in the following format:
38
+
39
+ [Sample plist](https://gist.github.com/alexfish/7505037)
40
+
41
+ calasmash will update the port and url values before launching the application, your iOS application will need to use the plist values when running it's calabash-ios target.
42
+
43
+ You can then use a method along these lines to get the url in the iOS application when running the calabash target and direct any API requests to the url.
44
+
45
+ [Sample method](https://gist.github.com/alexfish/7505005)
32
46
 
33
- ## Contributing
47
+ ## Contributing
34
48
 
35
49
  1. Fork it
36
50
  2. Create your feature branch (`git checkout -b my-new-feature`)
data/bin/calasmash CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # coding: utf-8
2
3
 
3
4
  require 'calasmash'
4
5
 
5
- Calasmash::Runner.new(ARGV)
6
+ Calasmash::Command.execute(*ARGV)
data/calasmash.gemspec CHANGED
@@ -1,15 +1,14 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'calasmash/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
6
  spec.name = "calasmash"
8
- spec.version = Calasmash::VERSION
7
+ spec.version = "1.0.0"
9
8
  spec.authors = ["Alex Fish"]
10
9
  spec.email = ["fish@ustwo.co.uk"]
11
10
  spec.description = "A gift for Juan"
12
- spec.summary = "Compile an app, run sinatra, point the app at sinatra, run the app tests with calabash"
11
+ spec.summary = "Compile an app, point the app at sinatra, run cucumber"
13
12
  spec.homepage = ""
14
13
  spec.license = "MIT"
15
14
 
@@ -20,8 +19,10 @@ Gem::Specification.new do |spec|
20
19
 
21
20
  spec.add_development_dependency "bundler", "~> 1.3"
22
21
  spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "rspec"
23
+ spec.add_development_dependency "guard-rspec"
23
24
 
24
- spec.add_runtime_dependency "CFPropertyList"
25
+ spec.add_runtime_dependency("CFPropertyList")
25
26
 
26
27
  spec.executables << "calasmash"
27
28
  end
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ module Calasmash
5
+
6
+ #
7
+ # The main point of entry for all commands, Command parses command line arguments
8
+ # and decides what to do about them.
9
+ #
10
+ # @author [alexfish]
11
+ #
12
+ class Command
13
+
14
+ class << self
15
+
16
+ #
17
+ # Execute a command with some arguments
18
+ # then figure out what we're supposed to be doing with
19
+ # the arguments
20
+ #
21
+ # @param *args [Array] An Array of arguments to play with
22
+ #
23
+ # @return [type] [description]
24
+ def execute(*args)
25
+ return overview unless args.length > 1
26
+
27
+ options = parse(args)
28
+ scheme = options[:scheme]
29
+ ios = options[:ios]
30
+ tags = options[:tags]
31
+ format = options[:format]
32
+ output = options[:output]
33
+
34
+ # Compile the project
35
+ compile(scheme) do
36
+ # Update the plist
37
+ update_plist(scheme)
38
+ # Run the tests
39
+ run_tests(ios, tags, format, output)
40
+ end
41
+ end
42
+
43
+ #
44
+ # parse the arguments and act on them
45
+ # @param args [Array] The arguments from execute
46
+ #
47
+ # @return [Hash] A hash containing all of our options
48
+ def parse(args)
49
+ options = {}
50
+ options[:tags] = []
51
+
52
+ OptionParser.new do |opt|
53
+ opt.on("-s","--scheme SCHEME","the scheme to build") do |tags|
54
+ options[:scheme] = tags
55
+ end
56
+
57
+ opt.on("-t","--tags TAGS","the tags to pass to Cucumber") do |tag_set|
58
+ options[:tags] << tag_set
59
+ end
60
+
61
+ opt.on("-i", "--ios OS", "iOS simulator version of the sdk to run e.g. 6.0 or 7.0") do |tags|
62
+ options[:ios] = tags
63
+ end
64
+
65
+ opt.on("-f", "--format FORMAT", "the format of the test reports to output") do |format|
66
+ options[:format] = format
67
+ end
68
+
69
+ opt.on("-o", "--output OUTPUT", "the output path for the test results") do |output|
70
+ options[:output] = output
71
+ end
72
+ end.parse!
73
+
74
+ return options
75
+ end
76
+
77
+ #
78
+ # Kick off a compile
79
+ # @param scheme [String] The scheme to compile
80
+ # @param &compiled [Block] Completion block
81
+ #
82
+ def compile(scheme, &compiled)
83
+ compiler = Calasmash::Compiler.new(scheme)
84
+ compiler.compile do |complete|
85
+ yield
86
+ end
87
+ end
88
+
89
+ #
90
+ # Update the applications plist so that the application
91
+ # connects to sinatra
92
+ # @param scheme [String] The scheme related to the application
93
+ #
94
+ def update_plist(scheme)
95
+ plist = Calasmash::Plist.new(scheme)
96
+ plist.execute
97
+ end
98
+
99
+ #
100
+ # Run the cucumber tests, that's why we're here afterall
101
+ #
102
+ # @param ios [String] The iOS version to test with
103
+ # @param tags [Array] The cucumber tags to test with
104
+ # @param format [String] The output format for the cucumber tests, Optional
105
+ # @param output [String] The path to the output directory to output test reports to, Optional
106
+ def run_tests(ios, tags, format=nil, output=nil)
107
+ cucumber = Calasmash::Cucumber.new(ios, tags)
108
+ cucumber.format = format if format
109
+ cucumber.output = output if output
110
+ cucumber.test
111
+ end
112
+
113
+ #
114
+ # Outputs a nice helpful banner overview to STDOUT
115
+ #
116
+ def overview
117
+ s = "Usage: calasmash [OPTIONS]"
118
+ s << "\n --tags -t the tags to pass to cucumber, for multiple tags pass one per tag"
119
+ s << "\n --scheme -s the Xcode scheme to build"
120
+ s << "\n --ios -i the iOS version to build with"
121
+ s << "\n --output -o The output directory for the test report"
122
+ s << "\n --format -f The format of the test report"
123
+
124
+ puts s
125
+ end
126
+
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,95 @@
1
+ # coding: utf-8
2
+
3
+ module Calasmash
4
+
5
+ #
6
+ # The calamsash compiler will compiles the Xcode project with the
7
+ # scheme it's told to compile with.
8
+ #
9
+ # @author [alexfish]
10
+ #
11
+ class Compiler
12
+
13
+ # Public: the Scheme the compiler is compiling
14
+ attr_accessor :scheme
15
+
16
+ def initialize(scheme)
17
+ @scheme = scheme
18
+ end
19
+
20
+ #
21
+ # The compiler's heart, executes the compiling with xcodebuild
22
+ #
23
+ # @param &complete Compleition block
24
+ #
25
+ # Returns nothing because it completes with a complete block
26
+ def compile(&complete)
27
+ started
28
+ status = nil
29
+ output = ""
30
+
31
+ Open3.popen3 command do |stdin, out, err, wait_thr|
32
+ [out, err].each do |stream|
33
+ Thread.new do
34
+ until (line = stream.gets).nil? do
35
+ print "."
36
+ output << line
37
+ end
38
+ end
39
+ end
40
+ wait_thr.join
41
+ status = wait_thr.value.exitstatus
42
+ end
43
+
44
+ if status != 0
45
+ puts "\nCompilation failed: \n\n #{output}"
46
+ exit status
47
+ else
48
+ completed
49
+ complete.call(true) if complete
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ #
56
+ # Output a nice message for starting
57
+ #
58
+ def started
59
+ puts "\nCompiling"
60
+ puts "=========\n"
61
+ end
62
+
63
+ #
64
+ # Output a nice message for completing
65
+ #
66
+ def completed
67
+ puts "\nCompiled 👌"
68
+ end
69
+
70
+ #
71
+ # Generate the string to be used as the xcode build command
72
+ # using the scheme ivar
73
+ #
74
+ # @return [String] The full xcode build command with args
75
+ def command
76
+ xcode_command = "xcodebuild -workspace #{workspace} \
77
+ -scheme #{@scheme} \
78
+ -sdk iphonesimulator \
79
+ CODE_SIGN_IDENTITY="" \
80
+ CODE_SIGNING_REQUIRED=NO"
81
+
82
+ xcode_command
83
+ end
84
+
85
+ #
86
+ # Looks in the current directory for the workspace file and
87
+ # gets it's name
88
+ #
89
+ # @return [String] The name of the workspace file that was found
90
+ def workspace
91
+ Dir["*.xcworkspace"].first
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ module Calasmash
5
+
6
+ #
7
+ # Provides a nice interface to cucumber, allowing
8
+ # us to run the cucumber test suite
9
+ #
10
+ # @author [alexfish]
11
+ #
12
+ class Cucumber
13
+
14
+ # Public: the output directory for the tests
15
+ attr_accessor :output
16
+
17
+ # Public: the output format for the tests
18
+ attr_accessor :format
19
+
20
+ #
21
+ # Create a new instance of Cucumber
22
+ # @param ios [String] The iOS version cucumber will run
23
+ # @param tags [Array] The tags cucumber will run with
24
+ #
25
+ def initialize(ios, tags)
26
+ @ios = ios
27
+ @tags = tags
28
+ end
29
+
30
+ #
31
+ # Run the cucumber tests
32
+ #
33
+ def test
34
+ started
35
+
36
+ status = nil
37
+ output = ""
38
+ Open3.popen3 command do |stdin, out, err, wait_thr|
39
+
40
+ [out, err].each do |stream|
41
+ Thread.new do
42
+ until (line = stream.gets).nil? do
43
+ print "."
44
+ output << line
45
+ end
46
+ end
47
+ end
48
+
49
+ wait_thr.join
50
+ status = wait_thr.value.exitstatus
51
+ end
52
+
53
+ if status != 0
54
+ puts "\n Compilation failed: \n\n #{output}"
55
+ exit status
56
+ else
57
+ completed
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ #
64
+ # Output a nice message for starting
65
+ #
66
+ def started
67
+ puts "\nRunning Cucumber"
68
+ puts "================\n"
69
+ end
70
+
71
+ #
72
+ # Output a nice message for completing
73
+ #
74
+ def completed
75
+ puts "\nCucumber Completed 👌"
76
+ end
77
+
78
+ #
79
+ # Figure out what the cucumber command is and
80
+ # return it
81
+ #
82
+ # @return [String] The cucumber command string
83
+ def command
84
+ command = "cucumber"
85
+ command += " OS=ios#{@ios.to_i} SDK_VERSION=#{@ios}" if @ios
86
+ command += " DEVICE_TARGET=simulator"
87
+ command += " --format #{self.format}" if self.format
88
+ command += " --out #{self.output}" if self.output
89
+ command += @tags.to_a.empty? ? "" : tag_arguments
90
+
91
+ command
92
+ end
93
+
94
+ #
95
+ # Generate the --tags arguments for the cucumber
96
+ # command
97
+ #
98
+ # @return [String] The --tags commands ready to go
99
+ def tag_arguments
100
+ command = ""
101
+ @tags.each do |tag_set|
102
+ command = "" unless command
103
+ command += " --tags #{tag_set}"
104
+ end
105
+ command
106
+ end
107
+
108
+ end
109
+ end
110
+
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ module Calasmash
5
+
6
+ #
7
+ # Does some fun stuff with Xcode plists, calasmash needs to update
8
+ # the Xcode projects plist to trick the simulator into connecting
9
+ # to a sinatra server instead
10
+ #
11
+ # @author [alexfish]
12
+ #
13
+ class Plist
14
+
15
+ # Public: the Scheme the plist is related to
16
+ attr_accessor :scheme
17
+
18
+ #
19
+ # Create a new plist instance
20
+ # @param scheme [String] The scheme related to the plist
21
+ #
22
+ # @return [Plist] A plist instance
23
+ def initialize(scheme)
24
+ @scheme = scheme
25
+ end
26
+
27
+ #
28
+ # Executes the plist tasks update and clear the old plists
29
+ #
30
+ def execute
31
+ started
32
+ update
33
+ clear
34
+
35
+ completed
36
+ end
37
+
38
+ private
39
+
40
+ #
41
+ # Output a nice message for starting
42
+ #
43
+ def started
44
+ puts "\nUpdating plist"
45
+ puts "=============="
46
+ end
47
+
48
+ #
49
+ # Output a nice message for completing
50
+ #
51
+ def completed
52
+ puts "Plist updated 👌"
53
+ end
54
+
55
+ #
56
+ # Update the Xcode applications server.plist file
57
+ # with sinatras port and URL
58
+ #
59
+ def update
60
+ plist_file = CFPropertyList::List.new(:file => server_plist_path)
61
+ plist = CFPropertyList.native_types(plist_file.value)
62
+
63
+ plist["url_preference"] = server_ip
64
+ plist["port_preference"] = Calasmash::PORT
65
+
66
+ plist_file.value = CFPropertyList.guess(plist)
67
+ plist_file.save(server_plist_path, CFPropertyList::List::FORMAT_XML)
68
+ end
69
+
70
+ #
71
+ # Clear the existing plist from the iOS simulator
72
+ #
73
+ def clear
74
+ FileUtils.rm(simulator_plist_path, :force => true)
75
+ end
76
+
77
+ #
78
+ # The local IP address of the mock backend server
79
+ #
80
+ # @return [String] The mock backends IP
81
+ def server_ip
82
+ Socket.ip_address_list.find {|a| a.ipv4? && !a.ipv4_loopback?}.ip_address
83
+ end
84
+
85
+ #
86
+ # The path to the iOS simulators plist
87
+ #
88
+ # @return [String] The path to the plist
89
+ def simulator_plist_path
90
+ "#{File.expand_path('~')}/Library/Preferences/com.apple.iphonesimulator.plist"
91
+ end
92
+
93
+ #
94
+ # The path to the application
95
+ #
96
+ # @return [String] The path to the application
97
+ def app_path
98
+ files = []
99
+
100
+ Find.find("#{File.expand_path('~')}/Library/Developer/Xcode/DerivedData/") do |path|
101
+ files << path if path =~ /#{@scheme}.app$/
102
+ end
103
+
104
+ files.sort_by { |filename| File.mtime(filename)}.last # get the latest
105
+ end
106
+
107
+ #
108
+ # The path to the server config plist
109
+ #
110
+ # @return The full path to the server config plist
111
+ def server_plist_path
112
+ app_path + "/server_config.plist"
113
+ end
114
+
115
+ end
116
+ end
data/lib/calasmash.rb CHANGED
@@ -1,211 +1,17 @@
1
- require "calasmash/version"
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
2
3
 
3
4
  require 'optparse'
4
- require 'socket'
5
+ require "open3"
5
6
  require 'cfpropertylist'
6
7
  require 'find'
7
- require 'open3'
8
-
9
- module Calasmash
10
- class Runner
11
-
12
- def initialize(args)
13
- @options = parse(args)
14
- if @options[:valid]
15
- start
16
- else
17
- puts "Invalid options!"
18
- end
19
- end
20
-
21
- def start
22
- puts "Starting..."
23
- compile
24
- update_plist
25
- delete_simulator_plist
26
- sleep(2)
27
- run_cucumber
28
- end
29
-
30
- def parse(args)
31
- options = {}
32
- options[:tags] = []
33
- @opt_parser = OptionParser.new do |opt|
34
- opt.banner = "Usage: calasmash [OPTIONS]"
35
- opt.separator ""
36
- opt.separator "Options"
37
-
38
- opt.on("-t","--tags TAGS","the tags to pass to Cucumber") do |tag_set|
39
- options[:tags] << tag_set
40
- end
41
-
42
- opt.on("-w","--workspace WORKSPACE","the workspace to build") do |tags|
43
- options[:workspace] = tags
44
- end
45
-
46
- opt.on("-s","--scheme SCHEME","the scheme to build") do |tags|
47
- options[:scheme] = tags
48
- end
49
-
50
- opt.on("-h","--help","help") do
51
- puts @opt_parser
52
- end
53
-
54
- opt.on('-f', "--format FORMAT", "test report format e.g. junit") do |tags|
55
- options[:format] = tags
56
- end
57
-
58
- opt.on('-o', "--out OUTPUT", "test report output path e.g. test") do |tags|
59
- options[:out] = tags
60
- end
61
-
62
- opt.on('-ios', "--ios OS", "iOS simulator version of the sdk to run e.g. 6.0 or 7.0") do |tags|
63
- options[:ios] = tags
64
- end
65
- end
66
-
67
- @opt_parser.parse! args
68
-
69
- options[:valid] = true
70
-
71
- validate_options(options)
72
- return options
73
- end
74
-
75
- def validate_options(options)
76
- if options[:workspace].nil?
77
- puts "Workspace path required, see --help for more information"
78
- options[:valid] = false
79
- elsif options[:scheme].nil?
80
- puts "Scheme required, see --help for more information"
81
- options[:valid] = false
82
- end
83
- options
84
- end
85
-
86
- def compile
87
- puts "Compiling..."
88
-
89
- status = nil
90
- xcode_command = "xcodebuild -workspace #{@options[:workspace]} -scheme #{@options[:scheme]} -sdk iphonesimulator CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO"
91
- Open3.popen3 xcode_command do |stdin, out, err, wait_thr|
92
-
93
- [out, err].each do |stream|
94
- Thread.new do
95
- until (line = stream.gets).nil? do
96
- puts line
97
- end
98
- end
99
- end
100
-
101
- wait_thr.join
102
- status = wait_thr.value.exitstatus
103
- end
104
-
105
- if status != 0
106
- puts "Compilation failed: #{status}"
107
- exit status
108
- end
109
- end
110
-
111
- def update_plist
112
- puts "Updating plist..."
113
-
114
- ip = Socket.ip_address_list.find {|a| a.ipv4? && !a.ipv4_loopback?}.ip_address
115
- port = 4567 #sinatras default port
116
-
117
- plist_file = CFPropertyList::List.new(:file => plist_path)
118
- plist = CFPropertyList.native_types(plist_file.value)
119
-
120
- plist["url_preference"] = ip
121
- plist["port_preference"] = port
122
-
123
- puts("plist: #{plist}")
124
-
125
- plist_file.value = CFPropertyList.guess(plist)
126
- plist_file.save(plist_path, CFPropertyList::List::FORMAT_XML)
127
-
128
- end
129
-
130
- def delete_simulator_plist
131
- puts "Deleting simulator plist..."
132
- # Delete last known simulator preference to prevent running in the wrong simulator
133
- FileUtils.rm(simulator_plist_path, :force => true)
134
- end
135
-
136
- def run_cucumber
137
- puts "Running cucumber..."
138
-
139
- # Which iOS simulator to run if specified else uses default for the platform
140
- os_params = ""
141
- if(@options[:ios])
142
- os = @options[:ios]
143
- os_params = " OS=ios#{os.to_i} SDK_VERSION=#{os}"
144
- end
145
-
146
- optional_params = ""
147
- if(@options[:out] && @options[:format])
148
- optional_params = " --format #{@options[:format]} --out #{@options[:out]} "
149
- end
150
-
151
- if(@options[:tags])
152
- @options[:tags].each do |tag_set|
153
- optional_params += " --tags #{tag_set}"
154
- end
155
- end
156
-
157
- cucumber_command = "cucumber"
158
- cucumber_command += os_params
159
- cucumber_command += " DEVICE_TARGET=simulator"
160
- cucumber_command += optional_params
161
-
162
- puts("#{cucumber_command}")
163
-
164
- status = nil
165
- Open3.popen3 cucumber_command do |stdin, out, err, wait_thr|
166
-
167
- [out, err].each do |stream|
168
- Thread.new do
169
- until (line = stream.gets).nil? do
170
- puts line
171
- end
172
- end
173
- end
174
-
175
- wait_thr.join
176
- status = wait_thr.value.exitstatus
177
- end
178
-
179
- if status != 0
180
- puts "Cucumber failed: #{status}"
181
- end
182
-
183
- # exit with whatever status Cucumber has exited
184
- exit status
185
- end
186
-
187
- def app_path
188
- files = []
189
-
190
- Find.find("#{File.expand_path('~')}/Library/Developer/Xcode/DerivedData/") do |path|
191
- files << path if path =~ /#{@options[:scheme]}.app$/
192
- end
193
-
194
- app_path = files.sort_by { |filename| File.mtime(filename)}.last # get the latest
195
-
196
- return app_path
197
- end
198
-
199
- def plist_path
200
-
201
- plist_path = app_path + "/server_config.plist"
202
- return plist_path
203
- end
204
-
205
- def simulator_plist_path
206
- return "#{File.expand_path('~')}/Library/Preferences/com.apple.iphonesimulator.plist"
207
- end
208
- end
209
- end
8
+ require 'socket'
210
9
 
10
+ require 'calasmash/command'
11
+ require 'calasmash/compiler'
12
+ require 'calasmash/plist'
13
+ require 'calasmash/cucumber'
211
14
 
15
+ module Calasmash
16
+ PORT = 4567
17
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe Calasmash::Command do
4
+
5
+ describe "when executing" do
6
+
7
+ before(:each) do
8
+ Calasmash::Command.stub(:compile)
9
+ Calasmash::Command.stub(:parse){nil}
10
+ end
11
+
12
+ it "should output the overview if missing args" do
13
+ Calasmash::Command.should_receive(:overview)
14
+ Calasmash::Command.execute
15
+ end
16
+ end
17
+
18
+ describe "when starting a compile" do
19
+
20
+ before(:each) do
21
+ @mock = double(Calasmash::Compiler)
22
+ @mock.stub(:compile)
23
+ Calasmash::Compiler.stub(:new){@mock}
24
+ end
25
+
26
+ it "should set the compilers scheme" do
27
+ Calasmash::Compiler.should_receive(:new).with("scheme")
28
+ Calasmash::Command.compile("scheme")
29
+ end
30
+
31
+ it "should start compiling" do
32
+ @mock.should_receive(:compile)
33
+ Calasmash::Command.compile("scheme")
34
+ end
35
+ end
36
+
37
+ describe "when updating the plist" do
38
+
39
+ before(:each ) do
40
+ @mock = double(Calasmash::Plist)
41
+ @mock.stub(:execute)
42
+ Calasmash::Plist.stub(:new){@mock}
43
+ end
44
+
45
+ it "should set the plists scheme" do
46
+ Calasmash::Plist.should_receive(:new).with("scheme")
47
+ Calasmash::Command.update_plist("scheme")
48
+ end
49
+
50
+ it "should execute the plist update" do
51
+ @mock.should_receive(:execute)
52
+ Calasmash::Command.update_plist("scheme")
53
+ end
54
+
55
+ describe "when running the cucumber tests" do
56
+
57
+ before(:each ) do
58
+ @mock = double(Calasmash::Cucumber)
59
+ @mock.stub(:test)
60
+ Calasmash::Cucumber.stub(:new){@mock}
61
+ end
62
+
63
+ it "should set the cucumber ios version" do
64
+ Calasmash::Cucumber.should_receive(:new).with("ios", anything)
65
+ Calasmash::Command.run_tests("ios", "tags")
66
+ end
67
+
68
+ it "should set the cucumber tags" do
69
+ Calasmash::Cucumber.should_receive(:new).with(anything, "tags")
70
+ Calasmash::Command.run_tests("ios", "tags")
71
+ end
72
+
73
+ it "should set the format" do
74
+ @cucumber = Calasmash::Cucumber.new
75
+ Calasmash::Cucumber.stub(:new){@cucumber}
76
+
77
+ @cucumber.should_receive(:format=)
78
+ Calasmash::Command.run_tests(nil, nil, "format")
79
+ end
80
+
81
+ it "should set the output" do
82
+ @cucumber = Calasmash::Cucumber.new
83
+ Calasmash::Cucumber.stub(:new){@cucumber}
84
+
85
+ @cucumber.should_receive(:output=)
86
+ Calasmash::Command.run_tests(nil, nil, nil, "output")
87
+ end
88
+
89
+ it "should start the tests" do
90
+ @mock.should_receive(:test)
91
+ Calasmash::Command.run_tests("ios", "tags")
92
+ end
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Calasmash::Compiler do
4
+
5
+ before(:each) do
6
+ Calasmash::Compiler.any_instance.stub(:puts)
7
+ end
8
+
9
+ it "should have a scheme instance" do
10
+ compiler = Calasmash::Compiler.new("scheme")
11
+ compiler.scheme.should match("scheme")
12
+ end
13
+
14
+ describe "when generating the command" do
15
+
16
+ before(:each) do
17
+ Calasmash::Compiler.any_instance.stub(:workspace)
18
+ @compiler = Calasmash::Compiler.new("test-scheme")
19
+ end
20
+
21
+ it "should contain the scheme" do
22
+ @compiler.instance_eval{command}.should match(/test-scheme/)
23
+ end
24
+ end
25
+
26
+ describe "when getting the workspacae" do
27
+
28
+ before(:each) do
29
+ @compiler = Calasmash::Compiler.new(nil)
30
+ Dir.stub(:[]){["workspace-file"]}
31
+ end
32
+
33
+ it "should get the workspace from the current directory" do
34
+ @compiler.instance_eval{workspace}.should match(/workspace-file/)
35
+ end
36
+ end
37
+
38
+ describe "when compiling" do
39
+
40
+ before(:each) do
41
+ wait = double
42
+ @value = double
43
+ wait.stub(:value){@value}
44
+ wait.stub(:join)
45
+ Open3.stub(:popen3).and_yield(nil, nil, nil, wait)
46
+
47
+ @compiler = Calasmash::Compiler.new(nil)
48
+ end
49
+
50
+ it "should exit if something goes bad" do
51
+ @value.stub(:exitstatus){1}
52
+ lambda { @compiler.compile }.should raise_error SystemExit
53
+ end
54
+
55
+ it "should complete if all is well" do
56
+ @value.stub(:exitstatus){0}
57
+ @compiler.compile do |complete|
58
+ complete.should equal(true)
59
+ end
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe Calasmash::Cucumber do
4
+
5
+ before(:each) do
6
+ Calasmash::Cucumber.any_instance.stub(:puts)
7
+ end
8
+
9
+ describe "when running the tests" do
10
+
11
+ before(:each) do
12
+ wait = double
13
+ @value = double
14
+ wait.stub(:value){@value}
15
+ wait.stub(:join)
16
+ Open3.stub(:popen3).and_yield(nil, nil, nil, wait)
17
+
18
+ @cucumber = Calasmash::Cucumber.new(nil, nil)
19
+ @cucumber.stub(:command)
20
+ end
21
+
22
+ it "should exit if something goes bad" do
23
+ @value.stub(:exitstatus){1}
24
+ lambda { @cucumber.test }.should raise_error SystemExit
25
+ end
26
+
27
+ it "should complete if all is well" do
28
+ @value.stub(:exitstatus){0}
29
+ @cucumber.should_receive(:completed)
30
+ @cucumber.test
31
+ end
32
+ end
33
+
34
+ describe "when generating the command" do
35
+
36
+ it "should add the ios version" do
37
+ @cucumber = Calasmash::Cucumber.new("1.0", nil)
38
+ @cucumber.stub(:tag_arguments)
39
+
40
+ @cucumber.instance_eval{command}.should match(/OS=ios1 SDK_VERSION=1.0/)
41
+ end
42
+
43
+ it "should not add the ios version if missing" do
44
+ @cucumber = Calasmash::Cucumber.new(nil, nil)
45
+ @cucumber.stub(:tag_arguments)
46
+
47
+ @cucumber.instance_eval{command}.should_not match(/OS/)
48
+ @cucumber.instance_eval{command}.should_not match(/SDK_VERSION/)
49
+ end
50
+
51
+ it "should add the format" do
52
+ @cucumber = Calasmash::Cucumber.new(nil, nil)
53
+ @cucumber.format = "test-format"
54
+
55
+ @cucumber.instance_eval{command}.should match(/--format test-format/)
56
+ end
57
+
58
+ it "should not add the format if missing" do
59
+ @cucumber = Calasmash::Cucumber.new(nil, nil)
60
+
61
+ @cucumber.instance_eval{command}.should_not match(/--format/)
62
+ end
63
+
64
+ it "should add the output" do
65
+ @cucumber = Calasmash::Cucumber.new(nil, nil)
66
+ @cucumber.output = "test-output"
67
+
68
+ @cucumber.instance_eval{command}.should match(/--out test-output/)
69
+ end
70
+
71
+ it "should not add the output if missing" do
72
+ @cucumber = Calasmash::Cucumber.new(nil, nil)
73
+
74
+ @cucumber.instance_eval{command}.should_not match(/--out/)
75
+ end
76
+
77
+ it "should add the tags" do
78
+ @cucumber = Calasmash::Cucumber.new(nil, ["tag1", "tag2"])
79
+ @cucumber.instance_eval{command}.should match(/--tags tag1 --tags tag2/)
80
+ end
81
+
82
+ it "should not add tags if missing" do
83
+ @cucumber = Calasmash::Cucumber.new(nil, nil)
84
+ @cucumber.instance_eval{command}.should_not match(/--tags/)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe Calasmash::Plist do
4
+
5
+ describe "when executed" do
6
+
7
+ before(:each) do
8
+ @plist = Calasmash::Plist.new("scheme")
9
+ @plist.stub(:update)
10
+ @plist.stub(:clear)
11
+ @plist.stub(:completed)
12
+ @plist.stub(:started)
13
+ end
14
+
15
+ it "should update" do
16
+ @plist.should_receive(:update)
17
+ @plist.execute
18
+ end
19
+
20
+ it "should clear" do
21
+ @plist.should_receive(:clear)
22
+ @plist.execute
23
+ end
24
+ end
25
+
26
+ describe "when clearing" do
27
+
28
+ before(:each) do
29
+ @plist = Calasmash::Plist.new("scheme")
30
+ @plist.stub(:update)
31
+ @plist.stub(:completed)
32
+ @plist.stub(:started)
33
+ end
34
+
35
+ it "should delete the simulator plist" do
36
+ @plist.stub(:simulator_plist_path){"plist_path"}
37
+ FileUtils.should_receive(:rm).with("plist_path", anything)
38
+ @plist.execute
39
+ end
40
+ end
41
+
42
+ describe "when updating" do
43
+
44
+ before(:each) do
45
+ @cfplist = double(CFPropertyList::List)
46
+ @cfplist.stub(:value)
47
+ @cfplist.stub(:value=)
48
+ @cfplist.stub(:save)
49
+ CFPropertyList::List.stub(:new){@cfplist}
50
+ CFPropertyList.stub(:native_types){@cfplist}
51
+ CFPropertyList.stub(:guess)
52
+
53
+ @plist = Calasmash::Plist.new("scheme")
54
+ @plist.stub(:clear)
55
+ @plist.stub(:completed)
56
+ @plist.stub(:started)
57
+ @plist.stub(:app_path){"app_path"}
58
+ end
59
+
60
+ it "should set the server ip and port" do
61
+ @plist.stub(:server_ip){"server_ip"}
62
+ stub_const("Calasmash::PORT", 123)
63
+
64
+ @cfplist.should_receive(:[]=).with("url_preference", "server_ip")
65
+ @cfplist.should_receive(:[]=).with("port_preference", 123)
66
+
67
+ @plist.execute
68
+ end
69
+
70
+ it "should write the app server plist" do
71
+ @cfplist.should_receive(:save).with("app_path/server_config.plist", anything)
72
+ @cfplist.stub(:[]=)
73
+
74
+ @plist.execute
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1 @@
1
+ require "calasmash"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calasmash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-10 00:00:00.000000000 Z
12
+ date: 2013-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -43,6 +43,38 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: guard-rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
46
78
  - !ruby/object:Gem::Dependency
47
79
  name: CFPropertyList
48
80
  requirement: !ruby/object:Gem::Requirement
@@ -68,8 +100,10 @@ extensions: []
68
100
  extra_rdoc_files: []
69
101
  files:
70
102
  - .gitignore
103
+ - .travis.yml
71
104
  - Gemfile
72
105
  - Gemfile.lock
106
+ - Guardfile
73
107
  - LICENSE
74
108
  - LICENSE.txt
75
109
  - README.md
@@ -77,7 +111,15 @@ files:
77
111
  - bin/calasmash
78
112
  - calasmash.gemspec
79
113
  - lib/calasmash.rb
80
- - lib/calasmash/version.rb
114
+ - lib/calasmash/command.rb
115
+ - lib/calasmash/compiler.rb
116
+ - lib/calasmash/cucumber.rb
117
+ - lib/calasmash/plist.rb
118
+ - spec/command_spec.rb
119
+ - spec/compiler_spec.rb
120
+ - spec/cucumber_spec.rb
121
+ - spec/plist_spec.rb
122
+ - spec/spec_helper.rb
81
123
  homepage: ''
82
124
  licenses:
83
125
  - MIT
@@ -99,10 +141,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
141
  version: '0'
100
142
  requirements: []
101
143
  rubyforge_project:
102
- rubygems_version: 1.8.24
144
+ rubygems_version: 1.8.23
103
145
  signing_key:
104
146
  specification_version: 3
105
- summary: Compile an app, run sinatra, point the app at sinatra, run the app tests
106
- with calabash
107
- test_files: []
108
- has_rdoc:
147
+ summary: Compile an app, point the app at sinatra, run cucumber
148
+ test_files:
149
+ - spec/command_spec.rb
150
+ - spec/compiler_spec.rb
151
+ - spec/cucumber_spec.rb
152
+ - spec/plist_spec.rb
153
+ - spec/spec_helper.rb
@@ -1,3 +0,0 @@
1
- module Calasmash
2
- VERSION = "0.0.10"
3
- end