[test] rake spec:all now runs on all installed iOS and OS X sdks.

This commit is contained in:
Eloy Durán
2014-04-11 12:20:09 +02:00
parent f3f98218b9
commit 87ea27d251
12 changed files with 147 additions and 87 deletions

View File

@@ -25,6 +25,7 @@ module Motion; module Util
# https://github.com/rubygems/rubygems/blob/81d806d818baeb5dcb6398ca631d772a003d078e/lib/rubygems/version.rb
#
def <=>(other)
other = Version.new(other) if String === other
return unless Version === other
return 0 if @version == other.to_s

View File

@@ -1,5 +1,18 @@
# Adapted from https://github.com/irrationalfab/PrettyBacon
BITS = RUBY_ARCH.include?('64') ? 64 : 32
if defined?(UIView)
IOS_VERSION = Motion::Util::Version.new(ENV['deployment_target'])
OSX_VERSION = nil
elsif defined?(NSView)
IOS_VERSION = nil
OSX_VERSION = Motion::Util::Version.new(ENV['deployment_target'])
end
unless IOS_VERSION || OSX_VERSION
NSLog("ERROR: Unable to determin iOS and OS X deployment target version!")
exit(1)
end
# Adapted from https://github.com/irrationalfab/PrettyBacon
module PrettyBacon
def self.color(color, string)
case color
@@ -32,9 +45,39 @@ module Bacon
end
end
alias_method :on_64bit_it, RUBY_ARCH =~ /64/ ? :it : :xit
alias_method :__it_before_conditionally, :it
alias_method :on_ios_it, defined?(UIView) ? :it : :xit
def it(*args, &block)
if args.last.is_a?(Hash)
options = args.pop
if options.has_key?(:if) && !options[:if]
return xit(*args, &block)
else options.has_key?(:unless) && options[:unless]
return xit(*args, &block)
end
end
__it_before_conditionally(*args, &block)
end
def bits
BITS
end
def sdk_version
IOS_VERSION || OSX_VERSION
end
def ios?
!IOS_VERSION.nil?
end
def osx?
!OSX_VERSION.nil?
end
def osx_32bit?
osx? && bits == 32
end
def capture_warning
$last_rb_warn = nil

View File

@@ -10,7 +10,7 @@ Motion::Project::App.setup do |app|
app.frameworks += ['AddressBook', 'AddressBookUI', 'AudioToolbox', 'AVFoundation', 'CoreData', 'CoreMIDI', 'GameKit']
app.vendor_project('vendor/code', :static)
app.spec_files.insert(1, *FileList['../helpers/*.rb'])
app.spec_files.insert(1, *FileList['../../lib/motion/util/version.rb', '../helpers/*.rb'])
app.deployment_target = ENV['deployment_target'] if ENV['deployment_target']
app.archs[app.local_platform] = [ENV['ARCH']] if ENV['ARCH']
@@ -57,8 +57,6 @@ if OSX_SDK_VERSIONS.empty?
end
namespace :spec do
task :clean_run => [:clean, :spec]
test_fail_count = []
task :install_aggregate_test_handler do
@@ -104,7 +102,7 @@ namespace :spec do
task bit => :install_aggregate_test_handler do
App.info "TESTING", "Running test suite on the #{platform} #{sdk_version} SDK with arch #{bit}-bit"
begin
sh "env PLATFORM=#{platform} ARCH=#{arch} deployment_target=#{sdk_version} rake spec:clean_run"
sh "env PLATFORM=#{platform} ARCH=#{arch} deployment_target=#{sdk_version} rake #{'clean' unless ENV['clean'] == '0'} spec"
rescue RuntimeError
test_fail_count << $?.exitstatus
end
@@ -121,13 +119,6 @@ namespace :spec do
desc "Run tests on all available SDKs and archs"
task :all => variant_tasks
known_to_fail = [
'osx:10.6:32', 'osx:10.6:64',
]
desc "Run tests that should pass on continuous integration"
task :ci => variant_tasks - known_to_fail
end
# TODO enable this once full test suite works on OS X.

View File

@@ -1,5 +1,5 @@
describe "iOS constants" do
on_ios_it "have their values retrieved at demand" do
it "have their values retrieved at demand", :if => ios? do
ABAddressBookCreate()
KABPersonFirstNameProperty.should != KABPersonLastNameProperty
end

View File

