virtualbox 0.5.4 → 0.6.0

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 (162) hide show
  1. data/.gitignore +2 -1
  2. data/Gemfile +1 -1
  3. data/Rakefile +1 -1
  4. data/Readme.md +5 -21
  5. data/VERSION +1 -1
  6. data/docs/WhatsNew.md +9 -47
  7. data/lib/virtualbox.rb +7 -30
  8. data/lib/virtualbox/abstract_model.rb +25 -5
  9. data/lib/virtualbox/abstract_model/attributable.rb +5 -1
  10. data/lib/virtualbox/abstract_model/dirty.rb +2 -0
  11. data/lib/virtualbox/abstract_model/interface_attributes.rb +96 -0
  12. data/lib/virtualbox/abstract_model/relatable.rb +19 -8
  13. data/lib/virtualbox/appliance.rb +59 -0
  14. data/lib/virtualbox/audio_adapter.rb +44 -0
  15. data/lib/virtualbox/bios.rb +44 -0
  16. data/lib/virtualbox/com.rb +23 -0
  17. data/lib/virtualbox/com/abstract_enum.rb +42 -0
  18. data/lib/virtualbox/com/abstract_implementer.rb +43 -0
  19. data/lib/virtualbox/com/abstract_interface.rb +165 -0
  20. data/lib/virtualbox/com/ffi/interface.rb +141 -0
  21. data/lib/virtualbox/com/ffi/interfaces.rb +42 -0
  22. data/lib/virtualbox/com/ffi/util.rb +101 -0
  23. data/lib/virtualbox/com/ffi/vboxxpcomc.rb +31 -0
  24. data/lib/virtualbox/com/ffi_interface.rb +65 -0
  25. data/lib/virtualbox/com/implementer/base.rb +52 -0
  26. data/lib/virtualbox/com/implementer/ffi.rb +350 -0
  27. data/lib/virtualbox/com/implementer/mscom.rb +165 -0
  28. data/lib/virtualbox/com/implementer/nil.rb +10 -0
  29. data/lib/virtualbox/com/interface/appliance.rb +20 -0
  30. data/lib/virtualbox/com/interface/audio_adapter.rb +13 -0
  31. data/lib/virtualbox/com/interface/audio_controller_type.rb +9 -0
  32. data/lib/virtualbox/com/interface/audio_driver_type.rb +9 -0
  33. data/lib/virtualbox/com/interface/bios_boot_menu_mode.rb +9 -0
  34. data/lib/virtualbox/com/interface/bios_settings.rb +19 -0
  35. data/lib/virtualbox/com/interface/clipboard_mode.rb +9 -0
  36. data/lib/virtualbox/com/interface/console.rb +48 -0
  37. data/lib/virtualbox/com/interface/cpu_property_type.rb +9 -0
  38. data/lib/virtualbox/com/interface/device_type.rb +9 -0
  39. data/lib/virtualbox/com/interface/dhcp_server.rb +20 -0
  40. data/lib/virtualbox/com/interface/firmware_type.rb +9 -0
  41. data/lib/virtualbox/com/interface/guest_os_type.rb +21 -0
  42. data/lib/virtualbox/com/interface/host.rb +40 -0
  43. data/lib/virtualbox/com/interface/host_network_interface.rb +28 -0
  44. data/lib/virtualbox/com/interface/host_network_interface_medium_type.rb +9 -0
  45. data/lib/virtualbox/com/interface/host_network_interface_status.rb +9 -0
  46. data/lib/virtualbox/com/interface/host_network_interface_type.rb +9 -0
  47. data/lib/virtualbox/com/interface/host_usb_device.rb +11 -0
  48. data/lib/virtualbox/com/interface/host_usb_device_filter.rb +11 -0
  49. data/lib/virtualbox/com/interface/hw_virt_ex_property_type.rb +9 -0
  50. data/lib/virtualbox/com/interface/machine.rb +103 -0
  51. data/lib/virtualbox/com/interface/machine_state.rb +12 -0
  52. data/lib/virtualbox/com/interface/medium.rb +48 -0
  53. data/lib/virtualbox/com/interface/medium_attachment.rb +16 -0
  54. data/lib/virtualbox/com/interface/medium_format.rb +16 -0
  55. data/lib/virtualbox/com/interface/medium_state.rb +9 -0
  56. data/lib/virtualbox/com/interface/medium_type.rb +9 -0
  57. data/lib/virtualbox/com/interface/medium_variant.rb +9 -0
  58. data/lib/virtualbox/com/interface/network_adapter.rb +28 -0
  59. data/lib/virtualbox/com/interface/network_adapter_type.rb +9 -0
  60. data/lib/virtualbox/com/interface/network_attachment_type.rb +9 -0
  61. data/lib/virtualbox/com/interface/nsiexception.rb +21 -0
  62. data/lib/virtualbox/com/interface/nsisupports.rb +13 -0
  63. data/lib/virtualbox/com/interface/parallel_port.rb +15 -0
  64. data/lib/virtualbox/com/interface/port_mode.rb +9 -0
  65. data/lib/virtualbox/com/interface/progress.rb +58 -0
  66. data/lib/virtualbox/com/interface/serial_port.rb +17 -0
  67. data/lib/virtualbox/com/interface/session.rb +16 -0
  68. data/lib/virtualbox/com/interface/session_state.rb +9 -0
  69. data/lib/virtualbox/com/interface/session_type.rb +9 -0
  70. data/lib/virtualbox/com/interface/shared_folder.rb +15 -0
  71. data/lib/virtualbox/com/interface/snapshot.rb +18 -0
  72. data/lib/virtualbox/com/interface/storage_bus.rb +9 -0
  73. data/lib/virtualbox/com/interface/storage_controller.rb +21 -0
  74. data/lib/virtualbox/com/interface/storage_controller_type.rb +9 -0
  75. data/lib/virtualbox/com/interface/system_properties.rb +35 -0
  76. data/lib/virtualbox/com/interface/usb_controller.rb +18 -0
  77. data/lib/virtualbox/com/interface/usb_device.rb +22 -0
  78. data/lib/virtualbox/com/interface/usb_device_filter.rb +21 -0
  79. data/lib/virtualbox/com/interface/usb_device_filter_action.rb +9 -0
  80. data/lib/virtualbox/com/interface/usb_device_state.rb +9 -0
  81. data/lib/virtualbox/com/interface/virtual_box_error_info.rb +15 -0
  82. data/lib/virtualbox/com/interface/virtual_system_description.rb +17 -0
  83. data/lib/virtualbox/com/interface/virtual_system_description_type.rb +12 -0
  84. data/lib/virtualbox/com/interface/virtual_system_description_value_type.rb +9 -0
  85. data/lib/virtualbox/com/interface/virtualbox.rb +54 -0
  86. data/lib/virtualbox/com/interface/vrdp_auth_type.rb +9 -0
  87. data/lib/virtualbox/com/interface/vrdp_server.rb +17 -0
  88. data/lib/virtualbox/com/mscom_interface.rb +22 -0
  89. data/lib/virtualbox/com/util.rb +18 -0
  90. data/lib/virtualbox/dvd.rb +7 -94
  91. data/lib/virtualbox/exceptions.rb +24 -0
  92. data/lib/virtualbox/ext/glob_loader.rb +22 -0
  93. data/lib/virtualbox/ext/logger.rb +38 -0
  94. data/lib/virtualbox/ext/platform.rb +1 -1
  95. data/lib/virtualbox/extra_data.rb +25 -37
  96. data/lib/virtualbox/forwarded_port.rb +35 -13
  97. data/lib/virtualbox/global.rb +22 -80
  98. data/lib/virtualbox/hard_drive.rb +30 -97
  99. data/lib/virtualbox/lib.rb +82 -0
  100. data/lib/virtualbox/media.rb +7 -6
  101. data/lib/virtualbox/medium.rb +138 -0
  102. data/lib/virtualbox/medium_attachment.rb +61 -0
  103. data/lib/virtualbox/network_adapter.rb +134 -0
  104. data/lib/virtualbox/shared_folder.rb +53 -78
  105. data/lib/virtualbox/storage_controller.rb +76 -20
  106. data/lib/virtualbox/system_properties.rb +74 -0
  107. data/lib/virtualbox/usb_controller.rb +55 -0
  108. data/lib/virtualbox/version.rb +15 -0
  109. data/lib/virtualbox/virtual_system_description.rb +47 -0
  110. data/lib/virtualbox/vm.rb +160 -272
  111. data/test/test_helper.rb +0 -108
  112. data/test/virtualbox/abstract_model/attributable_test.rb +7 -1
  113. data/test/virtualbox/abstract_model/dirty_test.rb +1 -1
  114. data/test/virtualbox/abstract_model/interface_attributes_test.rb +169 -0
  115. data/test/virtualbox/abstract_model/relatable_test.rb +20 -0
  116. data/test/virtualbox/abstract_model_test.rb +40 -5
  117. data/test/virtualbox/appliance_test.rb +152 -0
  118. data/test/virtualbox/audio_adapter_test.rb +83 -0
  119. data/test/virtualbox/bios_test.rb +83 -0
  120. data/test/virtualbox/com/abstract_enum_test.rb +48 -0
  121. data/test/virtualbox/com/abstract_implementer_test.rb +39 -0
  122. data/test/virtualbox/com/abstract_interface_test.rb +139 -0
  123. data/test/virtualbox/com/ffi/interface_test.rb +249 -0
  124. data/test/virtualbox/com/ffi/util_test.rb +86 -0
  125. data/test/virtualbox/com/ffi_interface_test.rb +42 -0
  126. data/test/virtualbox/com/implementer/base_test.rb +37 -0
  127. data/test/virtualbox/com/implementer/ffi_test.rb +519 -0
  128. data/test/virtualbox/com/implementer/mscom_test.rb +208 -0
  129. data/test/virtualbox/com/mscom_interface_test.rb +17 -0
  130. data/test/virtualbox/com/util_test.rb +17 -0
  131. data/test/virtualbox/dvd_test.rb +4 -95
  132. data/test/virtualbox/ext/platform_test.rb +8 -0
  133. data/test/virtualbox/extra_data_test.rb +78 -102
  134. data/test/virtualbox/forwarded_port_test.rb +57 -7
  135. data/test/virtualbox/global_test.rb +25 -115
  136. data/test/virtualbox/hard_drive_test.rb +49 -212
  137. data/test/virtualbox/lib_test.rb +93 -0
  138. data/test/virtualbox/medium_attachment_test.rb +147 -0
  139. data/test/virtualbox/medium_test.rb +192 -0
  140. data/test/virtualbox/network_adapter_test.rb +160 -0
  141. data/test/virtualbox/shared_folder_test.rb +144 -160
  142. data/test/virtualbox/storage_controller_test.rb +166 -45
  143. data/test/virtualbox/system_properties_test.rb +87 -0
  144. data/test/virtualbox/usb_controller_test.rb +104 -0
  145. data/test/virtualbox/version_test.rb +34 -0
  146. data/test/virtualbox/virtual_system_description_test.rb +61 -0
  147. data/test/virtualbox/vm_test.rb +288 -322
  148. data/test/virtualbox_test.rb +1 -9
  149. data/virtualbox.gemspec +139 -23
  150. metadata +143 -27
  151. data/lib/virtualbox/attached_device.rb +0 -249
  152. data/lib/virtualbox/command.rb +0 -109
  153. data/lib/virtualbox/image.rb +0 -137
  154. data/lib/virtualbox/nic.rb +0 -111
  155. data/lib/virtualbox/system_property.rb +0 -55
  156. data/lib/virtualbox/usb.rb +0 -72
  157. data/test/virtualbox/attached_device_test.rb +0 -303
  158. data/test/virtualbox/command_test.rb +0 -152
  159. data/test/virtualbox/image_test.rb +0 -190
  160. data/test/virtualbox/nic_test.rb +0 -76
  161. data/test/virtualbox/system_property_test.rb +0 -71
  162. data/test/virtualbox/usb_test.rb +0 -35
