bbrowning-virtualbox 0.7.6.dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. data/.gitignore +8 -0
  2. data/.yardopts +3 -0
  3. data/Gemfile +16 -0
  4. data/LICENSE +19 -0
  5. data/Rakefile +33 -0
  6. data/Readme.md +70 -0
  7. data/docs/GettingStarted.md +196 -0
  8. data/docs/WhatsNew.md +12 -0
  9. data/features/README.md +33 -0
  10. data/features/global.feature +19 -0
  11. data/features/global_extra_data.feature +27 -0
  12. data/features/step_definitions/abstract_model_steps.rb +39 -0
  13. data/features/step_definitions/extra_data_steps.rb +36 -0
  14. data/features/step_definitions/global_steps.rb +29 -0
  15. data/features/step_definitions/nat_engine_steps.rb +76 -0
  16. data/features/step_definitions/network_adapter_steps.rb +38 -0
  17. data/features/step_definitions/shared_folder_steps.rb +76 -0
  18. data/features/step_definitions/snapshot_steps.rb +74 -0
  19. data/features/step_definitions/storage_controller_steps.rb +16 -0
  20. data/features/step_definitions/virtualbox_steps.rb +17 -0
  21. data/features/step_definitions/vm_steps.rb +50 -0
  22. data/features/support/env.rb +61 -0
  23. data/features/support/helpers.rb +38 -0
  24. data/features/support/hooks.rb +30 -0
  25. data/features/support/ordered_hash.rb +49 -0
  26. data/features/support/vboxmanage.rb +191 -0
  27. data/features/version.feature +16 -0
  28. data/features/vm.feature +13 -0
  29. data/features/vm_bios.feature +29 -0
  30. data/features/vm_cpu.feature +29 -0
  31. data/features/vm_extra_data.feature +35 -0
  32. data/features/vm_hw_virt.feature +29 -0
  33. data/features/vm_nat_engine.feature +57 -0
  34. data/features/vm_network_adapters.feature +27 -0
  35. data/features/vm_shared_folders.feature +42 -0
  36. data/features/vm_snapshots.feature +29 -0
  37. data/features/vm_storage_controllers.feature +11 -0
  38. data/lib/virtualbox.rb +11 -0
  39. data/lib/virtualbox/abstract_model.rb +281 -0
  40. data/lib/virtualbox/abstract_model/attributable.rb +290 -0
  41. data/lib/virtualbox/abstract_model/dirty.rb +177 -0
  42. data/lib/virtualbox/abstract_model/interface_attributes.rb +98 -0
  43. data/lib/virtualbox/abstract_model/relatable.rb +332 -0
  44. data/lib/virtualbox/abstract_model/validatable.rb +167 -0
  45. data/lib/virtualbox/abstract_model/version_matcher.rb +35 -0
  46. data/lib/virtualbox/appliance.rb +62 -0
  47. data/lib/virtualbox/audio_adapter.rb +52 -0
  48. data/lib/virtualbox/bios.rb +50 -0
  49. data/lib/virtualbox/com.rb +23 -0
  50. data/lib/virtualbox/com/abstract_enum.rb +43 -0
  51. data/lib/virtualbox/com/abstract_implementer.rb +45 -0
  52. data/lib/virtualbox/com/abstract_interface.rb +167 -0
  53. data/lib/virtualbox/com/base_interface.rb +38 -0
  54. data/lib/virtualbox/com/ffi/interface.rb +150 -0
  55. data/lib/virtualbox/com/ffi/interfaces.rb +54 -0
  56. data/lib/virtualbox/com/ffi/util.rb +119 -0
  57. data/lib/virtualbox/com/ffi/vboxxpcomc.rb +31 -0
  58. data/lib/virtualbox/com/ffi_interface.rb +96 -0
  59. data/lib/virtualbox/com/implementer/base.rb +59 -0
  60. data/lib/virtualbox/com/implementer/ffi.rb +361 -0
  61. data/lib/virtualbox/com/implementer/mscom.rb +175 -0
  62. data/lib/virtualbox/com/implementer/nil.rb +10 -0
  63. data/lib/virtualbox/com/interface/3.1.x/access_mode.rb +11 -0
  64. data/lib/virtualbox/com/interface/3.1.x/appliance.rb +22 -0
  65. data/lib/virtualbox/com/interface/3.1.x/audio_adapter.rb +15 -0
  66. data/lib/virtualbox/com/interface/3.1.x/audio_controller_type.rb +11 -0
  67. data/lib/virtualbox/com/interface/3.1.x/audio_driver_type.rb +11 -0
  68. data/lib/virtualbox/com/interface/3.1.x/bios_boot_menu_mode.rb +11 -0
  69. data/lib/virtualbox/com/interface/3.1.x/bios_settings.rb +21 -0
  70. data/lib/virtualbox/com/interface/3.1.x/clipboard_mode.rb +11 -0
  71. data/lib/virtualbox/com/interface/3.1.x/console.rb +50 -0
  72. data/lib/virtualbox/com/interface/3.1.x/cpu_property_type.rb +11 -0
  73. data/lib/virtualbox/com/interface/3.1.x/device_type.rb +11 -0
  74. data/lib/virtualbox/com/interface/3.1.x/dhcp_server.rb +22 -0
  75. data/lib/virtualbox/com/interface/3.1.x/firmware_type.rb +11 -0
  76. data/lib/virtualbox/com/interface/3.1.x/guest_os_type.rb +23 -0
  77. data/lib/virtualbox/com/interface/3.1.x/host.rb +42 -0
  78. data/lib/virtualbox/com/interface/3.1.x/host_network_interface.rb +30 -0
  79. data/lib/virtualbox/com/interface/3.1.x/host_network_interface_medium_type.rb +11 -0
  80. data/lib/virtualbox/com/interface/3.1.x/host_network_interface_status.rb +11 -0
  81. data/lib/virtualbox/com/interface/3.1.x/host_network_interface_type.rb +11 -0
  82. data/lib/virtualbox/com/interface/3.1.x/host_usb_device.rb +13 -0
  83. data/lib/virtualbox/com/interface/3.1.x/host_usb_device_filter.rb +13 -0
  84. data/lib/virtualbox/com/interface/3.1.x/hw_virt_ex_property_type.rb +11 -0
  85. data/lib/virtualbox/com/interface/3.1.x/machine.rb +105 -0
  86. data/lib/virtualbox/com/interface/3.1.x/machine_state.rb +14 -0
  87. data/lib/virtualbox/com/interface/3.1.x/medium.rb +50 -0
  88. data/lib/virtualbox/com/interface/3.1.x/medium_attachment.rb +18 -0
  89. data/lib/virtualbox/com/interface/3.1.x/medium_format.rb +18 -0
  90. data/lib/virtualbox/com/interface/3.1.x/medium_state.rb +11 -0
  91. data/lib/virtualbox/com/interface/3.1.x/medium_type.rb +11 -0
  92. data/lib/virtualbox/com/interface/3.1.x/medium_variant.rb +11 -0
  93. data/lib/virtualbox/com/interface/3.1.x/network_adapter.rb +30 -0
  94. data/lib/virtualbox/com/interface/3.1.x/network_adapter_type.rb +11 -0
  95. data/lib/virtualbox/com/interface/3.1.x/network_attachment_type.rb +11 -0
  96. data/lib/virtualbox/com/interface/3.1.x/nsiexception.rb +23 -0
  97. data/lib/virtualbox/com/interface/3.1.x/nsisupports.rb +15 -0
  98. data/lib/virtualbox/com/interface/3.1.x/parallel_port.rb +17 -0
  99. data/lib/virtualbox/com/interface/3.1.x/port_mode.rb +11 -0
  100. data/lib/virtualbox/com/interface/3.1.x/progress.rb +63 -0
  101. data/lib/virtualbox/com/interface/3.1.x/serial_port.rb +19 -0
  102. data/lib/virtualbox/com/interface/3.1.x/session.rb +18 -0
  103. data/lib/virtualbox/com/interface/3.1.x/session_state.rb +11 -0
  104. data/lib/virtualbox/com/interface/3.1.x/session_type.rb +11 -0
  105. data/lib/virtualbox/com/interface/3.1.x/shared_folder.rb +17 -0
  106. data/lib/virtualbox/com/interface/3.1.x/snapshot.rb +20 -0
  107. data/lib/virtualbox/com/interface/3.1.x/storage_bus.rb +11 -0
  108. data/lib/virtualbox/com/interface/3.1.x/storage_controller.rb +23 -0
  109. data/lib/virtualbox/com/interface/3.1.x/storage_controller_type.rb +11 -0
  110. data/lib/virtualbox/com/interface/3.1.x/system_properties.rb +37 -0
  111. data/lib/virtualbox/com/interface/3.1.x/usb_controller.rb +20 -0
  112. data/lib/virtualbox/com/interface/3.1.x/usb_device.rb +24 -0
  113. data/lib/virtualbox/com/interface/3.1.x/usb_device_filter.rb +23 -0
  114. data/lib/virtualbox/com/interface/3.1.x/usb_device_filter_action.rb +11 -0
  115. data/lib/virtualbox/com/interface/3.1.x/usb_device_state.rb +11 -0
  116. data/lib/virtualbox/com/interface/3.1.x/virtual_box_error_info.rb +17 -0
  117. data/lib/virtualbox/com/interface/3.1.x/virtual_system_description.rb +19 -0
  118. data/lib/virtualbox/com/interface/3.1.x/virtual_system_description_type.rb +14 -0
  119. data/lib/virtualbox/com/interface/3.1.x/virtual_system_description_value_type.rb +11 -0
  120. data/lib/virtualbox/com/interface/3.1.x/virtualbox.rb +67 -0
  121. data/lib/virtualbox/com/interface/3.1.x/vrdp_auth_type.rb +11 -0
  122. data/lib/virtualbox/com/interface/3.1.x/vrdp_server.rb +19 -0
  123. data/lib/virtualbox/com/interface/3.2.x/access_mode.rb +11 -0
  124. data/lib/virtualbox/com/interface/3.2.x/appliance.rb +22 -0
  125. data/lib/virtualbox/com/interface/3.2.x/audio_adapter.rb +15 -0
  126. data/lib/virtualbox/com/interface/3.2.x/audio_controller_type.rb +11 -0
  127. data/lib/virtualbox/com/interface/3.2.x/audio_driver_type.rb +11 -0
  128. data/lib/virtualbox/com/interface/3.2.x/bios_boot_menu_mode.rb +11 -0
  129. data/lib/virtualbox/com/interface/3.2.x/bios_settings.rb +21 -0
  130. data/lib/virtualbox/com/interface/3.2.x/clipboard_mode.rb +11 -0
  131. data/lib/virtualbox/com/interface/3.2.x/console.rb +50 -0
  132. data/lib/virtualbox/com/interface/3.2.x/cpu_property_type.rb +11 -0
  133. data/lib/virtualbox/com/interface/3.2.x/device_type.rb +11 -0
  134. data/lib/virtualbox/com/interface/3.2.x/dhcp_server.rb +22 -0
  135. data/lib/virtualbox/com/interface/3.2.x/firmware_type.rb +11 -0
  136. data/lib/virtualbox/com/interface/3.2.x/guest.rb +13 -0
  137. data/lib/virtualbox/com/interface/3.2.x/guest_os_type.rb +33 -0
  138. data/lib/virtualbox/com/interface/3.2.x/host.rb +43 -0
  139. data/lib/virtualbox/com/interface/3.2.x/host_network_interface.rb +30 -0
  140. data/lib/virtualbox/com/interface/3.2.x/host_network_interface_medium_type.rb +11 -0
  141. data/lib/virtualbox/com/interface/3.2.x/host_network_interface_status.rb +11 -0
  142. data/lib/virtualbox/com/interface/3.2.x/host_network_interface_type.rb +11 -0
  143. data/lib/virtualbox/com/interface/3.2.x/host_usb_device.rb +13 -0
  144. data/lib/virtualbox/com/interface/3.2.x/host_usb_device_filter.rb +13 -0
  145. data/lib/virtualbox/com/interface/3.2.x/hw_virt_ex_property_type.rb +11 -0
  146. data/lib/virtualbox/com/interface/3.2.x/keyboard_hid_type.rb +11 -0
  147. data/lib/virtualbox/com/interface/3.2.x/machine.rb +118 -0
  148. data/lib/virtualbox/com/interface/3.2.x/machine_state.rb +14 -0
  149. data/lib/virtualbox/com/interface/3.2.x/medium.rb +51 -0
  150. data/lib/virtualbox/com/interface/3.2.x/medium_attachment.rb +18 -0
  151. data/lib/virtualbox/com/interface/3.2.x/medium_format.rb +18 -0
  152. data/lib/virtualbox/com/interface/3.2.x/medium_state.rb +11 -0
  153. data/lib/virtualbox/com/interface/3.2.x/medium_type.rb +11 -0
  154. data/lib/virtualbox/com/interface/3.2.x/medium_variant.rb +11 -0
  155. data/lib/virtualbox/com/interface/3.2.x/nat_alias_mode.rb +11 -0
  156. data/lib/virtualbox/com/interface/3.2.x/nat_engine.rb +27 -0
  157. data/lib/virtualbox/com/interface/3.2.x/nat_protocol.rb +11 -0
  158. data/lib/virtualbox/com/interface/3.2.x/network_adapter.rb +34 -0
  159. data/lib/virtualbox/com/interface/3.2.x/network_adapter_type.rb +11 -0
  160. data/lib/virtualbox/com/interface/3.2.x/network_attachment_type.rb +11 -0
  161. data/lib/virtualbox/com/interface/3.2.x/nsiexception.rb +23 -0
  162. data/lib/virtualbox/com/interface/3.2.x/nsisupports.rb +15 -0
  163. data/lib/virtualbox/com/interface/3.2.x/parallel_port.rb +17 -0
  164. data/lib/virtualbox/com/interface/3.2.x/pointing_hid_type.rb +11 -0
  165. data/lib/virtualbox/com/interface/3.2.x/port_mode.rb +11 -0
  166. data/lib/virtualbox/com/interface/3.2.x/progress.rb +63 -0
  167. data/lib/virtualbox/com/interface/3.2.x/serial_port.rb +19 -0
  168. data/lib/virtualbox/com/interface/3.2.x/session.rb +18 -0
  169. data/lib/virtualbox/com/interface/3.2.x/session_state.rb +11 -0
  170. data/lib/virtualbox/com/interface/3.2.x/session_type.rb +11 -0
  171. data/lib/virtualbox/com/interface/3.2.x/shared_folder.rb +17 -0
  172. data/lib/virtualbox/com/interface/3.2.x/snapshot.rb +20 -0
  173. data/lib/virtualbox/com/interface/3.2.x/storage_bus.rb +11 -0
  174. data/lib/virtualbox/com/interface/3.2.x/storage_controller.rb +24 -0
  175. data/lib/virtualbox/com/interface/3.2.x/storage_controller_type.rb +11 -0
  176. data/lib/virtualbox/com/interface/3.2.x/system_properties.rb +42 -0
  177. data/lib/virtualbox/com/interface/3.2.x/usb_controller.rb +21 -0
  178. data/lib/virtualbox/com/interface/3.2.x/usb_device.rb +24 -0
  179. data/lib/virtualbox/com/interface/3.2.x/usb_device_filter.rb +23 -0
  180. data/lib/virtualbox/com/interface/3.2.x/usb_device_filter_action.rb +11 -0
  181. data/lib/virtualbox/com/interface/3.2.x/usb_device_state.rb +11 -0
  182. data/lib/virtualbox/com/interface/3.2.x/virtual_box_error_info.rb +17 -0
  183. data/lib/virtualbox/com/interface/3.2.x/virtual_system_description.rb +19 -0
  184. data/lib/virtualbox/com/interface/3.2.x/virtual_system_description_type.rb +14 -0
  185. data/lib/virtualbox/com/interface/3.2.x/virtual_system_description_value_type.rb +11 -0
  186. data/lib/virtualbox/com/interface/3.2.x/virtualbox.rb +67 -0
  187. data/lib/virtualbox/com/interface/3.2.x/vrdp_auth_type.rb +11 -0
  188. data/lib/virtualbox/com/interface/3.2.x/vrdp_server.rb +21 -0
  189. data/lib/virtualbox/com/mscom_interface.rb +44 -0
  190. data/lib/virtualbox/com/nil_interface.rb +7 -0
  191. data/lib/virtualbox/com/util.rb +32 -0
  192. data/lib/virtualbox/cpu.rb +61 -0
  193. data/lib/virtualbox/dhcp_server.rb +89 -0
  194. data/lib/virtualbox/dvd.rb +27 -0
  195. data/lib/virtualbox/exceptions.rb +39 -0
  196. data/lib/virtualbox/ext/byte_normalizer.rb +17 -0
  197. data/lib/virtualbox/ext/glob_loader.rb +22 -0
  198. data/lib/virtualbox/ext/logger.rb +38 -0
  199. data/lib/virtualbox/ext/platform.rb +27 -0
  200. data/lib/virtualbox/ext/subclass_listing.rb +24 -0
  201. data/lib/virtualbox/extra_data.rb +127 -0
  202. data/lib/virtualbox/forwarded_port.rb +222 -0
  203. data/lib/virtualbox/global.rb +102 -0
  204. data/lib/virtualbox/guest_property.rb +116 -0
  205. data/lib/virtualbox/hard_drive.rb +246 -0
  206. data/lib/virtualbox/host.rb +71 -0
  207. data/lib/virtualbox/host_network_interface.rb +137 -0
  208. data/lib/virtualbox/hw_virtualization.rb +63 -0
  209. data/lib/virtualbox/lib.rb +84 -0
  210. data/lib/virtualbox/media.rb +20 -0
  211. data/lib/virtualbox/medium.rb +145 -0
  212. data/lib/virtualbox/medium_attachment.rb +61 -0
  213. data/lib/virtualbox/nat_engine.rb +71 -0
  214. data/lib/virtualbox/nat_forwarded_port.rb +171 -0
  215. data/lib/virtualbox/network_adapter.rb +166 -0
  216. data/lib/virtualbox/proxies/collection.rb +57 -0
  217. data/lib/virtualbox/shared_folder.rb +220 -0
  218. data/lib/virtualbox/snapshot.rb +185 -0
  219. data/lib/virtualbox/storage_controller.rb +160 -0
  220. data/lib/virtualbox/system_properties.rb +74 -0
  221. data/lib/virtualbox/usb_controller.rb +59 -0
  222. data/lib/virtualbox/usb_device_filter.rb +74 -0
  223. data/lib/virtualbox/version.rb +36 -0
  224. data/lib/virtualbox/virtual_system_description.rb +47 -0
  225. data/lib/virtualbox/vm.rb +684 -0
  226. data/lib/virtualbox/vrdp_server.rb +59 -0
  227. data/test/test_helper.rb +18 -0
  228. data/test/virtualbox/abstract_model/attributable_test.rb +269 -0
  229. data/test/virtualbox/abstract_model/dirty_test.rb +83 -0
  230. data/test/virtualbox/abstract_model/interface_attributes_test.rb +194 -0
  231. data/test/virtualbox/abstract_model/relatable_test.rb +348 -0
  232. data/test/virtualbox/abstract_model/validatable_test.rb +308 -0
  233. data/test/virtualbox/abstract_model/version_matcher_test.rb +41 -0
  234. data/test/virtualbox/abstract_model_test.rb +462 -0
  235. data/test/virtualbox/appliance_test.rb +159 -0
  236. data/test/virtualbox/audio_adapter_test.rb +83 -0
  237. data/test/virtualbox/bios_test.rb +83 -0
  238. data/test/virtualbox/com/abstract_enum_test.rb +49 -0
  239. data/test/virtualbox/com/abstract_implementer_test.rb +40 -0
  240. data/test/virtualbox/com/abstract_interface_test.rb +140 -0
  241. data/test/virtualbox/com/ffi/interface_test.rb +249 -0
  242. data/test/virtualbox/com/ffi/util_test.rb +108 -0
  243. data/test/virtualbox/com/ffi_interface_test.rb +42 -0
  244. data/test/virtualbox/com/implementer/base_test.rb +38 -0
  245. data/test/virtualbox/com/implementer/ffi_test.rb +527 -0
  246. data/test/virtualbox/com/implementer/mscom_test.rb +247 -0
  247. data/test/virtualbox/com/mscom_interface_test.rb +17 -0
  248. data/test/virtualbox/com/util_test.rb +17 -0
  249. data/test/virtualbox/cpu_test.rb +103 -0
  250. data/test/virtualbox/dhcp_server_test.rb +165 -0
  251. data/test/virtualbox/dvd_test.rb +28 -0
  252. data/test/virtualbox/ext/byte_normalizer_test.rb +34 -0
  253. data/test/virtualbox/ext/platform_test.rb +50 -0
  254. data/test/virtualbox/ext/subclass_listing_test.rb +25 -0
  255. data/test/virtualbox/extra_data_test.rb +155 -0
  256. data/test/virtualbox/forwarded_port_test.rb +286 -0
  257. data/test/virtualbox/global_test.rb +46 -0
  258. data/test/virtualbox/hard_drive_test.rb +141 -0
  259. data/test/virtualbox/host_network_interface_test.rb +254 -0
  260. data/test/virtualbox/host_test.rb +94 -0
  261. data/test/virtualbox/hw_virtualization_test.rb +103 -0
  262. data/test/virtualbox/lib_test.rb +93 -0
  263. data/test/virtualbox/medium_attachment_test.rb +147 -0
  264. data/test/virtualbox/medium_test.rb +192 -0
  265. data/test/virtualbox/nat_engine_test.rb +106 -0
  266. data/test/virtualbox/nat_forwarded_port_test.rb +222 -0
  267. data/test/virtualbox/network_adapter_test.rb +191 -0
  268. data/test/virtualbox/proxies/collection_test.rb +102 -0
  269. data/test/virtualbox/shared_folder_test.rb +219 -0
  270. data/test/virtualbox/snapshot_test.rb +231 -0
  271. data/test/virtualbox/storage_controller_test.rb +197 -0
  272. data/test/virtualbox/system_properties_test.rb +87 -0
  273. data/test/virtualbox/usb_controller_test.rb +112 -0
  274. data/test/virtualbox/usb_device_filter_test.rb +93 -0
  275. data/test/virtualbox/version_test.rb +59 -0
  276. data/test/virtualbox/virtual_system_description_test.rb +61 -0
  277. data/test/virtualbox/vm_test.rb +637 -0
  278. data/test/virtualbox/vrdp_server_test.rb +83 -0
  279. data/test/virtualbox_test.rb +11 -0
  280. data/virtualbox.gemspec +25 -0
  281. metadata +397 -0