@@ -1,32 +1,36 @@
begin
ThisConstDoesSoNotExist
rescue Object => e
$file_scope_exception = e
end
class TestClassScopeExceptions
def self.foo(arg1, arg2)
# TODO exceptions on the file scope cannot be handled in OSX 10.6
osx_32bit = OSX_VERSION && BITS == 32
unless osx_32bit
begin
ThisConstDoesSoNotExist
rescue Object => e
$file_scope_exception = e
end
begin
foo(:too_few_args)
rescue Object => e
$class_scope_exception = e
class TestClassScopeExceptions
def self.foo(arg1, arg2)
end
begin
foo(:too_few_args)
rescue Object => e
$class_scope_exception = e
end
end
end
describe "An exception" do
it "includes backtrace info when raised from a file scope" do
it "includes backtrace info when raised from a file scope", :unless => osx_32bit do
$file_scope_exception.backtrace.first.should.match /exception_spec\.rb:2/
end
it "includes backtrace info when raised from a class scope" do
it "includes backtrace info when raised from a class scope", :unless => osx_32bit do
$class_scope_exception.backtrace.first.should.match /exception_spec\.rb:12/
end
end
describe "NSExceptions" do
it "can be caught (1)" do
it "can be caught (1)", :unless => osx_32bit do
exc_name = 'TestException'
exc_reason = 'some reason'
exc_userInfo = { 'One' => 1, 'Two' => 2, 'Three' => 3}
@@ -39,7 +43,7 @@ describe "NSExceptions" do
end
end
it "can be caught (2)" do
it "can be caught (2)", :unless => osx_32bit do
begin
NSString.stringWithString(42)
rescue => e
@@ -48,7 +52,7 @@ describe "NSExceptions" do
end
end
it "should be raised with Kernel.raise" do
it "should be raised with Kernel.raise", :unless => osx_32bit do
begin
raise NSException.exceptionWithName('NSInvalidArgumentException', reason:'Woops!', userInfo:nil)
rescue => e

View File

@@ -4,21 +4,28 @@ describe "Float" do
1234567890.to_f.to_i.should == 1234567890
end
it "Time.now and NSDate" do
# issue 275
start = Time.now.to_f
sleep 0.2
(NSDate.date.timeIntervalSince1970 - start).should != 0
describe "when dealing with Time/NSDate" do
it "is not equal after some time has passed" do
# https://hipbyte.freshdesk.com/helpdesk/tickets/275
start = Time.now.to_f
sleep 0.2
(NSDate.date.timeIntervalSince1970 - start).should != 0
end
# issue 188
date = NSDate.alloc.initWithString("2013-01-01 23:59:59 +000")
date.timeIntervalSince1970.to_f.should == date.to_f
NSDate.dateWithTimeIntervalSince1970(date.timeIntervalSince1970).should == date
# TODO
it "is equal to a date parsed in Objective-C", :unless => bits == 64 do
# https://hipbyte.freshdesk.com/helpdesk/tickets/188
date = NSDate.alloc.initWithString("2013-01-01 23:59:59 +000")
date.timeIntervalSince1970.to_f.should == date.to_f
NSDate.dateWithTimeIntervalSince1970(date.timeIntervalSince1970).should == date
end
# issue 193
t1 = NSDate.dateWithNaturalLanguageString("midnight")
t2 = Time.dateWithNaturalLanguageString("midnight")
t1.to_f.should == t2.to_f
it "is equal when using NSDate or inherited API on Time" do
# https://hipbyte.freshdesk.com/helpdesk/tickets/193
t1 = NSDate.dateWithNaturalLanguageString("midnight")
t2 = Time.dateWithNaturalLanguageString("midnight")
t1.to_f.should == t2.to_f
end
end
it "/" do
@@ -41,7 +48,8 @@ describe "Float" do
-73.98158.round(5).to_s.should == "-73.98158"
end
it "::MAX constant" do
# TODO
it "::MAX constant", :unless => bits == 64 do
# RM-34
Float::MAX.__fixfloat__?.should == false
Float::MAX.should != Float::INFINITY
@@ -80,7 +88,8 @@ describe "Float" do
end
end
it "Heap Overflow in Floating Point Parsing" do
# TODO
it "Heap Overflow in Floating Point Parsing", :unless => bits == 64 do
# https://www.ruby-lang.org/en/news/2013/11/22/heap-overflow-in-floating-point-parsing-cve-2013-4164/
(("1."+"1"*300000).to_f * 9).should == 10.0
end

View File

