/Tests/AppKit/CPKeyValueBindingSimpleBindingsTest.j

http://github.com/cacaodev/cappuccino · Unknown · 196 lines · 148 code · 48 blank · 0 comment · 0 complexity · 30b5ddf868a6180326f41cb5cc887271 MD5 · raw file

  1. @import <AppKit/AppKit.j>
  2. @class Track
  3. /*!
  4. Bindings tests exercising the functionality seen in the Cocoa example "SimpleBindingsAdoption".
  5. */
  6. @implementation CPKeyValueBindingSimpleBindingsTest : OJTestCase
  7. {
  8. CPTextField textField @accessors;
  9. CPSlider slider @accessors;
  10. CPButton button @accessors;
  11. Track track @accessors;
  12. CPWindow theWindow @accessors;
  13. CPObjectController objectController @accessors;
  14. }
  15. - (void)setUp
  16. {
  17. // CPApp must be initialised or action sending will not work.
  18. [CPApplication sharedApplication];
  19. track = [Track new];
  20. [track setVolume:5.0];
  21. }
  22. - (void)createControls
  23. {
  24. textField = [CPTextField textFieldWithStringValue:@"" placeholder:@"" width:100];
  25. slider = [[CPSlider alloc] initWithFrame:CGRectMakeZero()];
  26. button = [CPButton buttonWithTitle:@"Mute"];
  27. }
  28. /*!
  29. Base case without bindings.
  30. */
  31. - (void)testSimpleBindings01
  32. {
  33. [self createControls];
  34. [textField setTarget:self];
  35. [textField setAction:@selector(updateVolumeFrom:)];
  36. [slider setTarget:self];
  37. [slider setAction:@selector(updateVolumeFrom:)];
  38. [button setTarget:self];
  39. [button setAction:@selector(muteTrack01:)];
  40. // Test the interaction.
  41. [textField setStringValue:@"0.7"];
  42. // Simulate user interaction to fire action.
  43. [textField performClick:self];
  44. [self verifyVolume:0.7 method:"actions"];
  45. [slider setFloatValue:9.0];
  46. [slider performClick:self];
  47. [self verifyVolume:9 method:"actions"];
  48. [button performClick:self];
  49. [self verifyVolume:0 method:"actions"];
  50. }
  51. /*!
  52. Using bindings and an object controller.
  53. */
  54. - (void)testSimpleBindings02
  55. {
  56. [self createControls];
  57. objectController = [CPObjectController new];
  58. [objectController bind:@"contentObject" toObject:self withKeyPath:@"track" options:nil];
  59. [textField bind:@"value" toObject:objectController withKeyPath:@"selection.volume" options:nil];
  60. [slider bind:@"value" toObject:objectController withKeyPath:@"selection.volume" options:nil];
  61. [button setTarget:self];
  62. [button setAction:@selector(muteTrack:)];
  63. // Test the interaction.
  64. [textField setStringValue:@"0.7"];
  65. // Simulate user interaction. By default bindings update on action only.
  66. [textField performClick:self];
  67. [self verifyVolume:0.7 method:"bindings"];
  68. [slider setFloatValue:9.0];
  69. [slider performClick:self];
  70. [self verifyVolume:9 method:"bindings"];
  71. [button performClick:self];
  72. [self verifyVolume:0 method:"bindings"];
  73. }
  74. /*!
  75. Using bindings and a controller set up in a cib (e.g. using Interface Builder).
  76. */
  77. - (void)testSimpleBindings03
  78. {
  79. // Note: this cib will connect 'objectController'. This is only for debugging purposes,
  80. // this code should run with or without that connection.
  81. var cib = [CPBundle loadCibFile:[[CPBundle bundleForClass:CPKeyValueBindingSimpleBindingsTest] pathForResource:"SimpleBindingsAdoption_03.cib"] externalNameTable:@{ CPCibOwner: self }];
  82. // Test the interaction.
  83. [textField setStringValue:@"0.7"];
  84. // Simulate user interaction. By default bindings update on action only.
  85. [textField performClick:self];
  86. [self verifyVolume:0.7 method:"bindings"];
  87. [slider setFloatValue:9.0];
  88. [slider performClick:self];
  89. [self verifyVolume:9 method:"bindings"];
  90. [button performClick:self];
  91. [self verifyVolume:0 method:"bindings"];
  92. // Test if CPNullPlaceholderBindingOption is correctly decoded
  93. var bindingInfo = [textField infoForBinding:@"value"],
  94. nullPlaceHolder = [[bindingInfo objectForKey:CPOptionsKey] objectForKey:CPNullPlaceholderBindingOption];
  95. [self assert:@"Nothing" equals:nullPlaceHolder];
  96. }
  97. - (void)verifyVolume:(float)aVolume method:(CPString)aMethod
  98. {
  99. [self assert:aVolume equals:[track volume] message:"volume should update through " + aMethod];
  100. [self assert:[track volume] equals:[textField floatValue]];
  101. [self assert:[track volume] equals:[slider floatValue]];
  102. }
  103. #pragma mark ----- actions used by implementation 01 -----
  104. - (void)updateVolumeFrom:(id)sender
  105. {
  106. var newVolume = [sender floatValue];
  107. [track setVolume:newVolume];
  108. [self updateUserInterface];
  109. }
  110. - (void)updateUserInterface
  111. {
  112. [slider setFloatValue:[track volume]];
  113. [textField setFloatValue:[track volume]];
  114. }
  115. - (void)muteTrack01:(id)sender
  116. {
  117. [track setVolume:0.0];
  118. [self updateUserInterface];
  119. }
  120. #pragma mark ----- actions used by implementation 02 and 03 -----
  121. - (void)muteTrack:(id)sender
  122. {
  123. [track setVolume:0.0];
  124. }
  125. @end
  126. @implementation Track : CPObject
  127. {
  128. float volume @accessors;
  129. CPString title @accessors;
  130. }
  131. - (void)setVolume:(float)aValue
  132. {
  133. if (volume != aValue)
  134. {
  135. // The Cocoa version does not need this explicit conversion but we do,
  136. // because otherwise bindings will turn this into a string when reading
  137. // from the text field. A side effect of loose typing.
  138. volume = parseFloat(aValue);
  139. }
  140. }
  141. - (void)setTitle:(CPString)newTitle
  142. {
  143. if (title != newTitle)
  144. {
  145. title = [newTitle copy];
  146. }
  147. }
  148. @end