@@ -0,0 +1,249 @@
1
+ require File.expand_path("../../../../test_helper", __FILE__)
2
+
3
+ class COMFFIInterfaceTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::COM::FFI::Interface
6
+ @interface = mock("interface")
7
+ @parent = mock("parent")
8
+ end
9
+
10
+ context "specifying a com interface" do
11
+ setup do
12
+ @com_interface = mock("com_interface")
13
+ VirtualBox::COM::Util.stubs(:versioned_interface).returns(@com_interface)
14
+ @klass.stubs(:define_vtbl_parent_for_interface)
15
+ @klass.stubs(:define_vtbl_for_interface)
16
+ end
17
+
18
+ should "get the interface with respect to the COM interfaces" do
19
+ VirtualBox::COM::Util.expects(:versioned_interface).with(@interface).returns(@com_interface)
20
+ @klass.com_interface(@interface, @parent)
21
+ end
22
+
23
+ should "define the vtbl parent and vtbl" do
24
+ @klass.expects(:define_vtbl_parent_for_interface).with(@com_interface)
25
+ @klass.expects(:define_vtbl_for_interface).with(@com_interface, @parent)
26
+ @klass.com_interface(@interface, @parent)
27
+ end
28
+ end
29
+
30
+ context "defining the vtbl parent class" do
31
+ setup do
32
+ @klass.layout_args.clear
33
+ end
34
+
35
+ should "create a basic struct with a pointer" do
36
+ @klass.expects(:const_set).with() do |name, klass|
37
+ assert_equal "VtblParent", name
38
+ assert_equal FFI::Struct, klass.superclass
39
+
40
+ true
41
+ end
42
+
43
+ @klass.define_vtbl_parent_for_interface(@interface)
44
+ end
45
+ end
46
+
47
+ context "defining the vtbl class" do
48
+ setup do
49
+ @klass.layout_args.clear
50
+
51
+ @klass.stubs(:define_interface_parent)
52
+ @klass.stubs(:define_interface_functions)
53
+ @klass.stubs(:define_interface_properties)
54
+ end
55
+
56
+ should "define the properties then functions" do
57
+ layout_mock = mock("layout")
58
+ layout_mock.stubs(:layout)
59
+ @klass.stubs(:const_set).returns(layout_mock)
60
+
61
+ def_seq = sequence("define_seq")
62
+ @klass.expects(:define_interface_parent).once.in_sequence(def_seq)
63
+ @klass.expects(:define_interface_properties).once.in_sequence(def_seq)
64
+ @klass.expects(:define_interface_functions).once.in_sequence(def_seq)
65
+ @klass.define_vtbl_for_interface(@interface)
66
+ end
67
+
68
+ should "define the constant with the proper class" do
69
+ layout_args = [[:foo], :bar]
70
+ layout_args.stubs(:clear) # Don't let the method overwrite them
71
+
72
+ klass = mock("klass")
73
+ klass.expects(:layout).with(*layout_args.flatten).once
74
+ Class.expects(:new).with(::FFI::Struct).returns(klass)
75
+ @klass.stubs(:layout_args).returns(layout_args)
76
+
77
+ @klass.expects(:const_set).with() do |name, set_klass|
78
+ assert_equal "Vtbl", name
79
+ assert_equal klass, set_klass
80
+
81
+ true
82
+ end.returns(klass)
83
+
84
+ @klass.define_vtbl_for_interface(@interface)
85
+ end
86
+ end
87
+
88
+ context "defining the interface parent" do
89
+ should "do nothing if nil is given" do
90
+ @klass.layout_args.expects(:<<).never
91
+ assert_nothing_raised { @klass.define_interface_parent(nil) }
92
+ end
93
+
94
+ should "get the class in the context of the FFI namespace" do
95
+ name = :foo
96
+ klass = mock("klass")
97
+ Object.expects(:module_eval).with("::VirtualBox::COM::FFI::#{VirtualBox::COM::Util.version_const}::#{name}::Vtbl").returns(klass)
98
+ @klass.layout_args.expects(:<<).with([:superklass, klass])
99
+ @klass.define_interface_parent(name)
100
+ end
101
+ end
102
+
103
+ context "defining all interface functions" do
104
+ setup do
105
+ @functions = []
106
+ @interface.stubs(:functions).returns(@functions)
107
+ end
108
+
109
+ def add_function(name, type, spec, opts={})
110
+ @functions << [name, {
111
+ :value_type => type,
112
+ :spec => spec,
113
+ :opts => opts
114
+ }]
115
+ end
116
+
117
+ should "define a function for the function" do
118
+ name = :foo
119
+ type = :bar
120
+ spec = [:baz]
121
+ add_function(name, type, spec)
122
+
123
+ @klass.expects(:define_interface_function).with(name, type, spec).once
124
+ @klass.define_interface_functions(@interface)
125
+ end
126
+
127
+ should "define functions in order" do
128
+ add_function(:foo, :bar, [:baz])
129
+ add_function(:bar, :baz, [:foo])
130
+
131
+ def_seq = sequence('define_seq')
132
+ @functions.each do |name, opts|
133
+ type = opts[:value_type]
134
+ spec = opts[:spec]
135
+ @klass.expects(:define_interface_function).with(name, type, spec).in_sequence(def_seq)
136
+ end
137
+
138
+ @klass.define_interface_functions(@interface)
139
+ end
140
+ end
141
+
142
+ context "defining a single interface function" do
143
+ setup do
144
+ @properties = []
145
+ @interface.stubs(:properties).returns(@properties)
146
+ end
147
+
148
+ def add_property(name, type, opts={})
149
+ @properties << [name, {
150
+ :value_type => type,
151
+ :opts => opts
152
+ }]
153
+ end
154
+
155
+ should "define a getter and setter for properties" do
156
+ name = :foo
157
+ type = :int
158
+ add_property(name, type)
159
+
160
+ @klass.expects(:define_interface_function).with("get_#{name}".to_sym, type)
161
+ @klass.expects(:define_interface_function).with("set_#{name}".to_sym, nil, [type])
162
+ @klass.define_interface_properties(@interface)
163
+ end
164
+
165
+ should "not define a setter for readonly properties" do
166
+ name = :foo
167
+ type = :int
168
+ add_property(name, type, :readonly => true)
169
+
170
+ @klass.expects(:define_interface_function).with("get_#{name}".to_sym, type)
171
+ @klass.expects(:define_interface_function).with("set_#{name}".to_sym, nil, [type]).never
172
+ @klass.define_interface_properties(@interface)
173
+ end
174
+
175
+ should "add properties in order" do
176
+ add_property(:foo, :int)
177
+ add_property(:bar, :uint)
178
+
179
+ def_seq = sequence('define_seq')
180
+ @properties.each do |name, opts|
181
+ type = opts[:value_type]
182
+ @klass.expects(:define_interface_function).with("get_#{name}".to_sym, type).in_sequence(def_seq)
183
+ @klass.expects(:define_interface_function).with("set_#{name}".to_sym, nil, [type]).in_sequence(def_seq)
184
+ end
185
+
186
+ @klass.define_interface_properties(@interface)
187
+ end
188
+ end
189
+
190
+ context "defining a function" do
191
+ setup do
192
+ @klass.layout_args.clear
193
+
194
+ @name = :foo
195
+ @spec = [:unicode_string]
196
+ @ffi_spec = VirtualBox::COM::FFI::Util.spec_to_ffi(@spec)
197
+ end
198
+
199
+ should "append the return type to the spec" do
200
+ expected = VirtualBox::COM::FFI::Util.spec_to_ffi(@spec.dup.push([:out, :int]))
201
+
202
+ @klass.expects(:callback).with(@name, expected, VirtualBox::COM::FFI::NSRESULT_TYPE)
203
+ @klass.define_interface_function(@name, :int, @spec)
204
+ end
205
+
206
+ should "turn the spec into FFI parameters, and create the callback" do
207
+ @klass.expects(:callback).with(@name, @ffi_spec, VirtualBox::COM::FFI::NSRESULT_TYPE)
208
+ @klass.define_interface_function(@name, nil, @spec)
209
+ end
210
+
211
+ should "add to the layout args" do
212
+ @klass.layout_args.expects(:<<).with([@name, @name]).once
213
+ @klass.define_interface_function(@name, nil, @spec)
214
+ end
215
+ end
216
+
217
+ context "initializing" do
218
+ setup do
219
+ @pointer = mock("pointer")
220
+ end
221
+
222
+ should "initialize the vtbl structs" do
223
+ @klass.any_instance.expects(:initialize_vtbl).with(@pointer)
224
+ @klass.new(@pointer)
225
+ end
226
+ end
227
+
228
+ context "initializing vtbl" do
229
+ setup do
230
+ @pointer = mock("pointer")
231
+ @klass = VirtualBox::COM::FFI::Util.versioned_interface(:VirtualBox)
232
+ end
233
+
234
+ should "initialize the VtblParent then the Vtbl" do
235
+ vtbl_pointer = mock("vtbl_pointer")
236
+ vtbl_parent = mock("vtbl_parent")
237
+ vtbl_parent.stubs(:[]).with(:vtbl).returns(vtbl_pointer)
238
+ vtbl = mock("vtbl")
239
+
240
+ init_seq = sequence("init_seq")
241
+ @klass::VtblParent.expects(:new).with(@pointer).returns(vtbl_parent).in_sequence(init_seq)
242
+ @klass::Vtbl.expects(:new).with(vtbl_pointer).returns(vtbl).in_sequence(init_seq)
243
+
244
+ instance = @klass.new(@pointer)
245
+ assert_equal vtbl_parent, instance.vtbl_parent
246
+ assert_equal vtbl, instance.vtbl
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,108 @@
1
+ require File.expand_path("../../../../test_helper", __FILE__)
2
+
3
+ class COMFFIUtilTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::COM::FFI::Util
6
+ end
7
+
8
+ context "interface class" do
9
+ should "return the result from getting from the COM util" do
10
+ interface = mock("interface")
11
+ result = mock("result")
12
+ VirtualBox::COM::Util.expects(:versioned_interface).with(interface).returns(result)
13
+ assert_equal result, @klass.interface_klass(interface)
14
+ end
15
+ end
16
+
17
+ context "versioned interface" do
18
+ should "get the current FFI interface associated with the current version" do
19
+ result = mock("result")
20
+ version_module = mock("vmod")
21
+ interface = mock("interface")
22
+ VirtualBox::COM::FFI.expects(:const_get).with(::VirtualBox::COM::Util.version_const).returns(version_module)
23
+ version_module.expects(:const_get).with(interface).returns(result)
24
+ assert_equal result, @klass.versioned_interface(interface)
25
+ end
26
+ end
27
+
28
+ context "converting function specs to FFI parameter lists" do
29
+ def assert_spec(spec, expected)
30
+ result = @klass.spec_to_ffi(spec)
31
+ result.shift
32
+ assert_equal expected, result
33
+ end
34
+
35
+ should "leaving primitives alone" do
36
+ assert_spec([:int], [:int])
37
+ end
38
+
39
+ should "convert any out parameters to pointers" do
40
+ assert_spec([[:out, :int]], [:pointer])
41
+ end
42
+
43
+ should "convert unicode strings to pointers" do
44
+ assert_spec([:unicode_string], [:pointer])
45
+ end
46
+
47
+ should "convert COM interfaces to pointers" do
48
+ assert_spec([:VirtualBox], [:pointer])
49
+ end
50
+
51
+ should "convert enums to ints" do
52
+ assert_spec([:FirmwareType], [VirtualBox::COM::T_UINT32])
53
+ end
54
+
55
+ should "convert unknown classes to pointers" do
56
+ assert_spec([:VirtualBoxFoo], [:pointer])
57
+ end
58
+
59
+ should "convert array parameters to two params" do
60
+ assert_spec([[:unicode_string]], [VirtualBox::COM::T_UINT32, :pointer])
61
+ end
62
+
63
+ should "add a pointer at the beginning for the `this` parameter" do
64
+ assert_equal [:pointer], @klass.spec_to_ffi([])
65
+ end
66
+
67
+ should "turn arrays into multiple pointers (one for size and one for the array)" do
68
+ assert_spec([[:out, [:int]]], [:pointer, :pointer])
69
+ end
70
+ end
71
+
72
+ context "camelizing" do
73
+ should "camel case strings" do
74
+ tests = {
75
+ "foo_bar" => "FooBar",
76
+ "foobar" => "Foobar",
77
+ # Special cases below
78
+ "guest_os_type" => "GuestOSType",
79
+ "dhcp_servers" => "DHCPServers",
80
+ "dvd_images" => "DVDImages",
81
+ "usb_devices" => "USBDevices",
82
+ "ram_size" => "RAMSize",
83
+ "vram_size" => "VRAMSize",
84
+ "accelerate_3d_enabled" => "Accelerate3DEnabled",
85
+ "bios_settings" => "BIOSSettings",
86
+ "vrdp_server" => "VRDPServer",
87
+ "get_hw_virt_ex_property" => "GetHWVirtExProperty",
88
+ "query_saved_screenshot_png_size" => "QuerySavedScreenshotPNGSize",
89
+ "acpi_enabled" => "ACPIEnabled",
90
+ "io_apic_enabled" => "IOAPICEnabled",
91
+ "pxe_debug_enabled" => "PXEDebugEnabled",
92
+ "nat_foo" => "NATFoo",
93
+ "ide_emulation" => "IDEEmulation",
94
+ "create_vfs_explorer" => "CreateVFSExplorer",
95
+ "ip_address" => "IPAddress",
96
+ "max_vdi_size" => "MaxVDISize",
97
+ "cpu_count" => "CPUCount",
98
+ "recommended_hdd" => "RecommendedHDD",
99
+ "rtc_use_utc" => "RTCUseUTC",
100
+ "use_host_io_cache" => "UseHostIOCache"
101
+ }
102
+
103
+ tests.each do |arg, expected|
104
+ assert_equal expected, @klass.camelize(arg)
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path("../../../test_helper", __FILE__)
2
+
3
+ class COMFFIInterfaceBaseTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::COM::FFIInterface
6
+ end
7
+
8
+ context "class methods" do
9
+ context "setting up" do
10
+ should "set the ffi lib to the given path then attach function" do
11
+ lib = :foo
12
+
13
+ setup_seq = sequence('setup_seq')
14
+ @klass.expects(:ffi_lib).with(lib).in_sequence(setup_seq)
15
+ @klass.expects(:attach_function).with(:VBoxGetXPCOMCFunctions, anything, anything).in_sequence(setup_seq)
16
+ @klass.setup(lib)
17
+ end
18
+ end
19
+
20
+ context "creating" do
21
+ should "setup the initialize" do
22
+ lib = :foo
23
+ result = mock("result")
24
+ create_seq = sequence("create_seq")
25
+ @klass.expects(:setup).with(lib).in_sequence(create_seq)
26
+ @klass.expects(:new).returns(result).in_sequence(create_seq)
27
+ assert_equal result, @klass.create(lib)
28
+ end
29
+ end
30
+ end
31
+
32
+ context "initialization" do
33
+ should "initialize com interface" do
34
+ @klass.any_instance.expects(:initialize_com).once
35
+ @klass.new
36
+ end
37
+ end
38
+
39
+ context "initializing com interface" do
40
+ # TODO
41
+ end
42
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path("../../../../test_helper", __FILE__)
2
+
3
+ class COMImplementerBaseTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::COM::Implementer::Base
6
+ @interface = mock("interface")
7
+ @lib = mock("lib")
8
+ end
9
+
10
+ context "with an instance" do
11
+ setup do
12
+ @instance = @klass.new(@interface, @lib)
13
+ end
14
+
15
+ context "inferring types" do
16
+ should "return the proper values" do
17
+ expectations = {
18
+ :int => [:int, :int],
19
+ :unicode_string => [:pointer, :unicode_string],
20
+ :Host => [:pointer, :interface]
21
+ }
22
+
23
+ expectations.each do |original, result|
24
+ assert_equal result, @instance.infer_type(original)
25
+ end
26
+ end
27
+ end
28
+
29
+ context "getting an interface class" do
30
+ should "get from COM::Interface and return" do
31
+ result = mock("result")
32
+ type_name = :foo
33
+ VirtualBox::COM::FFI::Util.expects(:interface_klass).with(type_name).returns(result)
34
+ assert_equal result, @instance.interface_klass(type_name)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,527 @@
1
+ require File.expand_path("../../../../test_helper", __FILE__)
2
+
3
+ class COMImplementerFFITest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::COM::Implementer::FFI
6
+ @interface = mock("interface")
7
+ end
8
+
9
+ context "initializing" do
10
+ setup do
11
+ @interface.stubs(:class).returns(VirtualBox::COM::Util.versioned_interface(:Session))
12
+
13
+ @ffi = mock("ffi")
14
+
15
+ @pointer = mock("pointer")
16
+ end
17
+
18
+ should "initialize the FFI interface associated with the AbstractInterface" do
19
+ result = mock("result")
20
+ VirtualBox::COM::FFI::Util.versioned_interface(:Session).expects(:new).with(@pointer).once.returns(result)
21
+ instance = @klass.new(@interface, @ffi, @pointer)
22
+ assert_equal result, instance.ffi_interface
23
+ end
24
+ end
25
+
26
+ context "with an instance" do
27
+ setup do
28
+ @lib_base = mock("lib_base")
29
+ @ffi_interface = mock("ffi_interface")
30
+ @ffi_class = mock("ffi_class")
31
+ @pointer = mock("pointer")
32
+
33
+ @ffi_class.stubs(:new).returns(@ffi_interface)
34
+ @klass.any_instance.stubs(:ffi_class).returns(@ffi_class)
35
+
36
+ @instance = @klass.new(@interface, @lib_base, @pointer)
37
+ end
38
+
39
+ context "reading a property" do
40
+ should "call call_vtbl_function with the proper arguments" do
41
+ @instance.expects(:call_vtbl_function).with(:get_foo, [[:out, :bar]])
42
+ @instance.read_property(:foo, { :value_type => :bar })
43
+ end
44
+ end
45
+
46
+ context "writing a property" do
47
+ should "call call_vtbl_function with the proper arguments" do
48
+ @instance.expects(:call_vtbl_function).with(:set_foo, [:bar], [7])
49
+ @instance.write_property(:foo, 7, { :value_type => :bar })
50
+ end
51
+ end
52
+
53
+ context "calling a function" do
54
+ should "call call_vtbl_function with the proper arguments" do
55
+ @instance.expects(:call_vtbl_function).with(:say_hello, [:int, [:out, :string]], [1, 2, 3])
56
+ @instance.call_function(:say_hello, [1, 2, 3], {
57
+ :value_type => :string,
58
+ :spec => [:int]
59
+ })
60
+ end
61
+ end
62
+
63
+ context "calling a vtbl function" do
64
+ setup do
65
+ @vtbl = mock("vtbl")
66
+ @vtbl_parent = mock("vtbl_parent")
67
+ @ffi_interface.stubs(:vtbl).returns(@vtbl)
68
+ @ffi_interface.stubs(:vtbl_parent).returns(@vtbl_parent)
69
+
70
+ @proc = mock("proc")
71
+
72
+ @name = :foo
73
+ @spec = [:bar]
74
+ @args = [:baz]
75
+ end
76
+
77
+ should "pass in the formal args then return the values from them" do
78
+ result = mock("result")
79
+ @formal = [:foo]
80
+
81
+ @instance.expects(:spec_to_args).with(@spec, @args).returns(@formal)
82
+ @instance.expects(:call_and_check).with(@name, @vtbl_parent, *@formal)
83
+ @instance.expects(:values_from_formal_args).with(@spec, @formal).returns(result)
84
+ assert_equal result, @instance.call_vtbl_function(@name, @spec, @args)
85
+ end
86
+ end
87
+
88
+ context "function calling and error checking" do
89
+ setup do
90
+ @function = mock("function")
91
+ @function.stubs(:call).returns(0)
92
+
93
+ @name = :foo
94
+ @vtbl = { @name => @function}
95
+ @ffi_interface.stubs(:vtbl).returns(@vtbl)
96
+ end
97
+
98
+ should "raise an exception if an error occurred" do
99
+ @function.expects(:call).returns(0x8000_4002)
100
+ assert_raises(VirtualBox::Exceptions::FFIException) {
101
+ @instance.call_and_check(@name)
102
+ }
103
+ end
104
+
105
+ should "not raise an exception if an error did not occur" do
106
+ @function.expects(:call).returns(0x0000_0000)
107
+ assert_nothing_raised {
108
+ @instance.call_and_check(@name)
109
+ }
110
+ end
111
+
112
+ should "not raise an exception for NS_ERROR_NOT_IMPLEMENTED" do
113
+ @function.expects(:call).returns(0x8000_4001)
114
+ assert_nothing_raised {
115
+ @instance.call_and_check(@name)
116
+ }
117
+ end
118
+
119
+ should "forward arguments" do
120
+ @function.expects(:call).with(1,2,3).returns(0)
121
+ assert_nothing_raised {
122
+ @instance.call_and_check(@name, 1, 2, 3)
123
+ }
124
+ end
125
+ end
126
+
127
+ context "result code mapping" do
128
+ should "return a mapped exception object if it exists" do
129
+ assert_equal VirtualBox::Exceptions::ObjectNotFoundException, @instance.exception_map(0x80BB_0001)
130
+ end
131
+
132
+ should "return FFIException if no mapping is found" do
133
+ assert_equal VirtualBox::Exceptions::FFIException, @instance.exception_map(-5)
134
+ end
135
+ end
136
+
137
+ context "spec to formal argument list" do
138
+ setup do
139
+ @pointer = mock("pointer")
140
+ @instance.stubs(:pointer_for_type).returns(@pointer)
141
+ end
142
+
143
+ should "replace primitives with their types" do
144
+ assert_equal [7], @instance.spec_to_args([:int], [7])
145
+ end
146
+
147
+ should "replace booleans with 1/0" do
148
+ bool = VirtualBox::COM::T_BOOL
149
+ assert_equal [1,0], @instance.spec_to_args([bool, bool], [true, false])
150
+ end
151
+
152
+ should "replace single out items with a pointer" do
153
+ @instance.expects(:pointer_for_type).with(:foo).returns(@pointer)
154
+ assert_equal [@pointer], @instance.spec_to_args([[:out, :foo]])
155
+ end
156
+
157
+ should "convert Ruby strings into unicode strings" do
158
+ spec = [VirtualBox::COM::WSTRING]
159
+ args = ["foo"]
160
+
161
+ @instance.expects(:string_to_utf16).with(args[0]).returns("bar")
162
+ assert_equal ["bar"], @instance.spec_to_args(spec, args)
163
+ end
164
+
165
+ should "convert interfaces with nil arguments to nil" do
166
+ spec = [:Machine]
167
+ args = [nil]
168
+
169
+ assert_equal [nil], @instance.spec_to_args(spec, args)
170
+ end
171
+
172
+ should "convert enums to their property indices" do
173
+ spec = [:FirmwareType]
174
+ args = [:efi]
175
+
176
+ assert_equal [1], @instance.spec_to_args(spec, args)
177
+ end
178
+
179
+ should "replace in array types with two parameters" do
180
+ @array = [true, false, false]
181
+ assert_equal [@array.length, [1, 0, 0]], @instance.spec_to_args([[VirtualBox::COM::T_BOOL]], [@array])
182
+ end
183
+
184
+ should "replace out array types with two parameters" do
185
+ @counter_pointer = mock("count_pointer")
186
+ @pointer = mock("pointer")
187
+
188
+ @instance.expects(:pointer_for_type).with(VirtualBox::COM::T_UINT32).returns(@count_pointer)
189
+ @instance.expects(:pointer_for_type).with(:foo).returns(@pointer)
190
+ assert_equal [@count_pointer, @pointer], @instance.spec_to_args([[:out, [:foo]]])
191
+ end
192
+ end
193
+
194
+ context "values from a formal parameter list" do
195
+ should "return nil if there are no output parameters" do
196
+ spec = []
197
+ formal = []
198
+
199
+ assert_nil @instance.values_from_formal_args(spec, formal)
200
+ end
201
+
202
+ should "dereference the pointer with proper type" do
203
+ pointer = mock("pointer")
204
+ spec = [[:out, :foo]]
205
+ formal = [pointer]
206
+
207
+ result = mock("result")
208
+ @instance.expects(:dereference_pointer).with(pointer, :foo).once.returns(result)
209
+ assert_equal result, @instance.values_from_formal_args(spec, formal)
210
+ end
211
+
212
+ should "dereference the array pointer with the proper type" do
213
+ count_pointer = mock("count_pointer")
214
+ pointer = mock("pointer")
215
+ count = mock("count")
216
+ result = mock("result")
217
+ spec = [[:out, [:foo]]]
218
+ formal = [count_pointer, pointer]
219
+
220
+ @instance.expects(:dereference_pointer).with(count_pointer, VirtualBox::COM::T_UINT32).returns(count)
221
+ @instance.expects(:dereference_pointer_array).with(pointer, :foo, count).returns(result)
222
+ assert_equal result, @instance.values_from_formal_args(spec, formal)
223
+ end
224
+
225
+ should "return an array for multiple values" do
226
+ spec = [:int, [:out, :foo], [:out, :bar]]
227
+ formal = [1,2,3]
228
+
229
+ result = mock("result")
230
+ @instance.stubs(:dereference_pointer).returns(result)
231
+ assert_equal [result, result], @instance.values_from_formal_args(spec, formal)
232
+ end
233
+ end
234
+
235
+ context "pointers for type" do
236
+ setup do
237
+ @pointer = mock("pointer")
238
+ FFI::MemoryPointer.stubs(:new).returns(@pointer)
239
+ end
240
+
241
+ should "create a pointer type for the given type" do
242
+ @instance.expects(:infer_type).with(:MyType).returns([:pointer, :struct])
243
+ FFI::MemoryPointer.expects(:new).with(:pointer).once.returns(@pointer)
244
+ @instance.pointer_for_type(:MyType) do |ptr, type|
245
+ assert_equal :struct, type
246
+ end
247
+ end
248
+
249
+ should "return the result of the yield" do
250
+ expected = mock("result")
251
+ result = @instance.pointer_for_type(:int) do |ptr, type|
252
+ expected
253
+ end
254
+
255
+ assert_equal expected, result
256
+ end
257
+
258
+ should "return the pointer if no block is given" do
259
+ assert_equal @pointer, @instance.pointer_for_type(:int)
260
+ end
261
+ end
262
+
263
+ context "dereferencing pointers" do
264
+ setup do
265
+ @pointer = mock('pointer')
266
+ @pointer.stubs(:respond_to?).returns(true)
267
+ @pointer.stubs(:get_bar).returns("foo")
268
+
269
+ @type = :zoo
270
+
271
+ @c_type = :foo
272
+ @inferred_type = :bar
273
+ @instance.stubs(:infer_type).returns([@c_type, @inferred_type])
274
+ end
275
+
276
+ should "infer the type" do
277
+ @instance.expects(:infer_type).with(@type).returns([@c_type, @inferred_type])
278
+ @instance.dereference_pointer(@pointer, @type)
279
+ end
280
+
281
+ should "call get_* method on pointer if it exists" do
282
+ result = mock("result")
283
+ @pointer.expects(:respond_to?).with("get_#{@inferred_type}".to_sym).returns(true)
284
+ @pointer.expects("get_#{@inferred_type}".to_sym).with(0).returns(result)
285
+ assert_equal result, @instance.dereference_pointer(@pointer, @type)
286
+ end
287
+
288
+ should "return a false bool if type is bool and failure" do
289
+ @pointer.expects(:get_bar).returns(0)
290
+ result = @instance.dereference_pointer(@pointer, VirtualBox::COM::T_BOOL)
291
+ assert_equal false, result
292
+ end
293
+
294
+ should "return a true bool if type is bool and success" do
295
+ @pointer.expects(:get_bar).returns(1)
296
+ result = @instance.dereference_pointer(@pointer, VirtualBox::COM::T_BOOL)
297
+ assert_equal true, result
298
+ end
299
+
300
+ should "call read_* on Util if pointer doesn't support it" do
301
+ result = mock("result")
302
+ @pointer.expects(:respond_to?).with("get_#{@inferred_type}".to_sym).returns(false)
303
+ @instance.expects("read_#{@inferred_type}".to_sym).with(@pointer, @type).returns(result)
304
+ assert_equal result, @instance.dereference_pointer(@pointer, @type)
305
+ end
306
+ end
307
+
308
+ context "dereferencing pointer array" do
309
+ setup do
310
+ @array_pointer = mock('array_pointer')
311
+ @array_pointer.stubs(:respond_to?).returns(true)
312
+ @array_pointer.stubs(:get_array_of_bar)
313
+
314
+ @pointer = mock('pointer')
315
+ @pointer.stubs(:get_pointer).with(0).returns(@array_pointer)
316
+
317
+ @type = :zoo
318
+ @length = 3
319
+
320
+ @c_type = :foo
321
+ @inferred_type = :bar
322
+ @instance.stubs(:infer_type).returns([@c_type, @inferred_type])
323
+ end
324
+
325
+ should "infer the type" do
326
+ @instance.expects(:infer_type).with(@type).returns([@c_type, @inferred_type])
327
+ @instance.dereference_pointer_array(@pointer, @type, @length)
328
+ end
329
+
330
+ should "return an empty array if count is zero" do
331
+ assert_equal [], @instance.dereference_pointer_array(@pointer, @type, 0)
332
+ end
333
+
334
+ should "call get_* method on array pointer if it exists" do
335
+ result = mock("result")
336
+ @array_pointer.expects(:respond_to?).with("get_array_of_#{@inferred_type}".to_sym).returns(true)
337
+ @array_pointer.expects("get_array_of_#{@inferred_type}".to_sym).with(0, @length).returns(result)
338
+ assert_equal result, @instance.dereference_pointer_array(@pointer, @type, @length)
339
+ end
340
+
341
+ should "call read_* on Util if pointer doesn't support it" do
342
+ result = mock("result")
343
+ @array_pointer.expects(:respond_to?).with("get_array_of_#{@inferred_type}".to_sym).returns(false)
344
+ @instance.expects("read_array_of_#{@inferred_type}".to_sym).with(@array_pointer, @type, @length).returns(result)
345
+ assert_equal result, @instance.dereference_pointer_array(@pointer, @type, @length)
346
+ end
347
+ end
348
+
349
+ context "custom pointer dereferencers" do
350
+ context "reading unicode string" do
351
+ setup do
352
+ @sub_ptr = mock("sub_ptr")
353
+ @sub_ptr.stubs(:null?).returns(false)
354
+
355
+ @ptr = mock("pointer")
356
+ @ptr.stubs(:get_pointer).returns(@sub_ptr)
357
+ end
358
+
359
+ should "return empty string for null pointer" do
360
+ @sub_ptr.expects(:null?).returns(true)
361
+ @instance.expects(:utf16_to_string).never
362
+ assert_equal "", @instance.read_unicode_string(@ptr)
363
+ end
364
+
365
+ should "call utf16_to_string on the dereferenced pointer" do
366
+ result = mock("result")
367
+ @ptr.expects(:get_pointer).with(0).returns(@sub_ptr)
368
+ @instance.expects(:utf16_to_string).with(@sub_ptr).returns(result)
369
+ assert_equal result, @instance.read_unicode_string(@ptr)
370
+ end
371
+ end
372
+
373
+ context "reading interfaces" do
374
+ setup do
375
+ @original_type = :foo
376
+ @interface_klass = mock("foo_class")
377
+
378
+ @sub_ptr = mock("sub_ptr")
379
+ @sub_ptr.stubs(:null?).returns(false)
380
+
381
+ @ptr = mock("pointer")
382
+ @ptr.stubs(:get_pointer).with(0).returns(@sub_ptr)
383
+ end
384
+
385
+ should "convert type to a const and return instance" do
386
+ @instance.expects(:interface_klass).with(@original_type).returns(@interface_klass)
387
+ @interface_klass.expects(:new).with(@klass, @instance.lib, @ptr.get_pointer(0)).returns(@instance)
388
+ assert_equal @instance, @instance.read_interface(@ptr, @original_type)
389
+ end
390
+
391
+ should "return nil if pointer is null" do
392
+ @sub_ptr.expects(:null?).returns(true)
393
+ @instance.expects(:interface_klass).never
394
+ assert_nil @instance.read_interface(@ptr, @original_type)
395
+ end
396
+ end
397
+
398
+ context "reading an enum" do
399
+ setup do
400
+ @enum_klass = mock("enum_class")
401
+ @enum_klass.stubs(:[])
402
+
403
+ @original_type = :foo
404
+ @value = 7
405
+
406
+ @ptr = mock("ptr")
407
+ @ptr.stubs(:get_uint).returns(@value)
408
+ end
409
+
410
+ should "convert type to class and get the value" do
411
+ result = mock("result")
412
+ @instance.expects(:interface_klass).with(@original_type).returns(@enum_klass)
413
+ @enum_klass.expects(:[]).with(@value).returns(result)
414
+ assert_equal result, @instance.read_enum(@ptr, @original_type)
415
+ end
416
+ end
417
+
418
+ context "reading an array of enums" do
419
+ setup do
420
+ @type = :foo
421
+ @length = 3
422
+
423
+ @pointers = []
424
+ @length.times do |i|
425
+ pointer = mock("pointer#{i}")
426
+ @pointers << pointer
427
+ end
428
+
429
+ @pointer = mock("pointer")
430
+ @pointer.stubs(:get_array_of_uint).returns(@pointers)
431
+
432
+ @interface_klass = mock("foo_class")
433
+
434
+ @instance.stubs(:read_struct).returns("foo")
435
+ end
436
+
437
+ should "grab the array of pointers, then convert each to a struct" do
438
+ deref_seq = sequence("deref_seq")
439
+ @instance.expects(:interface_klass).with(@type).returns(@interface_klass)
440
+ @pointer.expects(:get_array_of_uint).with(0, @length).returns(@pointers).in_sequence(deref_seq)
441
+ return_values = @pointers.collect do |pointer|
442
+ value = "struct_of_pointer: #{pointer}"
443
+ @interface_klass.expects(:[]).with(pointer).returns(value).in_sequence(deref_seq)
444
+ value
445
+ end
446
+
447
+ assert_equal return_values, @instance.read_array_of_enum(@pointer, @type, @length)
448
+ end
449
+ end
450
+
451
+ context "reading an array of interfaces" do
452
+ setup do
453
+ @type = :foo
454
+ @length = 3
455
+
456
+ @pointers = []
457
+ @length.times do |i|
458
+ pointer = mock("pointer#{i}")
459
+ @pointers << pointer
460
+ end
461
+
462
+ @pointer = mock("pointer")
463
+ @pointer.stubs(:get_array_of_pointer).returns(@pointers)
464
+
465
+ @interface_klass = mock("foo_class")
466
+
467
+ @instance.stubs(:read_struct).returns("foo")
468
+ end
469
+
470
+ should "grab the array of pointers, then convert each to a struct" do
471
+ deref_seq = sequence("deref_seq")
472
+ @instance.expects(:interface_klass).with(@type).returns(@interface_klass)
473
+ @pointer.expects(:get_array_of_pointer).with(0, @length).returns(@pointers).in_sequence(deref_seq)
474
+ return_values = @pointers.collect do |pointer|
475
+ value = "struct_of_pointer: #{pointer}"
476
+ @interface_klass.expects(:new).with(@klass, @instance.lib, pointer).returns(value).in_sequence(deref_seq)
477
+ value
478
+ end
479
+
480
+ assert_equal return_values, @instance.read_array_of_interface(@pointer, @type, @length)
481
+ end
482
+ end
483
+
484
+ context "reading an array of unicode strings" do
485
+ setup do
486
+ @type = :foo
487
+ @length = 3
488
+
489
+ @pointers = []
490
+ @length.times do |i|
491
+ pointer = mock("pointer#{i}")
492
+ pointer.stubs(:null?).returns(false)
493
+ @pointers << pointer
494
+ end
495
+
496
+ @pointer = mock("pointer")
497
+ @pointer.stubs(:get_array_of_pointer).returns(@pointers)
498
+
499
+ @instance.stubs(:read_struct).returns("foo")
500
+ end
501
+
502
+ should "grab the array of pointers, then convert each to a UTF8 string" do
503
+ deref_seq = sequence("deref_seq")
504
+ @pointer.expects(:get_array_of_pointer).with(0, @length).returns(@pointers).in_sequence(deref_seq)
505
+ return_values = @pointers.collect do |pointer|
506
+ value = "struct_of_pointer: #{pointer}"
507
+ @instance.expects(:utf16_to_string).with(pointer).returns(value).in_sequence(deref_seq)
508
+ value
509
+ end
510
+
511
+ assert_equal return_values, @instance.read_array_of_unicode_string(@pointer, @type, @length)
512
+ end
513
+
514
+ should "treat nil pointers as nil" do
515
+ deref_seq = sequence("deref_seq")
516
+ @pointer.expects(:get_array_of_pointer).with(0, @length).returns(@pointers).in_sequence(deref_seq)
517
+ return_values = @pointers.collect do |pointer|
518
+ pointer.expects(:null?).returns(true)
519
+ nil
520
+ end
521
+
522
+ assert_equal return_values, @instance.read_array_of_unicode_string(@pointer, @type, @length)
523
+ end
524
+ end
525
+ end
526
+ end
527
+ end