mirror of
https://github.com/zhigang1992/RubyMotion.git
synced 2026-04-21 02:50:14 +08:00
add test suite (rudimentary)
This commit is contained in:
3
test/.gitignore
vendored
Normal file
3
test/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.repl_history
|
||||
build
|
||||
resources/*.nib
|
||||
10
test/Rakefile
Normal file
10
test/Rakefile
Normal file
@@ -0,0 +1,10 @@
|
||||
$:.unshift("../lib")
|
||||
#$:.unshift("/Library/RubyMotion/lib")
|
||||
require 'motion/project'
|
||||
|
||||
Motion::Project::App.setup do |app|
|
||||
# Use `rake config' to see complete project settings.
|
||||
app.name = 'test'
|
||||
app.frameworks += ['AddressBook', 'AddressBookUI', 'CoreData', 'CoreMIDI', 'GameKit']
|
||||
app.vendor_project('vendor/code', :static)
|
||||
end
|
||||
5
test/app/app_delegate.rb
Normal file
5
test/app/app_delegate.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AppDelegate
|
||||
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
||||
true
|
||||
end
|
||||
end
|
||||
25
test/spec/archiver_spec.rb
Normal file
25
test/spec/archiver_spec.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
class TestArchiver
|
||||
attr_accessor :name
|
||||
|
||||
def encodeWithCoder(encoder)
|
||||
encoder.encodeObject(self.name, forKey: "name")
|
||||
end
|
||||
|
||||
def initWithCoder(decoder)
|
||||
if self.init
|
||||
self.name = decoder.decodeObjectForKey("name")
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
describe "NSKeyedArchiver" do
|
||||
it "works" do
|
||||
m = TestArchiver.new
|
||||
m.name = "test"
|
||||
|
||||
m2 = NSKeyedUnarchiver.unarchiveObjectWithData(NSKeyedArchiver.archivedDataWithRootObject(m))
|
||||
m2.class.should == TestArchiver
|
||||
m2.name.should == m.name
|
||||
end
|
||||
end
|
||||
22
test/spec/array_spec.rb
Normal file
22
test/spec/array_spec.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
describe "Array#delete_at" do
|
||||
it "does not prematurely release the removed object" do
|
||||
a = ['a', 'b', 'c']
|
||||
o = a[1]
|
||||
a.delete_at(1)
|
||||
o.should == 'b'
|
||||
a.should == ['a', 'c']
|
||||
a.insert(1, o)
|
||||
o.should == 'b'
|
||||
a.should == ['a', 'b', 'c']
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#shift" do
|
||||
it "should not prematurely release the removed object" do
|
||||
@a = nil
|
||||
RunloopYield.new do
|
||||
@a = ['a', 'b', 'c'].shift
|
||||
end
|
||||
@a.should == 'a'
|
||||
end
|
||||
end
|
||||
6
test/spec/const_spec.rb
Normal file
6
test/spec/const_spec.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
describe "iOS constants" do
|
||||
it "have their values retrieved at demand" do
|
||||
ABAddressBookCreate()
|
||||
KABPersonFirstNameProperty.should != KABPersonLastNameProperty
|
||||
end
|
||||
end
|
||||
6
test/spec/coredata_spec.rb
Normal file
6
test/spec/coredata_spec.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
#describe "NSMigrationManager" do
|
||||
# it "migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error:" do
|
||||
# mm = NSMigrationManager.new
|
||||
# mm.migrateStoreFromURL(nil, type:nil, options:nil, withMappingModel:nil, toDestinationURL:nil, destinationType:nil, destinationOptions:nil, error:nil)
|
||||
# end
|
||||
#end
|
||||
10
test/spec/coremidi_spec.rb
Normal file
10
test/spec/coremidi_spec.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
describe "CoreMidi" do
|
||||
it "can list devices" do
|
||||
n = MIDIGetNumberOfDevices()
|
||||
n.should > 0
|
||||
n.times do |i|
|
||||
device = MIDIGetDevice(i)
|
||||
device.class.should == MIDIDeviceRef
|
||||
end
|
||||
end
|
||||
end
|
||||
16
test/spec/exception_spec.rb
Normal file
16
test/spec/exception_spec.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
describe "NSExceptions" do
|
||||
it "can be catched" do
|
||||
exc_name = 'TestException'
|
||||
exc_reason = 'some reason'
|
||||
exc_userInfo = { 'One' => 1, 'Two' => 2, 'Three' => 3}
|
||||
begin
|
||||
NSException.exceptionWithName(exc_name, reason:exc_reason, userInfo:exc_userInfo).raise
|
||||
rescue => e
|
||||
nse = e.nsexception
|
||||
nse.should != nil
|
||||
nse.name.should == exc_name
|
||||
nse.reason.should == exc_reason
|
||||
nse.userInfo.should == exc_userInfo
|
||||
end
|
||||
end
|
||||
end
|
||||
5
test/spec/function_spec.rb
Normal file
5
test/spec/function_spec.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
#desc "An inline function" do
|
||||
# it "can be called" do
|
||||
# TestInlineFunction(1, 2, 3).should == 1 + 2 + 3
|
||||
# end
|
||||
#end
|
||||
8
test/spec/gcd_spec.rb
Normal file
8
test/spec/gcd_spec.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
=begin
|
||||
describe "Group#notify" do
|
||||
it "works" do
|
||||
group = Dispatch::Group.new
|
||||
group.notify (Dispatch::Queue.main) { p 42 }
|
||||
end
|
||||
end
|
||||
=end
|
||||
7
test/spec/hash_spec.rb
Normal file
7
test/spec/hash_spec.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
describe "Hash" do
|
||||
it 'can be created using []' do
|
||||
h = Hash[a: 'a', b: 'b']
|
||||
h[:a].should == 'a'
|
||||
h[:b].should == 'b'
|
||||
end
|
||||
end
|
||||
15
test/spec/helpers/runloop_yield.rb
Normal file
15
test/spec/helpers/runloop_yield.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class RunloopYield
|
||||
def initialize(&b)
|
||||
@b = b
|
||||
run
|
||||
end
|
||||
|
||||
def run
|
||||
performSelectorOnMainThread(:'test_start', withObject:nil, waitUntilDone:false)
|
||||
NSRunLoop.currentRunLoop.runUntilDate(NSDate.dateWithTimeIntervalSinceNow(0.1))
|
||||
end
|
||||
|
||||
def test_start
|
||||
@b.call
|
||||
end
|
||||
end
|
||||
75
test/spec/kvo_spec.rb
Normal file
75
test/spec/kvo_spec.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
class Observed1
|
||||
attr_accessor :name
|
||||
|
||||
def self.automaticallyNotifiesObserversForKey(theKey)
|
||||
automatic = false
|
||||
if (theKey == "name")
|
||||
automatic = false
|
||||
else
|
||||
automatic = super
|
||||
end
|
||||
automatic
|
||||
end
|
||||
|
||||
def name=(name)
|
||||
self.willChangeValueForKey("name")
|
||||
@name = name
|
||||
self.didChangeValueForKey("name")
|
||||
end
|
||||
end
|
||||
|
||||
class Observed2
|
||||
attr_accessor :name
|
||||
end
|
||||
|
||||
class Observer
|
||||
attr_reader :did_observe
|
||||
|
||||
def observe(observed)
|
||||
observed.addObserver(self, forKeyPath: "name", options: 0, context: nil)
|
||||
end
|
||||
|
||||
def unobserve(observed)
|
||||
observed.removeObserver(self, forKeyPath: "name")
|
||||
end
|
||||
|
||||
def observeValueForKeyPath(key_path, ofObject:object, change:change, context:context)
|
||||
@did_observe = true
|
||||
end
|
||||
end
|
||||
|
||||
describe "KVO" do
|
||||
it "works for objects that implement the KVO interface manually" do
|
||||
observed = Observed1.new
|
||||
observed.name = "first"
|
||||
|
||||
observer = Observer.new
|
||||
observer.observe(observed)
|
||||
|
||||
observed.name = "second"
|
||||
observer.did_observe.should == true
|
||||
observer.unobserve(observed)
|
||||
end
|
||||
|
||||
it "works for objects that use attr_accessor" do
|
||||
observed = Observed2.new
|
||||
observed.name = "first"
|
||||
|
||||
observer = Observer.new
|
||||
observer.observe(observed)
|
||||
|
||||
observed.name = "second"
|
||||
observer.did_observe.should == true
|
||||
observer.unobserve(observed)
|
||||
end
|
||||
end
|
||||
|
||||
describe "KVC" do
|
||||
it "works for objects that use attr_accessor" do
|
||||
x = Observed2.new
|
||||
x.name = 'foo'
|
||||
x.valueForKey('name').should == 'foo'
|
||||
x.setValue('bar', forKey:'name')
|
||||
x.name == 'bar'
|
||||
end
|
||||
end
|
||||
215
test/spec/main_spec.rb
Normal file
215
test/spec/main_spec.rb
Normal file
@@ -0,0 +1,215 @@
|
||||
class MyTestMethod < TestMethod
|
||||
def methodReturningCGSize
|
||||
super
|
||||
end
|
||||
def methodReturningCGRect
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
describe 'A method accepting a 32-bit struct' do
|
||||
it "can be called" 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 64-bit struct' do
|
||||
it "can be called" do
|
||||
o = TestMethod.new
|
||||
o.methodReturningCGSize.should == CGSize.new(1, 2)
|
||||
end
|
||||
|
||||
it "can be defined" do
|
||||
o = MyTestMethod.new
|
||||
TestMethod.testMethodReturningCGSize(o).should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'A method returning a 128-bit struct' do
|
||||
it "can be called" do
|
||||
o = TestMethod.new
|
||||
o.methodReturningCGRect.should == CGRect.new(CGPoint.new(1, 2), CGSize.new(3, 4))
|
||||
end
|
||||
|
||||
it "can be defined" do
|
||||
o = MyTestMethod.new
|
||||
TestMethod.testMethodReturningCGRect(o).should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'A 3rd-party method accepting an iOS enum' do
|
||||
it "can be called" do
|
||||
TestMethod.testMethodAcceptingUIInterfaceOrientation(UIInterfaceOrientationPortrait).should == true
|
||||
TestMethod.testMethodAcceptingUIInterfaceOrientation(UIInterfaceOrientationLandscapeLeft).should == false
|
||||
end
|
||||
end
|
||||
|
||||
describe 'A method accepting and returning UIEdgeInsets' do
|
||||
it "can be called" do
|
||||
s = UIEdgeInsetsMake(1, 2, 3, 4)
|
||||
TestMethod.testMethodAcceptingUIEdgeInsets(s).should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'A method accepting a block' do
|
||||
it "can be called (1)" do
|
||||
TestMethod.testMethodCallingBlock(lambda { 42 }).should == 42
|
||||
TestMethod.testMethodCallingBlock(nil).should == nil
|
||||
end
|
||||
|
||||
it "can be called (2)" do
|
||||
res = []
|
||||
[1, 2, 3, 4, 5].enumerateObjectsUsingBlock(lambda do |obj, idx, stop_ptr|
|
||||
res << [obj, idx]
|
||||
end)
|
||||
res.should == [[1,0], [2,1], [3,2], [4,3], [5,4]]
|
||||
res = []
|
||||
[1, 2, 3, 4, 5].enumerateObjectsUsingBlock(lambda do |obj, idx, stop_ptr|
|
||||
res << obj
|
||||
stop_ptr[0] = true if idx == 2
|
||||
end)
|
||||
res.should == [1, 2, 3]
|
||||
end
|
||||
end
|
||||
|
||||
describe 'A method accepting a CF type' do
|
||||
it "can be called (1)" do
|
||||
s = CFStringCreateCopy(nil, 'foo')
|
||||
TestMethod.testMethodAcceptingCFType(s).should == true
|
||||
TestMethod.testMethodAcceptingCFType('foo').should == true
|
||||
end
|
||||
|
||||
it "can be called (2)" do
|
||||
controller = ABPersonViewController.alloc.init
|
||||
person = ABPersonCreate()
|
||||
controller.displayedPerson = person
|
||||
controller.displayedPerson.should == person
|
||||
end
|
||||
end
|
||||
|
||||
describe 'A method returning a CF type' do
|
||||
it "can be called" do
|
||||
s = CFStringCreateCopy(nil, 'foo')
|
||||
s.should == 'foo'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'CFTypeRefs' do
|
||||
it "are mapped as 'id' types" do
|
||||
KSecAttrAccount.should == 'acct' # and not Pointer
|
||||
end
|
||||
end
|
||||
|
||||
describe 'RUBY_ENGINE' do
|
||||
it "should be 'rubymotion'" do
|
||||
RUBY_ENGINE.should == 'rubymotion'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Objects conforming to NSFastEnumeration" do
|
||||
it "can be iterated using #each" do
|
||||
iter = TestIterator.new
|
||||
enum = iter.to_enum
|
||||
enum.to_a.should == ['1', '2', '3', '4', '5']
|
||||
end
|
||||
end
|
||||
|
||||
class TestAttrAlias
|
||||
attr_accessor :foo
|
||||
alias :bar :foo
|
||||
end
|
||||
|
||||
describe "attr_" do
|
||||
it "can be aliased" do
|
||||
o = TestAttrAlias.new
|
||||
o.foo = 42
|
||||
o.bar.should == 42
|
||||
end
|
||||
|
||||
it "return proper values when used by valueForKey:" do
|
||||
o = TestAttrAlias.new
|
||||
TestMethod.testValueForKey(o, expected:nil).should == true
|
||||
o.foo = '42'
|
||||
TestMethod.testValueForKey(o, expected:'42').should == true
|
||||
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
|
||||
|
||||
describe "A method sending +new on a Ruby class" do
|
||||
it "returns an instance" do
|
||||
o = TestMethod.new.methodSendingNew(TestNewInstance)
|
||||
o.class.should == TestNewInstance
|
||||
end
|
||||
end
|
||||
|
||||
class TestPrivateMethod
|
||||
def foo; 42; end
|
||||
private
|
||||
def bar; 42; end
|
||||
end
|
||||
|
||||
describe "A private method" do
|
||||
it "cannot be called with #public_send" do
|
||||
o = TestPrivateMethod.new
|
||||
o.foo.should == 42
|
||||
o.send(:foo).should == 42
|
||||
o.public_send(:foo).should == 42
|
||||
lambda { o.bar }.should.raise(NoMethodError)
|
||||
o.send(:bar).should == 42
|
||||
lambda { o.public_send(:bar) }.should.raise(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "An informal protocol method with BOOL types" do
|
||||
it "can be called" do
|
||||
o = TestMethod.new
|
||||
o.testProtocolFlag = true
|
||||
o.testProtocolFlag.should == true
|
||||
o.testProtocolFlag = false
|
||||
o.testProtocolFlag.should == false
|
||||
o = UITextField.new
|
||||
o.enablesReturnKeyAutomatically = true
|
||||
o.enablesReturnKeyAutomatically.should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe "Constants starting with a lower-case character" do
|
||||
it "can be accessed by upper-casing the first letter" do
|
||||
LowerCaseConstant.should == 42
|
||||
end
|
||||
end
|
||||
|
||||
describe "Classes starting with a lower-case character" do
|
||||
it "can be accessed by upper-casing the first letter" do
|
||||
k = NSClassFromString('lowerCaseClass')
|
||||
k.should != nil
|
||||
LowerCaseClass.should == k
|
||||
end
|
||||
end
|
||||
|
||||
describe "Large unsigned ints (Bignum)" do
|
||||
it "can be passed as 'unsigned ints'" do
|
||||
NSNumber.numberWithUnsignedInt(4294967295).should == 4294967295
|
||||
end
|
||||
end
|
||||
|
||||
describe "Properties implemented using forwarders" do
|
||||
it "can be called" do
|
||||
player = GKLocalPlayer.localPlayer
|
||||
player.alias.should == nil
|
||||
player.alias = 'lol'
|
||||
player.alias.should == 'lol'
|
||||
end
|
||||
end
|
||||
189
test/spec/memory_spec.rb
Normal file
189
test/spec/memory_spec.rb
Normal file
@@ -0,0 +1,189 @@
|
||||
class BlockTestParam
|
||||
def dealloc
|
||||
$dealloc_test = true
|
||||
super
|
||||
end
|
||||
def res
|
||||
42
|
||||
end
|
||||
end
|
||||
|
||||
class BlockTest
|
||||
def test_sync
|
||||
o = BlockTestParam.new
|
||||
1.times do
|
||||
@res = o.res
|
||||
end
|
||||
end
|
||||
|
||||
def test_async
|
||||
o = BlockTestParam.new
|
||||
Dispatch::Queue.concurrent.async do
|
||||
@res = o.res
|
||||
end
|
||||
end
|
||||
def res
|
||||
@res
|
||||
end
|
||||
end
|
||||
|
||||
describe "&block dvars" do
|
||||
it "are properly retain/released (sync)" do
|
||||
$dealloc_test = false
|
||||
o = BlockTest.new
|
||||
o.performSelectorOnMainThread(:'test_sync', withObject:nil, waitUntilDone:false)
|
||||
NSRunLoop.currentRunLoop.runUntilDate(NSDate.dateWithTimeIntervalSinceNow(0.1))
|
||||
o.res.should == 42
|
||||
$dealloc_test.should == true
|
||||
end
|
||||
|
||||
it "are properly retain/released (async)" do
|
||||
$dealloc_test = false
|
||||
o = BlockTest.new
|
||||
o.performSelectorOnMainThread(:'test_async', withObject:nil, waitUntilDone:false)
|
||||
NSRunLoop.currentRunLoop.runUntilDate(NSDate.dateWithTimeIntervalSinceNow(0.1))
|
||||
o.res.should == 42
|
||||
$dealloc_test.should == true
|
||||
end
|
||||
end
|
||||
|
||||
class DeallocTest
|
||||
def self.test
|
||||
DeallocTest.new
|
||||
end
|
||||
def dealloc
|
||||
super
|
||||
$dealloc_test = true
|
||||
end
|
||||
end
|
||||
|
||||
describe "dealloc" do
|
||||
it "can be defined and is called" do
|
||||
$dealloc_test = false
|
||||
DeallocTest.performSelectorOnMainThread(:'test', withObject:nil, waitUntilDone:false)
|
||||
NSRunLoop.currentRunLoop.runUntilDate(NSDate.dateWithTimeIntervalSinceNow(0.1))
|
||||
$dealloc_test.should == true
|
||||
end
|
||||
end
|
||||
|
||||
$retain_test = false
|
||||
class RetainTest
|
||||
def retain
|
||||
super
|
||||
$retain_test = true
|
||||
end
|
||||
end
|
||||
|
||||
describe "retain and release" do
|
||||
it "can be called directly" do
|
||||
o = Object.new
|
||||
o.retainCount.should == 1
|
||||
o.retain
|
||||
o.retainCount.should == 2
|
||||
o.release
|
||||
o.retainCount.should == 1
|
||||
end
|
||||
|
||||
it "can be defined" do
|
||||
o = RetainTest.new
|
||||
$retain_test.should == false
|
||||
NSArray.arrayWithObject(o)
|
||||
$retain_test.should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe "references" do
|
||||
it "can be created using instance variables" do
|
||||
o = Object.new
|
||||
o.retainCount.should == 1
|
||||
@tmpref = o
|
||||
o.retainCount.should == 2
|
||||
@tmpref = nil
|
||||
o.retainCount.should == 1
|
||||
end
|
||||
|
||||
it "can be created using constants" do
|
||||
o = Object.new
|
||||
o.retainCount.should == 1
|
||||
ConstRef = o
|
||||
o.retainCount.should == 2
|
||||
end
|
||||
end
|
||||
|
||||
class InitTest
|
||||
def self.test_start
|
||||
@o = InitTest.new
|
||||
@o.instance_variable_set(:@foo, 42)
|
||||
5.times { @o.init }
|
||||
end
|
||||
def self.test_res
|
||||
@o
|
||||
end
|
||||
end
|
||||
|
||||
describe "init" do
|
||||
it "can safely be called separately" do
|
||||
InitTest.performSelectorOnMainThread(:'test_start', withObject:nil, waitUntilDone:false)
|
||||
NSRunLoop.currentRunLoop.runUntilDate(NSDate.dateWithTimeIntervalSinceNow(0.1))
|
||||
InitTest.test_res.instance_variable_get(:@foo).should == 42
|
||||
end
|
||||
end
|
||||
|
||||
class InitSuperTest
|
||||
def init
|
||||
if super
|
||||
end
|
||||
self
|
||||
end
|
||||
def dealloc
|
||||
$dealloc_test = true
|
||||
super
|
||||
end
|
||||
def self.test_start
|
||||
InitSuperTest.alloc.init
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "init+super" do
|
||||
it "returns an autoreleased object" do
|
||||
$dealloc_test = false
|
||||
InitSuperTest.performSelectorOnMainThread(:'test_start', withObject:nil, waitUntilDone:false)
|
||||
NSRunLoop.currentRunLoop.runUntilDate(NSDate.dateWithTimeIntervalSinceNow(0.1))
|
||||
$dealloc_test.should == true
|
||||
end
|
||||
end
|
||||
|
||||
class TestSetValueForKey
|
||||
attr_accessor :foo
|
||||
end
|
||||
|
||||
describe "setValue:forKey:" do
|
||||
it "retains the value" do
|
||||
o = TestSetValueForKey.new
|
||||
val = Object.new
|
||||
refcount = val.retainCount
|
||||
o.setValue(val, forKey:'foo')
|
||||
o.foo.should == val
|
||||
val.retainCount.should >= refcount + 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "setValuesForKeysWithDictionary:" do
|
||||
it "retain the values" do
|
||||
o = TestSetValueForKey.new
|
||||
val = Object.new
|
||||
refcount = val.retainCount
|
||||
o.setValuesForKeysWithDictionary({'foo' => val})
|
||||
val.retainCount.should >= refcount + 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "Random" do
|
||||
it "can be allocated" do
|
||||
autorelease_pool do
|
||||
100.times { Random.new }
|
||||
end
|
||||
1.should == 1
|
||||
end
|
||||
end
|
||||
20
test/spec/module_spec.rb
Normal file
20
test/spec/module_spec.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
class TestModuleSubclass < Module
|
||||
def initialize
|
||||
@foo = 42
|
||||
end
|
||||
def foo
|
||||
@foo
|
||||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
describe "Module" do
|
||||
it "can be subclassed and mixed up" do
|
||||
m = TestModuleSubclass.new
|
||||
m.foo.should == 42
|
||||
o = Object.new
|
||||
o.extend(m)
|
||||
o.foo.should == 42
|
||||
end
|
||||
end
|
||||
=end
|
||||
11
test/spec/nsdecimal_spec.rb
Normal file
11
test/spec/nsdecimal_spec.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
describe "NSDecimal" do
|
||||
it "can be created from NSDecimalNumber" do
|
||||
dn = NSDecimalNumber.decimalNumberWithString('123.456')
|
||||
d = dn.decimalValue
|
||||
d.class.should == NSDecimal
|
||||
NSDecimalNumber.decimalNumberWithDecimal(d).should == dn
|
||||
ptr = Pointer.new(NSDecimal.type)
|
||||
ptr[0] = d
|
||||
NSDecimalString(ptr, nil).should == dn.stringValue
|
||||
end
|
||||
end
|
||||
17
test/spec/nsvalue_spec.rb
Normal file
17
test/spec/nsvalue_spec.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
describe "NSValue objects" do
|
||||
it "can be created manually" do
|
||||
s = MyStruct4C.new(1, 2, 3, 4)
|
||||
pointer = Pointer.new(MyStruct4C.type)
|
||||
pointer[0] = s
|
||||
val = NSValue.value(pointer, withObjCType:MyStruct4C.type)
|
||||
TestMethod.testMethodAcceptingMyStruct4CValue(val).should == true
|
||||
end
|
||||
|
||||
=begin
|
||||
it "can be created from Boxed#to_value" do
|
||||
val = MyStruct4C.new(1, 2, 3, 4).to_value
|
||||
val.objcType.should == MyStruct4C.type
|
||||
TestMethod.testMethodAcceptingMyStruct4CValue(val).should == true
|
||||
end
|
||||
=end
|
||||
end
|
||||
8
test/spec/pointer_spec.rb
Normal file
8
test/spec/pointer_spec.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
describe "Pointer" do
|
||||
it "can point to C strings" do
|
||||
vals = (1..10).to_a
|
||||
ptr = Pointer.new(:string, vals.size)
|
||||
vals.each_with_index { |v, i| ptr[i] = v.to_s }
|
||||
TestMethod.testPointerToStrings(ptr, length:vals.size).should == vals.inject(0) { |m, v| m + v }
|
||||
end
|
||||
end
|
||||
20
test/spec/protocol_spec.rb
Normal file
20
test/spec/protocol_spec.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
class TestConformsToProtocolObject1
|
||||
def requiredMethod1; 42; end
|
||||
def requiredMethod2; 42; end
|
||||
end
|
||||
|
||||
class TestConformsToProtocolObject2
|
||||
def requiredMethod1; 42; end
|
||||
def requiredMethod2; 42; end
|
||||
def optionalMethod3; 42; end
|
||||
end
|
||||
|
||||
describe "conformsToProtocol:" do
|
||||
it "works on Ruby objects implementing required methods" do
|
||||
TestMethod.testConformsToProtocol(TestConformsToProtocolObject1.new).should == true
|
||||
end
|
||||
|
||||
it "works on Ruby objects implementing all methods" do
|
||||
TestMethod.testConformsToProtocol(TestConformsToProtocolObject2.new).should == true
|
||||
end
|
||||
end
|
||||
10
test/spec/string_spec.rb
Normal file
10
test/spec/string_spec.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
describe "Strings containing null terminators" do
|
||||
it "can be compiled and used" do
|
||||
s = "\x00"
|
||||
s.size.should == 1
|
||||
s = "\x00\x00"
|
||||
s.size.should == 2
|
||||
s = "\x00\x00\x00"
|
||||
s.size.should == 3
|
||||
end
|
||||
end
|
||||
60
test/vendor/code/code.h
vendored
Normal file
60
test/vendor/code/code.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
struct MyStruct4C {
|
||||
char a, b, c, d;
|
||||
};
|
||||
|
||||
typedef id (^MyBlock)(void);
|
||||
|
||||
@protocol TestProtocol <NSObject>
|
||||
- (BOOL)testProtocolFlag;
|
||||
- (void)setTestProtocolFlag:(BOOL)testFlag;
|
||||
@end
|
||||
|
||||
@protocol TestConformsToProtocol <NSObject>
|
||||
@required
|
||||
- (int)requiredMethod1;
|
||||
- (int)requiredMethod2;
|
||||
@optional
|
||||
- (int)optionalMethod3;
|
||||
@end
|
||||
|
||||
@interface TestMethod : NSObject <TestProtocol>
|
||||
{
|
||||
BOOL _testProtocolFlag;
|
||||
}
|
||||
|
||||
- (CGSize)methodReturningCGSize;
|
||||
- (CGRect)methodReturningCGRect;
|
||||
+ (BOOL)testMethodReturningCGSize:(TestMethod *)testMethod;
|
||||
+ (BOOL)testMethodReturningCGRect:(TestMethod *)testMethod;
|
||||
|
||||
+ (BOOL)testMethodAcceptingUIInterfaceOrientation:(UIInterfaceOrientation)orientation;
|
||||
+ (BOOL)testMethodAcceptingUIEdgeInsets:(UIEdgeInsets)insets;
|
||||
+ (id)testMethodCallingBlock:(MyBlock)block;
|
||||
+ (BOOL)testMethodAcceptingCFType:(CFStringRef)cfstring;
|
||||
+ (BOOL)testMethodAcceptingMyStruct4C:(struct MyStruct4C)s;
|
||||
+ (BOOL)testMethodAcceptingMyStruct4C:(struct MyStruct4C)s another:(struct MyStruct4C)s2;
|
||||
+ (BOOL)testMethodAcceptingMyStruct4CValue:(NSValue *)val;
|
||||
|
||||
+ (BOOL)testValueForKey:(Class)klass expected:(id)expected;
|
||||
|
||||
+ (int)testPointerToStrings:(char **)strs length:(int)len;
|
||||
|
||||
- (int)methodReturningLargeInt;
|
||||
- (id)methodSendingNew:(Class)klass;
|
||||
|
||||
+ (BOOL)testConformsToProtocol:(id <TestConformsToProtocol>)obj;
|
||||
|
||||
@end
|
||||
|
||||
@interface TestIterator : NSObject <NSFastEnumeration>
|
||||
@end
|
||||
|
||||
static inline int TestInlineFunction(int x, int y, int z) {
|
||||
return x + y + z;
|
||||
}
|
||||
|
||||
extern int lowerCaseConstant;
|
||||
@interface lowerCaseClass : NSObject
|
||||
@end
|
||||
126
test/vendor/code/code.m
vendored
Normal file
126
test/vendor/code/code.m
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "code.h"
|
||||
|
||||
@implementation TestMethod
|
||||
|
||||
- (CGSize)methodReturningCGSize
|
||||
{
|
||||
return CGSizeMake(1, 2);
|
||||
}
|
||||
|
||||
- (CGRect)methodReturningCGRect
|
||||
{
|
||||
return CGRectMake(1, 2, 3, 4);
|
||||
}
|
||||
|
||||
+ (BOOL)testMethodReturningCGSize:(TestMethod *)testMethod
|
||||
{
|
||||
CGSize size = [testMethod methodReturningCGSize];
|
||||
return size.width == 1 && size.height == 2;
|
||||
}
|
||||
|
||||
+ (BOOL)testMethodReturningCGRect:(TestMethod *)testMethod
|
||||
{
|
||||
CGRect rect = [testMethod methodReturningCGRect];
|
||||
return rect.origin.x == 1 && rect.origin.y == 2 && rect.size.width == 3 && rect.size.height == 4;
|
||||
}
|
||||
|
||||
+ (BOOL)testMethodAcceptingUIInterfaceOrientation:(UIInterfaceOrientation)orientation
|
||||
{
|
||||
return orientation == UIInterfaceOrientationPortrait;
|
||||
}
|
||||
|
||||
+ (BOOL)testMethodAcceptingUIEdgeInsets:(UIEdgeInsets)insets
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL)testMethodAcceptingCFType:(CFStringRef)cfstring
|
||||
{
|
||||
return [(id)cfstring isEqualToString:@"foo"];
|
||||
}
|
||||
|
||||
+ (BOOL)testMethodAcceptingMyStruct4C:(struct MyStruct4C)s
|
||||
{
|
||||
return s.a == 1 && s.b == 2 && s.c == 3 && s.d == 4;
|
||||
}
|
||||
|
||||
+ (BOOL)testMethodAcceptingMyStruct4C:(struct MyStruct4C)s another:(struct MyStruct4C)s2
|
||||
{
|
||||
return [self testMethodAcceptingMyStruct4C:s] && [self testMethodAcceptingMyStruct4C:s2];
|
||||
}
|
||||
|
||||
+ (BOOL)testMethodAcceptingMyStruct4CValue:(NSValue *)value
|
||||
{
|
||||
struct MyStruct4C s;
|
||||
[value getValue:&s];
|
||||
return [self testMethodAcceptingMyStruct4C:s];
|
||||
}
|
||||
|
||||
+ (id)testMethodCallingBlock:(MyBlock)block
|
||||
{
|
||||
if (block != nil) {
|
||||
return block();
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (BOOL)testValueForKey:(id)obj expected:(id)expected
|
||||
{
|
||||
id val = [obj valueForKey:@"foo"];
|
||||
return val == expected || (val != nil && [val isEqual:expected]);
|
||||
}
|
||||
|
||||
+ (int)testPointerToStrings:(char **)strs length:(int)len
|
||||
{
|
||||
int total = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
assert(strs[i] != NULL);
|
||||
total += atoi(strs[i]);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
- (int)methodReturningLargeInt
|
||||
{
|
||||
return 2147483646;
|
||||
}
|
||||
|
||||
- (id)methodSendingNew:(Class)klass
|
||||
{
|
||||
return [[klass new] autorelease];
|
||||
}
|
||||
|
||||
- (BOOL)testProtocolFlag
|
||||
{
|
||||
return _testProtocolFlag;
|
||||
}
|
||||
|
||||
- (void)setTestProtocolFlag:(BOOL)testFlag
|
||||
{
|
||||
_testProtocolFlag = testFlag;
|
||||
}
|
||||
|
||||
+ (BOOL)testConformsToProtocol:(id <TestConformsToProtocol>)obj
|
||||
{
|
||||
return [obj conformsToProtocol:@protocol(TestConformsToProtocol)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation TestIterator
|
||||
|
||||
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
|
||||
{
|
||||
static NSArray *content = nil;
|
||||
if (content == nil) {
|
||||
content = [[NSArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", nil] retain];
|
||||
}
|
||||
return [content countByEnumeratingWithState:state objects:stackbuf count:len];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
int lowerCaseConstant = 42;
|
||||
|
||||
@implementation lowerCaseClass
|
||||
@end
|
||||
Reference in New Issue
Block a user