@@ -1,27 +1,27 @@
# Tagged pointers are only available on 64-bit platforms.
describe "ImmediateRef" do
on_64bit_it "forwards messages to the wrapped tagged pointer object" do
it "forwards messages to the wrapped tagged pointer object", :unless => bits == 64 do
ref = NSIndexPath.indexPathWithIndex(42)
ref.indexAtPosition(0).should == 42
ref.should == NSIndexPath.indexPathWithIndex(42)
end
on_64bit_it "returns the tagged pointer object's class" do
it "returns the tagged pointer object's class", :unless => bits == 64 do
ref = NSIndexPath.indexPathWithIndex(42)
ref.class.should == NSIndexPath
end
on_64bit_it "returns the tagged pointer object's methods" do
it "returns the tagged pointer object's methods", :unless => bits == 64 do
ref = NSIndexPath.indexPathWithIndex(42)
ref.methods(false).should == NSIndexPath.public_instance_methods(false)
end
on_64bit_it "returns the tagged pointer object's description" do
it "returns the tagged pointer object's description", :unless => bits == 64 do
ref = NSIndexPath.indexPathWithIndex(42)
ref.inspect.should.match /#<ImmediateRef:0x\h+ <NSIndexPath: 0x\h+> \{length = 1, path = 42\}>/
end
on_64bit_it "stays an ImmediateRef when calling a Ruby method on it" do
it "stays an ImmediateRef when calling a Ruby method on it", :unless => bits == 64 do
class NSIndexPath
def ruby_instance_method
self
@@ -31,7 +31,7 @@ describe "ImmediateRef" do
ref.ruby_instance_method.should.eql ref
end
on_64bit_it "is able to dispatch methods to itself" do
it "is able to dispatch methods to itself", :unless => bits == 64 do
class NSIndexPath
def ruby_instance_method
self.indexAtPosition(0)

View File

@@ -8,15 +8,25 @@ class MyTestMethod < TestMethod
end
describe 'A method accepting a 32-bit struct' do
it "can be called" do
# TODO
it "can be called", :unless => bits == 64 do
s = MyStruct4C.new(1, 2, 3, 4)
TestMethod.testMethodAcceptingMyStruct4C(s).should == true
TestMethod.testMethodAcceptingMyStruct4C(s, another:s).should == true
end
end
describe "A method returning a big 32-bit integer" do
it "returns a Bignum", :unless => bits == 64 do
o = TestMethod.new.methodReturningLargeInt
o.class.should == Bignum
o.should == 2147483646
end
end
describe 'A method returning a 64-bit struct' do
it "can be called" do
# TODO
it "can be called", :unless => osx_32bit? do
o = TestMethod.new
o.methodReturningCGSize.should == CGSize.new(1, 2)
end
@@ -28,7 +38,8 @@ describe 'A method returning a 64-bit struct' do
end
describe 'A method returning a 128-bit struct' do
it "can be called" do
# TODO
it "can be called", :unless => osx_32bit? do
o = TestMethod.new
o.methodReturningCGRect.should == CGRect.new(CGPoint.new(1, 2), CGSize.new(3, 4))
end
@@ -40,14 +51,14 @@ describe 'A method returning a 128-bit struct' do
end
describe 'A 3rd-party method accepting an iOS enum' do
on_ios_it "can be called" do
it "can be called", :if => ios? do
TestMethod.testMethodAcceptingUIInterfaceOrientation(UIInterfaceOrientationPortrait).should == true
TestMethod.testMethodAcceptingUIInterfaceOrientation(UIInterfaceOrientationLandscapeLeft).should == false
end
end
describe 'A method accepting and returning UIEdgeInsets' do
on_ios_it "can be called" do
it "can be called", :if => ios? do
s = UIEdgeInsetsMake(1, 2, 3, 4)
TestMethod.testMethodAcceptingUIEdgeInsets(s).should == true
end
@@ -81,7 +92,7 @@ describe 'A method accepting a CF type' do
TestMethod.testMethodAcceptingCFType('foo').should == true
end
on_ios_it "can be called (2)" do
it "can be called (2)", :if => ios? do
controller = ABPersonViewController.alloc.init
person = ABPersonCreate()
controller.displayedPerson = person
@@ -136,14 +147,6 @@ describe "attr_" do
end
end
describe "A method returning a big 32-bit integer" do
it "returns a Bignum" do
o = TestMethod.new.methodReturningLargeInt
o.class.should == Bignum
o.should == 2147483646
end
end
class TestNewInstance
end
@@ -161,7 +164,8 @@ class TestPrivateMethod
end
describe "A private method" do
it "cannot be called with #public_send" do
# TODO
it "cannot be called with #public_send", :unless => osx_32bit? do
o = TestPrivateMethod.new
o.foo.should == 42
o.send(:foo).should == 42
@@ -182,7 +186,7 @@ describe "An informal protocol method with BOOL types" do
end
# TODO Do we know of a Foundation version that works on OS X as well?
on_ios_it "can be called (1)" do
it "can be called (1)", :if => ios? do
o = UITextField.new
o.enablesReturnKeyAutomatically = true
o.enablesReturnKeyAutomatically.should == true