@@ -0,0 +1,83 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class AudioAdapterTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::AudioAdapter
6
+ @interface = mock("interface")
7
+ @parent = mock("parent")
8
+ end
9
+
10
+ context "class methods" do
11
+ context "populating relationship" do
12
+ setup do
13
+ @instance = mock("instance")
14
+ @klass.stubs(:new).returns(@instance)
15
+
16
+ @audio_adapter = mock("audio_adapter")
17
+ @interface.stubs(:audio_adapter).returns(@audio_adapter)
18
+ end
19
+
20
+ should "call new for the interface" do
21
+ @klass.expects(:new).with(nil, @audio_adapter).once.returns(@instance)
22
+ assert_equal @instance, @klass.populate_relationship(nil, @interface)
23
+ end
24
+ end
25
+
26
+ context "saving relationship" do
27
+ should "call save with the interface on the instance" do
28
+ instance = mock("instance")
29
+ instance.expects(:save).once
30
+
31
+ @klass.save_relationship(nil, instance)
32
+ end
33
+ end
34
+ end
35
+
36
+ context "initializing" do
37
+ setup do
38
+ @klass.any_instance.stubs(:load_interface_attributes)
39
+ end
40
+
41
+ should "load interface attribtues" do
42
+ @klass.any_instance.expects(:load_interface_attributes).with(@interface).once
43
+ @klass.new(@parent, @interface)
44
+ end
45
+
46
+ should "not be dirty" do
47
+ @instance = @klass.new(@parent, @interface)
48
+ assert !@instance.changed?
49
+ end
50
+
51
+ should "be existing record" do
52
+ @instance = @klass.new(@parent, @interface)
53
+ assert !@instance.new_record?
54
+ end
55
+ end
56
+
57
+ context "instance methods" do
58
+ setup do
59
+ @klass.any_instance.stubs(:load_interface_attributes)
60
+
61
+ @parent = mock("parent")
62
+ @interface = mock("interface")
63
+ @instance = @klass.new(@parent, @interface)
64
+ end
65
+
66
+ context "saving" do
67
+ setup do
68
+ @audio_adapter = mock("audio_adapter")
69
+ @session = mock("session")
70
+ @machine = mock("machine")
71
+ @machine.stubs(:audio_adapter).returns(@audio_adapter)
72
+ @session.stubs(:machine).returns(@machine)
73
+ @parent.stubs(:with_open_session).yields(@session)
74
+ end
75
+
76
+ should "save the interface settings with the new bios settings" do
77
+ save_seq = sequence("save_seq")
78
+ @instance.expects(:save_changed_interface_attributes).with(@audio_adapter).once.in_sequence(save_seq)
79
+ @instance.save
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,83 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class BIOSTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::BIOS
6
+ @interface = mock("interface")
7
+ @parent = mock("parent")
8
+ end
9
+
10
+ context "class methods" do
11
+ context "populating relationship" do
12
+ setup do
13
+ @instance = mock("instance")
14
+ @klass.stubs(:new).returns(@instance)
15
+
16
+ @bios_settings = mock("bios_settings")
17
+ @interface.stubs(:bios_settings).returns(@bios_settings)
18
+ end
19
+
20
+ should "call new for the interface" do
21
+ @klass.expects(:new).with(nil, @bios_settings).once.returns(@instance)
22
+ assert_equal @instance, @klass.populate_relationship(nil, @interface)
23
+ end
24
+ end
25
+
26
+ context "saving relationship" do
27
+ should "call save with the interface on the instance" do
28
+ instance = mock("instance")
29
+ instance.expects(:save).once
30
+
31
+ @klass.save_relationship(nil, instance)
32
+ end
33
+ end
34
+ end
35
+
36
+ context "initializing" do
37
+ setup do
38
+ @klass.any_instance.stubs(:load_interface_attributes)
39
+ end
40
+
41
+ should "load interface attribtues" do
42
+ @klass.any_instance.expects(:load_interface_attributes).with(@interface).once
43
+ @klass.new(@parent, @interface)
44
+ end
45
+
46
+ should "not be dirty" do
47
+ @instance = @klass.new(@parent, @interface)
48
+ assert !@instance.changed?
49
+ end
50
+
51
+ should "be existing record" do
52
+ @instance = @klass.new(@parent, @interface)
53
+ assert !@instance.new_record?
54
+ end
55
+ end
56
+
57
+ context "instance methods" do
58
+ setup do
59
+ @klass.any_instance.stubs(:load_interface_attributes)
60
+
61
+ @parent = mock("parent")
62
+ @interface = mock("interface")
63
+ @instance = @klass.new(@parent, @interface)
64
+ end
65
+
66
+ context "saving" do
67
+ setup do
68
+ @bios_settings = mock("bios_settings")
69
+ @session = mock("session")
70
+ @machine = mock("machine")
71
+ @machine.stubs(:bios_settings).returns(@bios_settings)
72
+ @session.stubs(:machine).returns(@machine)
73
+ @parent.stubs(:with_open_session).yields(@session)
74
+ end
75
+
76
+ should "save the interface settings with the new bios settings" do
77
+ save_seq = sequence("save_seq")
78
+ @instance.expects(:save_changed_interface_attributes).with(@bios_settings).once.in_sequence(save_seq)
79
+ @instance.save
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,48 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class COMAbstractEnumTest < Test::Unit::TestCase
4
+ context "setting up the map" do
5
+ setup do
6
+ @enum = VirtualBox::COM::AbstractEnum
7
+ @enum.reset!
8
+ end
9
+
10
+ should "set the map up and be able to access it" do
11
+ @enum.map([:a, :b, :c])
12
+ assert_equal :a, @enum[0]
13
+ assert_equal :b, @enum[1]
14
+ assert_equal :c, @enum[2]
15
+ end
16
+
17
+ should "do the reverse mapping of value to index" do
18
+ @enum.map([:a, :b, :c])
19
+ assert_equal 1, @enum.index(:b)
20
+ end
21
+
22
+ should "reset the map if another is given" do
23
+ @enum.map([:a])
24
+ @enum.map([:b])
25
+ assert_equal :b, @enum[0]
26
+ end
27
+
28
+ should "allow iterating over the enum" do
29
+ array = [:a, :b, :c]
30
+ other_array = []
31
+ @enum.map(array)
32
+ @enum.each do |item|
33
+ other_array << item
34
+ end
35
+
36
+ assert_equal array, other_array
37
+ end
38
+
39
+ should "include enumerable methods" do
40
+ array = [:a, :b, :c]
41
+ @enum.map(array)
42
+
43
+ @enum.each_with_index do |object, index|
44
+ assert_equal array[index], object
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,39 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class AbstractImplementerTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::COM::AbstractImplementer
6
+ @interface = mock("interface")
7
+ end
8
+
9
+ context "initialization" do
10
+ should "make the interface accessible" do
11
+ instance = @klass.new(@interface)
12
+ assert_equal @interface, instance.interface
13
+ end
14
+ end
15
+
16
+ context "base methods" do
17
+ setup do
18
+ @instance = @klass.new(@interface)
19
+ end
20
+
21
+ should "implement the read_property function" do
22
+ assert_nothing_raised {
23
+ @instance.read_property(:foo, :bar)
24
+ }
25
+ end
26
+
27
+ should "implement the write_property function" do
28
+ assert_nothing_raised {
29
+ @instance.write_property(:foo, :bar, :opts)
30
+ }
31
+ end
32
+
33
+ should "implement the call_function function" do
34
+ assert_nothing_raised {
35
+ @instance.call_function(:foo, [], :opts)
36
+ }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,139 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class AbstractInterfaceTest < Test::Unit::TestCase
4
+ class EmptyAITest < VirtualBox::COM::AbstractInterface
5
+ end
6
+
7
+ class BasicAITest < EmptyAITest
8
+ function :foo, :int, []
9
+ function :foo2, :int, []
10
+ property :bar, :int
11
+ property :bar2, :int
12
+ property :bar3, :int
13
+ end
14
+
15
+ setup do
16
+ @impl_instance = mock("impl_instance")
17
+ @impl = mock("implementer")
18
+ @impl.stubs(:new).returns(@impl_instance)
19
+ end
20
+
21
+ context "class methods" do
22
+ context "without any members defined" do
23
+ setup do
24
+ @klass = EmptyAITest
25
+ @klass.members.clear
26
+
27
+ @klass.stubs(:define_method)
28
+ end
29
+
30
+ should "put defined functions in the members hash" do
31
+ assert_nil @klass.member(:foo)
32
+ @klass.function(:foo, :int, :bar)
33
+ assert @klass.member(:foo)
34
+ end
35
+
36
+ should "define an method for functions" do
37
+ @klass.expects(:define_method).with(:foo)
38
+ @klass.function(:foo, :int, :bar)
39
+ end
40
+
41
+ should "put defined properties in the members hash" do
42
+ assert_nil @klass.member(:foo)
43
+ @klass.property(:foo, :bar)
44
+ assert @klass.member(:foo)
45
+ end
46
+
47
+ should "create methods for reading and writing properties" do
48
+ @klass.expects(:define_method).with(:foo).once
49
+ @klass.expects(:define_method).with(:foo=).once
50
+ @klass.property(:foo, :bar)
51
+ end
52
+
53
+ should "not creating writing method for property if its readonly" do
54
+ @klass.expects(:define_method).with(:foo=).never
55
+ @klass.property(:foo, :bar, :readonly => true)
56
+ end
57
+ end
58
+
59
+ context "with members defined" do
60
+ setup do
61
+ @klass = BasicAITest
62
+ end
63
+
64
+ should "return the properties in order" do
65
+ properties = @klass.properties
66
+ properties.collect! { |prop| prop[0] }
67
+
68
+ assert_equal [:bar, :bar2, :bar3], properties
69
+ end
70
+
71
+ should "return the functions in order" do
72
+ funcs = @klass.functions
73
+ funcs.collect! { |func| func[0] }
74
+
75
+ assert_equal [:foo, :foo2], funcs
76
+ end
77
+ end
78
+ end
79
+
80
+ context "initialization" do
81
+ should "instantiate the implementer" do
82
+ @impl.expects(:new).with() do |interface, extra|
83
+ assert interface.is_a?(VirtualBox::COM::AbstractInterface)
84
+ assert_equal :foo, extra
85
+ true
86
+ end
87
+
88
+ BasicAITest.new(@impl, :foo)
89
+ end
90
+ end
91
+
92
+ context "instance methods" do
93
+ setup do
94
+ @interface = BasicAITest.new(@impl)
95
+ end
96
+
97
+ context "checking for property existence" do
98
+ should "return true for existing properties" do
99
+ assert @interface.has_property?(:bar)
100
+ end
101
+
102
+ should "return false non-existent properties and methods" do
103
+ assert !@interface.has_property?(:foo)
104
+ end
105
+ end
106
+
107
+ context "checking for function existence" do
108
+ should "return true for existing functions" do
109
+ assert @interface.has_function?(:foo)
110
+ end
111
+
112
+ should "return false non-existent function and properties" do
113
+ assert !@interface.has_function?(:bar)
114
+ end
115
+ end
116
+
117
+ context "reading a property" do
118
+ should "call read property on the implementer and return result" do
119
+ result = mock("result")
120
+ @impl_instance.expects(:read_property).with(:bar, anything).returns(result)
121
+ assert_equal result, @interface.bar
122
+ end
123
+ end
124
+
125
+ context "calling a function" do
126
+ should "call the call function method on the implementer and return result" do
127
+ result = mock("result")
128
+ @impl_instance.expects(:call_function).with(:foo, [1, 2, 3], anything).returns(result)
129
+ assert_equal result, @interface.foo(1, 2, 3)
130
+ end
131
+ end
132
+
133
+ context "inspecting" do
134
+ should "be just the class name" do
135
+ assert_equal "#<AbstractInterfaceTest::BasicAITest>", @interface.inspect
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,249 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
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::Interface.stubs(:const_get).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::Interface.expects(:const_get).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::#{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::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