@@ -135,29 +135,49 @@ describe(module.id, function () {
135135 } ) ;
136136
137137 it ( "instanceOfUITabBarController" , function ( ) {
138- if ( pendingIfMissingSymbol ( "UITabBarController" ) ||
139- pendingIfMissingSymbol ( "UIViewController" ) ||
140- pendingIfMissingSymbol ( "UIResponder" ) ) {
138+ if ( hasGlobalSymbol ( "UITabBarController" ) &&
139+ hasGlobalSymbol ( "UIViewController" ) &&
140+ hasGlobalSymbol ( "UIResponder" ) ) {
141+ var uiObject = UITabBarController . alloc ( ) . init ( ) ;
142+ expect ( uiObject instanceof UITabBarController ) . toBe ( true ) ;
143+ expect ( uiObject instanceof UIViewController ) . toBe ( true ) ;
144+ expect ( uiObject instanceof UIResponder ) . toBe ( true ) ;
145+ expect ( uiObject instanceof NSObject ) . toBe ( true ) ;
141146 return ;
142147 }
143148
144- var object = UITabBarController . alloc ( ) . init ( ) ;
145- expect ( object instanceof UITabBarController ) . toBe ( true ) ;
146- expect ( object instanceof UIViewController ) . toBe ( true ) ;
147- expect ( object instanceof UIResponder ) . toBe ( true ) ;
148- expect ( object instanceof NSObject ) . toBe ( true ) ;
149+ if ( hasGlobalSymbol ( "NSTabViewController" ) &&
150+ hasGlobalSymbol ( "NSViewController" ) &&
151+ hasGlobalSymbol ( "NSResponder" ) ) {
152+ var nsObject = NSTabViewController . alloc ( ) . init ( ) ;
153+ expect ( nsObject instanceof NSTabViewController ) . toBe ( true ) ;
154+ expect ( nsObject instanceof NSViewController ) . toBe ( true ) ;
155+ expect ( nsObject instanceof NSResponder ) . toBe ( true ) ;
156+ expect ( nsObject instanceof NSObject ) . toBe ( true ) ;
157+ return ;
158+ }
159+
160+ pending ( "Neither UIKit nor AppKit tab/view controller hierarchy is available." ) ;
149161 } ) ;
150162
151163 it ( "Appearance" , function ( ) {
152- if ( pendingIfMissingSymbol ( "UILabel" ) || pendingIfMissingSymbol ( "UIColor" ) ) {
164+ if ( hasGlobalSymbol ( "UILabel" ) && hasGlobalSymbol ( "UIColor" ) ) {
165+ expect ( UILabel . appearance ( ) . description . indexOf ( '<Customizable class: UILabel>' ) ) . not . toBe ( - 1 ) ;
166+
167+ UILabel . appearance ( ) . textColor = UIColor . redColor ;
168+ expect ( UILabel . appearance ( ) . textColor ) . toBe ( UIColor . redColor ) ;
153169 return ;
154170 }
155171
156- expect ( UILabel . appearance ( ) . description . indexOf ( '<Customizable class: UILabel>' ) ) . not . toBe ( - 1 ) ;
172+ if ( hasGlobalSymbol ( "NSAppearance" ) && hasGlobalSymbol ( "NSAppearanceNameAqua" ) ) {
173+ var appearance = NSAppearance . appearanceNamed ( NSAppearanceNameAqua ) ;
174+ expect ( appearance ) . toBeDefined ( ) ;
175+ expect ( appearance ) . not . toBeNull ( ) ;
176+ expect ( appearance . name ) . toContain ( "Aqua" ) ;
177+ return ;
178+ }
157179
158- UILabel . appearance ( ) . textColor = UIColor . redColor ;
159- expect ( UILabel . appearance ( ) . textColor ) . toBe ( UIColor . redColor ) ;
160- // expect(UILabel.appearance().constructor).toBe(UILabel);
180+ pending ( "Neither UIKit nor AppKit appearance APIs are available." ) ;
161181 } ) ;
162182
163183 it ( "ReadonlyPropertyInProtocolAndOverrideWithSetterInInterface" , function ( ) {
@@ -248,42 +268,88 @@ describe(module.id, function () {
248268 } ) ;
249269
250270 it ( "SpecialCaseProperty_When_InstancesRespondToSelector:_IsFalse" , function ( ) {
251- if ( pendingIfMissingSymbol ( "UITextField" ) ) {
271+ var uiTextField = hasGlobalSymbol ( "UITextField" ) ? global . UITextField : null ;
272+ var nsView = hasGlobalSymbol ( "NSView" ) ? global . NSView : null ;
273+ if ( uiTextField ) {
274+ var uiField = new uiTextField ( ) ;
275+ expect ( uiField . secureTextEntry ) . toBe ( false ) ;
276+ uiField . secureTextEntry = true ;
277+ expect ( uiField . secureTextEntry ) . toBe ( true ) ;
278+ return ;
279+ }
280+
281+ if ( ! nsView ) {
282+ pending ( "No suitable platform class is available for special-case property checks." ) ;
252283 return ;
253284 }
254285
255- var field = new UITextField ( ) ;
256- expect ( field . secureTextEntry ) . toBe ( false ) ;
257- field . secureTextEntry = true ;
258- expect ( field . secureTextEntry ) . toBe ( true ) ;
286+ var field = nsView . alloc ( ) . init ( ) ;
287+ expect ( field . hidden ) . toBe ( false ) ;
288+ field . hidden = true ;
289+ expect ( field . hidden ) . toBe ( true ) ;
259290 } ) ;
260291
261292 it ( "SpecialCaseProperty_When_CustomSelector_ImplementedInJS" , function ( ) {
262- if ( pendingIfMissingSymbol ( "UITextField" ) ) {
293+ var uiTextField = hasGlobalSymbol ( "UITextField" ) ? global . UITextField : null ;
294+ var nsView = hasGlobalSymbol ( "NSView" ) ? global . NSView : null ;
295+ if ( uiTextField ) {
296+ var uiField = new ( uiTextField . extend ( {
297+ get secureTextEntry ( ) {
298+ TNSLog ( "getter" ) ;
299+ return this . _secureTextEntry ;
300+ } ,
301+ set secureTextEntry ( val ) {
302+ this . _secureTextEntry = val ;
303+ TNSLog ( "setter:" + val ) ;
304+ }
305+ } ) ) ( ) ;
306+ var uiExpectedOutput = "" ;
307+
308+ expect ( uiField . secureTextEntry ) . toBeUndefined ( ) ; uiExpectedOutput += "getter" ;
309+
310+ uiField . secureTextEntry = true ; uiExpectedOutput += "setter:true" ;
311+
312+ expect ( uiField . secureTextEntry ) . toBe ( true ) ; uiExpectedOutput += "getter" ;
313+
314+ uiField . secureTextEntry = false ; uiExpectedOutput += "setter:false" ;
315+
316+ expect ( uiField . secureTextEntry ) . toBe ( false ) ; uiExpectedOutput += "getter" ;
317+
318+ expect ( TNSGetOutput ( ) ) . toBe ( uiExpectedOutput ) ;
319+ return ;
320+ }
321+
322+ if ( ! nsView ) {
323+ pending ( "No suitable platform class is available for special-case property checks." ) ;
263324 return ;
264325 }
265326
266- var field = new ( UITextField . extend ( {
267- get secureTextEntry ( ) {
327+ var overrides = { } ;
328+ Object . defineProperty ( overrides , "hidden" , {
329+ get : function ( ) {
268330 TNSLog ( "getter" ) ;
269- return this . _secureTextEntry ;
331+ return this . _value ;
270332 } ,
271- set secureTextEntry ( val ) {
272- this . _secureTextEntry = val ;
333+ set : function ( val ) {
334+ this . _value = val ;
273335 TNSLog ( "setter:" + val ) ;
274- }
275- } ) ) ( ) ;
336+ } ,
337+ enumerable : true ,
338+ configurable : true
339+ } ) ;
340+
341+ var field = new ( nsView . extend ( overrides ) ) ( ) ;
276342 var expectedOutput = "" ;
277343
278- expect ( field . secureTextEntry ) . toBeUndefined ( ) ; expectedOutput += "getter" ;
344+ expect ( field . hidden ) . toBeUndefined ( ) ; expectedOutput += "getter" ;
279345
280- field . secureTextEntry = true ; expectedOutput += "setter:true" ;
346+ field . hidden = true ; expectedOutput += "setter:true" ;
281347
282- expect ( field . secureTextEntry ) . toBe ( true ) ; expectedOutput += "getter" ;
348+ expect ( field . hidden ) . toBe ( true ) ; expectedOutput += "getter" ;
283349
284- field . secureTextEntry = false ; expectedOutput += "setter:false" ;
350+ field . hidden = false ; expectedOutput += "setter:false" ;
285351
286- expect ( field . secureTextEntry ) . toBe ( false ) ; expectedOutput += "getter" ;
352+ expect ( field . hidden ) . toBe ( false ) ; expectedOutput += "getter" ;
287353
288354 expect ( TNSGetOutput ( ) ) . toBe ( expectedOutput ) ;
289355 } ) ;
@@ -802,25 +868,32 @@ describe(module.id, function () {
802868 // });
803869
804870 it ( "Unimplemented properties from UIBarItem class should be provided by the inheritors" , function ( ) {
805- var classConstructors = [ "UIBarButtonItem" , "UITabBarItem" ] ;
806- for ( var className of classConstructors ) {
807- if ( ! hasGlobalSymbol ( className ) ) {
808- pending ( className + " is not available in this runtime/platform configuration." ) ;
809- return ;
871+ if ( hasGlobalSymbol ( "UIBarButtonItem" ) && hasGlobalSymbol ( "UITabBarItem" ) ) {
872+ var iosClassConstructors = [ "UIBarButtonItem" , "UITabBarItem" ] ;
873+ var iosProps = [ "enabled" , "image" , "imageInsets" , "title" ] ;
874+ if ( NSProcessInfo . processInfo . isOperatingSystemAtLeastVersion ( { majorVersion : 11 , minorVersion : 0 , patchVersion : 0 } ) ) {
875+ iosProps = iosProps . concat ( "landscapeImagePhone" , "landscapeImagePhoneInsets" ) ;
810876 }
811- }
812877
813- var props = [ "enabled" , "image" , "imageInsets" , "title" ] ;
814- if ( NSProcessInfo . processInfo . isOperatingSystemAtLeastVersion ( { majorVersion : 11 , minorVersion : 0 , patchVersion : 0 } ) ) {
815- props = props . concat ( "landscapeImagePhone" , "landscapeImagePhoneInsets" ) ;
878+ for ( var iosKlass of iosClassConstructors ) {
879+ var iosInstance = new global [ iosKlass ] ( ) ;
880+ for ( var iosProp of iosProps ) {
881+ expect ( iosInstance [ iosProp ] ) . toBeDefined ( `"${ iosProp } " must be defined in instances of "${ iosKlass } "` ) ;
882+ }
883+ }
884+ return ;
816885 }
817886
818- for ( var klass of classConstructors ) {
819- var instance = new global [ klass ] ( ) ;
820- for ( var prop of props ) {
821- expect ( instance [ prop ] ) . toBeDefined ( `"${ prop } " must be defined in instances of "${ klass } "` ) ;
887+ if ( hasGlobalSymbol ( "NSToolbarItem" ) ) {
888+ var toolbarItem = NSToolbarItem . alloc ( ) . initWithItemIdentifier ( "nativescript.test.item" ) ;
889+ var macProps = [ "enabled" , "image" , "label" , "paletteLabel" , "toolTip" ] ;
890+ for ( var macProp of macProps ) {
891+ expect ( toolbarItem [ macProp ] ) . toBeDefined ( `"${ macProp } " must be defined in instances of "NSToolbarItem"` ) ;
822892 }
893+ return ;
823894 }
895+
896+ pending ( "Neither UIKit UIBarItem inheritors nor AppKit NSToolbarItem are available." ) ;
824897 } ) ;
825898
826899 it ( "Unimplemented properties from MTLRenderPassAttachmentDescriptor class should be provided by the inheritors" , function ( ) {
@@ -846,16 +919,25 @@ describe(module.id, function () {
846919 } ) ;
847920
848921 it ( "Dynamically load modules" , ( ) => {
849- if ( pendingIfMissingSymbol ( "CMMotionActivityManager" ) ) {
922+ var className = null ;
923+ for ( var candidate of [ "CMMotionActivityManager" , "CMMotionManager" , "CLLocationManager" , "AVAudioEngine" ] ) {
924+ if ( hasGlobalSymbol ( candidate ) ) {
925+ className = candidate ;
926+ break ;
927+ }
928+ }
929+
930+ if ( ! className ) {
931+ pending ( "No candidate class from dynamically loaded frameworks is available in this runtime." ) ;
850932 return ;
851933 }
852934
853- // The CMMotionActivityManager interface is defined inside the CoreMotion system framework which is not
854- // statically loaded and the runtime must dynamically resolve it at runtime.
855- let activityManager = CMMotionActivityManager . new ( ) ;
856- expect ( activityManager ) . not . toBeUndefined ( ) ;
857- expect ( activityManager ) . not . toBeNull ( ) ;
858- expect ( activityManager instanceof CMMotionActivityManager ) . toBe ( true ) ;
935+ // The selected class is expected to come from a framework resolved at runtime.
936+ let dynamicType = global [ className ] ;
937+ let instance = dynamicType . new ? dynamicType . new ( ) : dynamicType . alloc ( ) . init ( ) ;
938+ expect ( instance ) . not . toBeUndefined ( ) ;
939+ expect ( instance ) . not . toBeNull ( ) ;
940+ expect ( instance instanceof dynamicType ) . toBe ( true ) ;
859941 } ) ;
860942
861943 it ( "Optional method returning a structure should use objc_msgSend_stret on x86_64" , ( ) => {
0 commit comments