View File

@@ -226,7 +226,8 @@ class Proc
end
describe "C functions that return retained objects" do
it "returns an autoreleased object if the function name contains 'Create'" do
# TODO
it "returns an autoreleased object if the function name contains 'Create'", :unless => osx_32bit? do
lambda {
CFStringCreateWithFormat(nil, {}, '%@', 42)
}.should.be.autoreleased

View File

@@ -11,11 +11,13 @@ describe "Objective-C setter" do
end
describe "Objective-C predicate" do
it "is available in its Ruby `#predicate?` form" do
# TODO
it "is available in its Ruby `#predicate?` form", :unless => osx_32bit? do
TestSpecialSelectors.new.should.respond_to :predicate?
end
it "is callable in its Ruby `#predicate?` form" do
# TODO
it "is callable in its Ruby `#predicate?` form", :unless => osx_32bit? do
obj = TestSpecialSelectors.new
obj.aSetter = 42
obj.predicate?(42).should == true
@@ -23,24 +25,28 @@ describe "Objective-C predicate" do
end
describe "Objective-C subscripting" do
it "is available in its Ruby `#[]` getter form" do
# TODO
it "is available in its Ruby `#[]` getter form", :unless => osx_32bit? do
obj = TestSpecialSelectors.new
obj.should.respond_to :[]
end
it "is available in its Ruby `#[]=` setter form" do
# TODO
it "is available in its Ruby `#[]=` setter form", :unless => osx_32bit? do
obj = TestSpecialSelectors.new
obj.should.respond_to :[]=
end
it "works with indexed-subscripting" do
# TODO
it "works with indexed-subscripting", :unless => osx_32bit? do
obj = TestSpecialSelectors.new
o = obj[0] = 42
obj[0].should == 42
o.should == 42
end
it "works with keyed-subscripting" do
# TODO
it "works with keyed-subscripting", :unless => osx_32bit? do
obj = TestSpecialSelectors.new
o = obj['a'] = 'foo'
obj['a'].should == 'foo'

View File

@@ -36,7 +36,8 @@ describe "Strings with multibyte characters" do
"..€€……".index("").should == 4
end
it "finds the most right-side index of a character" do
# TODO
it "finds the most right-side index of a character", :unless => osx_32bit? do
"..€€……".rindex(".").should == 1
"..€€……".rindex("").should == 3
"..€€……".rindex("").should == 5

View File

@@ -55,7 +55,8 @@ describe "WeakRef" do
WeakRef.new(Object.new).respond_to?(:weakref_alive?).should == true
end
it "returns whether or not the reference is still alive" do
# Unsupported on older OS versions.
it "returns whether or not the reference is still alive", :if => ((osx? && sdk_version >= '10.7') || (ios? && sdk_version >= '5.0')) do
autorelease_pool do
@ref = WeakRef.new(Object.new)
@ref.weakref_alive?.should == true
@@ -65,7 +66,8 @@ describe "WeakRef" do
end
end
it "raises a WeakRef::RefError if messaged when the reference is no longer alive" do
# TODO leads to segfault on OS X 10.6 64-bit
it "raises a WeakRef::RefError if messaged when the reference is no longer alive", :unless => (osx? && sdk_version == '10.6' && bits == 64) do
autorelease_pool do
@ref = WeakRef.new(Object.new)
lambda { @ref.to_s }.should.not.raise
@@ -108,21 +110,19 @@ describe "WeakRef" do
WeakRef.new(false).should == false
end
# TODO what's the good way to determine if we're running on 10.7?
unless defined?(NSView) && ENV['deployment_target'] == '10.7'
it "allows weak references to AVFoundation classes" do
lambda { WeakRef.new(AVPlayer.new) }.should.not.raise
end
# On 10.7 this should raise
it "allows weak references to AVFoundation classes", :unless => osx? && sdk_version == '10.7' do
lambda { WeakRef.new(AVPlayer.new) }.should.not.raise
end
it "raises with classes that do not support weak references" do
it "raises with classes that do not support weak references", :unless => osx_32bit? && sdk_version == '10.6' do
# iOS and OS X classes, regardless of SDK version
classes = [
NSParagraphStyle,
NSMutableParagraphStyle,
]
# OSX only classes
if defined?(NSView)
if osx?
unless defined?(NSMenuView)
class NSMenuView; end
end
@@ -134,7 +134,7 @@ describe "WeakRef" do
NSTextView,
])
# In addition, the following classes don't allow weak references on 10.7
if ENV['deployment_target'] == '10.7'
if OSX_VERSION == '10.7'
classes.concat([
AVPlayer,
NSFontManager,