cukunity 0.1.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 (226) hide show
  1. data/.document +5 -0
  2. data/.gitmodules +0 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +60 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.md +214 -0
  8. data/Rakefile +51 -0
  9. data/Unity/Assets/Demo/Art/Buttons/down.png +0 -0
  10. data/Unity/Assets/Demo/Art/Buttons/down.png.meta +28 -0
  11. data/Unity/Assets/Demo/Art/Buttons/left.png +0 -0
  12. data/Unity/Assets/Demo/Art/Buttons/left.png.meta +28 -0
  13. data/Unity/Assets/Demo/Art/Buttons/ok.png +0 -0
  14. data/Unity/Assets/Demo/Art/Buttons/ok.png.meta +28 -0
  15. data/Unity/Assets/Demo/Art/Buttons/options.png +0 -0
  16. data/Unity/Assets/Demo/Art/Buttons/options.png.meta +28 -0
  17. data/Unity/Assets/Demo/Art/Buttons/play.png +0 -0
  18. data/Unity/Assets/Demo/Art/Buttons/play.png.meta +28 -0
  19. data/Unity/Assets/Demo/Art/Buttons/quit.png +0 -0
  20. data/Unity/Assets/Demo/Art/Buttons/quit.png.meta +28 -0
  21. data/Unity/Assets/Demo/Art/Buttons/retry.png +0 -0
  22. data/Unity/Assets/Demo/Art/Buttons/retry.png.meta +28 -0
  23. data/Unity/Assets/Demo/Art/Buttons/right.png +0 -0
  24. data/Unity/Assets/Demo/Art/Buttons/right.png.meta +28 -0
  25. data/Unity/Assets/Demo/Art/Buttons/up.png +0 -0
  26. data/Unity/Assets/Demo/Art/Buttons/up.png.meta +28 -0
  27. data/Unity/Assets/Demo/Art/Buttons.meta +2 -0
  28. data/Unity/Assets/Demo/Art/clear.png +0 -0
  29. data/Unity/Assets/Demo/Art/clear.png.meta +28 -0
  30. data/Unity/Assets/Demo/Art/options.png +0 -0
  31. data/Unity/Assets/Demo/Art/options.png.meta +28 -0
  32. data/Unity/Assets/Demo/Art/sokoban.png +0 -0
  33. data/Unity/Assets/Demo/Art/sokoban.png.meta +28 -0
  34. data/Unity/Assets/Demo/Art.meta +2 -0
  35. data/Unity/Assets/Demo/Cubes/CrateCube.mat +0 -0
  36. data/Unity/Assets/Demo/Cubes/CrateCube.mat.meta +2 -0
  37. data/Unity/Assets/Demo/Cubes/CrateCube.prefab +0 -0
  38. data/Unity/Assets/Demo/Cubes/CrateCube.prefab.meta +2 -0
  39. data/Unity/Assets/Demo/Cubes/FloorCube.mat +0 -0
  40. data/Unity/Assets/Demo/Cubes/FloorCube.mat.meta +2 -0
  41. data/Unity/Assets/Demo/Cubes/FloorCube.prefab +0 -0
  42. data/Unity/Assets/Demo/Cubes/FloorCube.prefab.meta +2 -0
  43. data/Unity/Assets/Demo/Cubes/GoalCube.mat +0 -0
  44. data/Unity/Assets/Demo/Cubes/GoalCube.mat.meta +2 -0
  45. data/Unity/Assets/Demo/Cubes/GoalCube.prefab +0 -0
  46. data/Unity/Assets/Demo/Cubes/GoalCube.prefab.meta +2 -0
  47. data/Unity/Assets/Demo/Cubes/PlayerCube.mat +0 -0
  48. data/Unity/Assets/Demo/Cubes/PlayerCube.mat.meta +2 -0
  49. data/Unity/Assets/Demo/Cubes/PlayerCube.prefab +0 -0
  50. data/Unity/Assets/Demo/Cubes/PlayerCube.prefab.meta +2 -0
  51. data/Unity/Assets/Demo/Cubes/WallCube.mat +0 -0
  52. data/Unity/Assets/Demo/Cubes/WallCube.mat.meta +2 -0
  53. data/Unity/Assets/Demo/Cubes/WallCube.prefab +0 -0
  54. data/Unity/Assets/Demo/Cubes/WallCube.prefab.meta +2 -0
  55. data/Unity/Assets/Demo/Cubes.meta +2 -0
  56. data/Unity/Assets/Demo/Resources/MainMenu.prefab +0 -0
  57. data/Unity/Assets/Demo/Resources/MainMenu.prefab.meta +2 -0
  58. data/Unity/Assets/Demo/Resources/OptionsMenu.prefab +0 -0
  59. data/Unity/Assets/Demo/Resources/OptionsMenu.prefab.meta +2 -0
  60. data/Unity/Assets/Demo/Resources.meta +2 -0
  61. data/Unity/Assets/Demo/Scripts/CameraController.js +18 -0
  62. data/Unity/Assets/Demo/Scripts/CameraController.js.meta +2 -0
  63. data/Unity/Assets/Demo/Scripts/EnterPlayerName.js +21 -0
  64. data/Unity/Assets/Demo/Scripts/EnterPlayerName.js.meta +2 -0
  65. data/Unity/Assets/Demo/Scripts/GameLeftButton.js +18 -0
  66. data/Unity/Assets/Demo/Scripts/GameLeftButton.js.meta +2 -0
  67. data/Unity/Assets/Demo/Scripts/GameQuitButton.js +6 -0
  68. data/Unity/Assets/Demo/Scripts/GameQuitButton.js.meta +2 -0
  69. data/Unity/Assets/Demo/Scripts/GameRetryButton.js +7 -0
  70. data/Unity/Assets/Demo/Scripts/GameRetryButton.js.meta +2 -0
  71. data/Unity/Assets/Demo/Scripts/GameRightButton.js +18 -0
  72. data/Unity/Assets/Demo/Scripts/GameRightButton.js.meta +2 -0
  73. data/Unity/Assets/Demo/Scripts/GameUpButton.js +18 -0
  74. data/Unity/Assets/Demo/Scripts/GameUpButton.js.meta +2 -0
  75. data/Unity/Assets/Demo/Scripts/OnTouchGUIElementDown.js +34 -0
  76. data/Unity/Assets/Demo/Scripts/OnTouchGUIElementDown.js.meta +2 -0
  77. data/Unity/Assets/Demo/Scripts/PlayerData.js +3 -0
  78. data/Unity/Assets/Demo/Scripts/PlayerData.js.meta +2 -0
  79. data/Unity/Assets/Demo/Scripts/SokobanController.js +240 -0
  80. data/Unity/Assets/Demo/Scripts/SokobanController.js.meta +2 -0
  81. data/Unity/Assets/Demo/Scripts/TakeScreenShot.js +26 -0
  82. data/Unity/Assets/Demo/Scripts/TakeScreenShot.js.meta +2 -0
  83. data/Unity/Assets/Demo/Scripts/TitleOptionsButton.js +8 -0
  84. data/Unity/Assets/Demo/Scripts/TitleOptionsButton.js.meta +2 -0
  85. data/Unity/Assets/Demo/Scripts/TitleOptionsOkButton.js +8 -0
  86. data/Unity/Assets/Demo/Scripts/TitleOptionsOkButton.js.meta +2 -0
  87. data/Unity/Assets/Demo/Scripts/TitlePlayButton.js +6 -0
  88. data/Unity/Assets/Demo/Scripts/TitlePlayButton.js.meta +2 -0
  89. data/Unity/Assets/Demo/Scripts/TitleQuitButton.js +7 -0
  90. data/Unity/Assets/Demo/Scripts/TitleQuitButton.js.meta +2 -0
  91. data/Unity/Assets/Demo/Scripts/UpdateMovesLabel.js +26 -0
  92. data/Unity/Assets/Demo/Scripts/UpdateMovesLabel.js.meta +2 -0
  93. data/Unity/Assets/Demo/Scripts/UpdatePlayerName.js +14 -0
  94. data/Unity/Assets/Demo/Scripts/UpdatePlayerName.js.meta +2 -0
  95. data/Unity/Assets/Demo/Scripts.meta +2 -0
  96. data/Unity/Assets/Demo/demo_game.unity +0 -0
  97. data/Unity/Assets/Demo/demo_game.unity.meta +2 -0
  98. data/Unity/Assets/Demo/demo_title.unity +0 -0
  99. data/Unity/Assets/Demo/demo_title.unity.meta +2 -0
  100. data/Unity/Assets/Demo.meta +2 -0
  101. data/Unity/Assets/Plugins/CukunityInstance.prefab +0 -0
  102. data/Unity/Assets/Plugins/CukunityInstance.prefab.meta +2 -0
  103. data/Unity/Assets/Plugins/CukunityServer.cs +871 -0
  104. data/Unity/Assets/Plugins/CukunityServer.cs.meta +2 -0
  105. data/Unity/Assets/Plugins/JsonFx.Json.dll +0 -0
  106. data/Unity/Assets/Plugins/JsonFx.Json.dll.meta +2 -0
  107. data/Unity/Assets/Plugins/iOS/CukunityServer.mm +242 -0
  108. data/Unity/Assets/Plugins/iOS/CukunityServer.mm.meta +2 -0
  109. data/Unity/Assets/Plugins/iOS.meta +2 -0
  110. data/Unity/Assets/Plugins.meta +2 -0
  111. data/Unity/Library/AudioManager.asset +0 -0
  112. data/Unity/Library/BuildSettings.asset +0 -0
  113. data/Unity/Library/DynamicsManager.asset +0 -0
  114. data/Unity/Library/EditorBuildSettings.asset +0 -0
  115. data/Unity/Library/EditorSettings.asset +0 -0
  116. data/Unity/Library/EditorUserBuildSettings.asset +0 -0
  117. data/Unity/Library/EditorUserSettings.asset +0 -0
  118. data/Unity/Library/InputManager.asset +0 -0
  119. data/Unity/Library/InspectorExpandedItems.asset +0 -0
  120. data/Unity/Library/MonoManager.asset +0 -0
  121. data/Unity/Library/NetworkManager.asset +0 -0
  122. data/Unity/Library/ProjectSettings.asset +0 -0
  123. data/Unity/Library/QualitySettings.asset +0 -0
  124. data/Unity/Library/TagManager.asset +0 -0
  125. data/Unity/Library/TimeManager.asset +0 -0
  126. data/Unity/ProjectSettings/AudioManager.asset +0 -0
  127. data/Unity/ProjectSettings/DynamicsManager.asset +0 -0
  128. data/Unity/ProjectSettings/EditorBuildSettings.asset +0 -0
  129. data/Unity/ProjectSettings/EditorSettings.asset +0 -0
  130. data/Unity/ProjectSettings/InputManager.asset +0 -0
  131. data/Unity/ProjectSettings/NavMeshLayers.asset +0 -0
  132. data/Unity/ProjectSettings/NetworkManager.asset +0 -0
  133. data/Unity/ProjectSettings/ProjectSettings.asset +0 -0
  134. data/Unity/ProjectSettings/QualitySettings.asset +0 -0
  135. data/Unity/ProjectSettings/TagManager.asset +0 -0
  136. data/Unity/ProjectSettings/TimeManager.asset +0 -0
  137. data/VERSION +1 -0
  138. data/bin/cukunity +7 -0
  139. data/cukunity.gemspec +298 -0
  140. data/features/get_scene_command.feature +39 -0
  141. data/features/i18n/ja/sokoban_clear.feature +109 -0
  142. data/features/install.feature +23 -0
  143. data/features/keyboard_input.feature +26 -0
  144. data/features/load_level_command.feature +36 -0
  145. data/features/run.feature +33 -0
  146. data/features/select_visible.feature +29 -0
  147. data/features/support/env.rb +11 -0
  148. data/features/touch_input.feature +96 -0
  149. data/lib/cukunity/cli/argument_parser.rb +103 -0
  150. data/lib/cukunity/cli/bootstrap_command.rb +39 -0
  151. data/lib/cukunity/cli/doctor_command.rb +150 -0
  152. data/lib/cukunity/cli/features_command.rb +35 -0
  153. data/lib/cukunity/cli/main.rb +18 -0
  154. data/lib/cukunity/cli/options.rb +8 -0
  155. data/lib/cukunity/cli.rb +11 -0
  156. data/lib/cukunity/cucumber/step_definitions/get_scene_command_steps.rb +37 -0
  157. data/lib/cukunity/cucumber/step_definitions/i18n/ja/get_scene_command_steps.rb +37 -0
  158. data/lib/cukunity/cucumber/step_definitions/i18n/ja/install_steps.rb +25 -0
  159. data/lib/cukunity/cucumber/step_definitions/i18n/ja/keyboard_input_steps.rb +17 -0
  160. data/lib/cukunity/cucumber/step_definitions/i18n/ja/load_level_command_steps.rb +17 -0
  161. data/lib/cukunity/cucumber/step_definitions/i18n/ja/run_steps.rb +25 -0
  162. data/lib/cukunity/cucumber/step_definitions/i18n/ja/select_visible_steps.rb +9 -0
  163. data/lib/cukunity/cucumber/step_definitions/i18n/ja/touch_input_steps.rb +19 -0
  164. data/lib/cukunity/cucumber/step_definitions/i18n/ja.rb +9 -0
  165. data/lib/cukunity/cucumber/step_definitions/install_steps.rb +33 -0
  166. data/lib/cukunity/cucumber/step_definitions/keyboard_input_steps.rb +13 -0
  167. data/lib/cukunity/cucumber/step_definitions/load_level_command_steps.rb +17 -0
  168. data/lib/cukunity/cucumber/step_definitions/run_steps.rb +32 -0
  169. data/lib/cukunity/cucumber/step_definitions/select_visible_steps.rb +15 -0
  170. data/lib/cukunity/cucumber/step_definitions/touch_input_steps.rb +18 -0
  171. data/lib/cukunity/cucumber/support/platform_helpers.rb +105 -0
  172. data/lib/cukunity/cucumber/support/spec_helpers.rb +21 -0
  173. data/lib/cukunity/cucumber/support/transforms.rb +5 -0
  174. data/lib/cukunity/cucumber/support/unity_helpers.rb +35 -0
  175. data/lib/cukunity/cucumber.rb +28 -0
  176. data/lib/cukunity/drivers/android/app.rb +43 -0
  177. data/lib/cukunity/drivers/android/appkiller/.gitignore +9 -0
  178. data/lib/cukunity/drivers/android/appkiller/AndroidManifest.xml +17 -0
  179. data/lib/cukunity/drivers/android/appkiller/ant.properties +17 -0
  180. data/lib/cukunity/drivers/android/appkiller/build.xml +85 -0
  181. data/lib/cukunity/drivers/android/appkiller/proguard.cfg +40 -0
  182. data/lib/cukunity/drivers/android/appkiller/project.properties +11 -0
  183. data/lib/cukunity/drivers/android/appkiller/res/layout/main.xml +13 -0
  184. data/lib/cukunity/drivers/android/appkiller/res/values/strings.xml +4 -0
  185. data/lib/cukunity/drivers/android/appkiller/src/cukunity/appkiller/AppKiller.java +29 -0
  186. data/lib/cukunity/drivers/android/keyboard_input.rb +149 -0
  187. data/lib/cukunity/drivers/android/keycodes.rb +531 -0
  188. data/lib/cukunity/drivers/android/monkey_client.rb +65 -0
  189. data/lib/cukunity/drivers/android/process.rb +103 -0
  190. data/lib/cukunity/drivers/android/touch_input.rb +24 -0
  191. data/lib/cukunity/drivers/android/tunnel_client_methods.rb +22 -0
  192. data/lib/cukunity/drivers/android/unity_client.rb +27 -0
  193. data/lib/cukunity/drivers/android/utils.rb +50 -0
  194. data/lib/cukunity/drivers/android.rb +9 -0
  195. data/lib/cukunity/drivers/iOS/app.rb +32 -0
  196. data/lib/cukunity/drivers/iOS/keyboard_input.rb +104 -0
  197. data/lib/cukunity/drivers/iOS/process.rb +42 -0
  198. data/lib/cukunity/drivers/iOS/touch_input.rb +18 -0
  199. data/lib/cukunity/drivers/iOS/tunnel_client_methods.rb +27 -0
  200. data/lib/cukunity/drivers/iOS/uiautomation.rb +97 -0
  201. data/lib/cukunity/drivers/iOS/uiautomation_master.rb +152 -0
  202. data/lib/cukunity/drivers/iOS/uiautomation_slave.js +238 -0
  203. data/lib/cukunity/drivers/iOS/uiautomation_slave.rb +41 -0
  204. data/lib/cukunity/drivers/iOS/unity_client.rb +27 -0
  205. data/lib/cukunity/drivers/iOS/utils.rb +46 -0
  206. data/lib/cukunity/drivers/iOS.rb +9 -0
  207. data/lib/cukunity/exceptions.rb +24 -0
  208. data/lib/cukunity/keyboard_input_methods.rb +35 -0
  209. data/lib/cukunity/request_line_response_client_methods.rb +80 -0
  210. data/lib/cukunity/tasks/cucumber.rake +22 -0
  211. data/lib/cukunity/touch_input_methods.rb +19 -0
  212. data/lib/cukunity/unity/client_methods.rb +46 -0
  213. data/lib/cukunity/unity/command_facade.rb +67 -0
  214. data/lib/cukunity/unity/component.rb +39 -0
  215. data/lib/cukunity/unity/gameobject.rb +53 -0
  216. data/lib/cukunity/unity/hint.rb +27 -0
  217. data/lib/cukunity/unity/json_container.rb +48 -0
  218. data/lib/cukunity/unity/level.rb +6 -0
  219. data/lib/cukunity/unity/scene.rb +18 -0
  220. data/lib/cukunity/unity/screen.rb +45 -0
  221. data/lib/cukunity/unity/screen_hint_methods.rb +61 -0
  222. data/lib/cukunity/unity/text_hint_methods.rb +17 -0
  223. data/lib/cukunity/unity.rb +11 -0
  224. data/lib/cukunity/utils.rb +56 -0
  225. data/lib/cukunity.rb +19 -0
  226. metadata +411 -0
@@ -0,0 +1,46 @@
1
+ require 'json'
2
+ require 'singleton'
3
+
4
+ module Cukunity
5
+ module Unity
6
+ module ClientMethods
7
+ include Cukunity::Utils
8
+ include Cukunity::Unity::CommandFacade
9
+ include Cukunity::RequestLineResponseClientMethods
10
+ alias_method :request_connect, :connect
11
+
12
+ DEFAULT_HOSTNAME = '127.0.0.1'
13
+ DEFAULT_PORT = 9921
14
+
15
+ def command(name, opts = {})
16
+ req = opts.merge({'command' => name})
17
+ res = request(req.to_json) do |line|
18
+ JSON.parse(line)
19
+ end
20
+ raise Exception::UnityCommandError.new(res['error']) if res.nil? or res.has_key?('error')
21
+ res
22
+ end
23
+
24
+ private
25
+ def connect(host = DEFAULT_HOSTNAME, port = DEFAULT_PORT)
26
+ request_connect(host, port) do |socket|
27
+ if (line = socket.gets).nil?
28
+ # close and try again
29
+ close
30
+ else
31
+ JSON.parse(line).tap do |ack|
32
+ raise Exception::UnityInvalidAck.new if ack != {}
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def self.included(base)
39
+ # include Singleton methods in the base class
40
+ base.class_eval do
41
+ include Singleton
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,67 @@
1
+ module Cukunity
2
+ module Unity
3
+ module CommandFacade
4
+ def screen
5
+ Unity::Screen.new(self, command('get_screen'))
6
+ end
7
+
8
+ def level
9
+ Unity::Level.new(command('get_level'))
10
+ end
11
+
12
+ def load_level(level, max_time = 30)
13
+ level_was_loaded = nil
14
+ options =
15
+ if level.is_a? String
16
+ level_was_loaded = lambda do
17
+ self.level.name == level
18
+ end
19
+ { 'name' => level }
20
+ else
21
+ level_was_loaded = lambda do
22
+ self.level.number == level.to_i
23
+ end
24
+ { 'number' => level.to_i }
25
+ end
26
+ Unity::Scene.new(self, command('load_level', options))
27
+ raise Exception::UnityCommandError.new if check_timeout(max_time) do
28
+ level_was_loaded.call
29
+ end
30
+ end
31
+
32
+ def scene
33
+ Unity::Scene.new(self, command('get_scene'))
34
+ end
35
+
36
+ def gameobjects
37
+ scene.gameobjects
38
+ end
39
+
40
+ def gameobject(name)
41
+ gameobjects.find do |gameobject|
42
+ gameobject.value_of('name') == name
43
+ end
44
+ end
45
+
46
+ def components(options = {})
47
+ options = merge_options(options, { :recursive => true })
48
+ gameobjects.inject([]) do |components, gameobject|
49
+ components + gameobject.components(options)
50
+ end
51
+ end
52
+
53
+ def hints(options = {})
54
+ options = merge_options(options, { :recursive => true })
55
+ gameobjects.inject([]) do |hints, gameobject|
56
+ hints + gameobject.hints(options)
57
+ end
58
+ end
59
+
60
+ def hint(options = {})
61
+ hints(options).find do |h|
62
+ yield h
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,39 @@
1
+ module Cukunity
2
+ module Unity
3
+ class Component < Unity::JSONContainer
4
+ attr_reader :gameobject
5
+
6
+ def initialize(json, gameobject)
7
+ super(json)
8
+ @gameobject = gameobject
9
+ end
10
+
11
+ def hint(*args)
12
+ hints(*args).first
13
+ end
14
+
15
+ def has_hint?(*args)
16
+ !hint(*args).nil?
17
+ end
18
+
19
+ def hints(options = {})
20
+ # memoize all hints
21
+ if @hints.nil?
22
+ @hints = (value_of('.hints') || []).inject([]) do |hints, json|
23
+ type = json[0]
24
+ values = json[1]
25
+ hints + values.map do |json|
26
+ Unity::Hint.new(json, type, self)
27
+ end
28
+ end
29
+ end
30
+ options = merge_options(options, { :type => nil })
31
+ return @hints if options[:type].nil?
32
+ # select desired hints
33
+ @hints.select do |hint|
34
+ options[:type].to_s == hint.type
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,53 @@
1
+ module Cukunity
2
+ module Unity
3
+ class GameObject < Unity::JSONContainer
4
+ attr_reader :scene
5
+ attr_reader :parent
6
+
7
+ def initialize(json, scene, parent = nil)
8
+ super(json)
9
+ @scene = scene
10
+ @parent = parent
11
+ end
12
+
13
+ def children
14
+ @children ||= (value_of('children') || []).map do |json|
15
+ Unity::GameObject.new(json, @scene, self)
16
+ end
17
+ end
18
+
19
+ def component(*args)
20
+ components(*args).first
21
+ end
22
+
23
+ def has_component?(*args)
24
+ !!component(*args)
25
+ end
26
+
27
+ def components(options = {})
28
+ # memoize all components
29
+ if @components.nil?
30
+ @components = (value_of('components') || []).map do |json|
31
+ Unity::Component.new(json, self)
32
+ end
33
+ @components += children.inject([]) do |components, child|
34
+ components + child.components(:recursive => true)
35
+ end
36
+ end
37
+ options = merge_options(options, { :recursive => false })
38
+ # select desired components
39
+ @components.select do |component|
40
+ acceptable_type = (options[:type].nil? or options[:type] == component.type)
41
+ acceptable_type and (options[:recursive] or component.gameobject == self)
42
+ end
43
+ end
44
+
45
+ def hints(options = {})
46
+ options = merge_options(options, { :recursive => false })
47
+ components(restrict_options(options, :recursive)).inject([]) do |hints, component|
48
+ hints + component.hints(options)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ module Cukunity
2
+ module Unity
3
+ class Hint < Unity::JSONContainer
4
+ include ScreenHintMethods
5
+ include TextHintMethods
6
+
7
+ attr_reader :component
8
+ attr_reader :type
9
+ attr_reader :value
10
+
11
+ def initialize(json, type, component)
12
+ super(json)
13
+ @type = type
14
+ @value = json
15
+ @component = component
16
+ end
17
+
18
+ def gameobject
19
+ component.gameobject
20
+ end
21
+
22
+ def to_s
23
+ { type.to_s => json }.to_s
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,48 @@
1
+ module Cukunity
2
+ module Unity
3
+ class JSONContainer
4
+ include Cukunity::Utils
5
+ attr_reader :json
6
+
7
+ def initialize(json)
8
+ @json = json
9
+ end
10
+
11
+ def value_of(key)
12
+ @json[key.to_s]
13
+ end
14
+
15
+ alias_method :[], :value_of
16
+ alias_method :property, :value_of
17
+
18
+ def keys
19
+ @json.keys
20
+ end
21
+
22
+ alias_method :properties, :keys
23
+
24
+ def has_key?(key)
25
+ @json.has_key?(key.to_s)
26
+ end
27
+
28
+ alias_method :has_property?, :has_key?
29
+
30
+ # inspect json structure dynamically
31
+ def method_missing(meth, *args, &block)
32
+ if json.is_a? Hash
33
+ meth = meth.to_s
34
+ return property(meth) if has_property?(meth)
35
+ if meth[-1..-1] == '?'
36
+ meth = meth[0...-1]
37
+ return !!property(meth) if has_property?(meth)
38
+ end
39
+ end
40
+ super
41
+ end
42
+
43
+ def to_s
44
+ @json.to_s
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,6 @@
1
+ module Cukunity
2
+ module Unity
3
+ class Level < Unity::JSONContainer
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,18 @@
1
+ module Cukunity
2
+ module Unity
3
+ class Scene < Unity::JSONContainer
4
+ attr_reader :client
5
+
6
+ def initialize(client, *args)
7
+ @client = client
8
+ super(*args)
9
+ end
10
+
11
+ def gameobjects
12
+ @gameobjects ||= (value_of('gameObjects') || []).map do |json|
13
+ Unity::GameObject.new(json, self)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,45 @@
1
+ module Cukunity
2
+ module Unity
3
+ class Screen < Unity::JSONContainer
4
+ attr_reader :client
5
+
6
+ def initialize(client, *args)
7
+ @client = client
8
+ super(*args)
9
+ end
10
+
11
+ def tap(pos, options = {})
12
+ options = invert_y(pos, options)
13
+ options[:type] = :tap
14
+ client.platform::TouchInput.touch_screen(options)
15
+ end
16
+
17
+ def touch_down(pos, options = {})
18
+ options = invert_y(pos, options)
19
+ options[:down] = :down
20
+ client.platform::TouchInput.touch_screen(options)
21
+ end
22
+
23
+ def touch_release(pos, options = {})
24
+ options = invert_y(pos, options)
25
+ options[:up] = :up
26
+ client.platform::TouchInput.touch_screen(options)
27
+ end
28
+
29
+ def touch_move(pos, options = {})
30
+ options = invert_y(pos, options)
31
+ options[:move] = :move
32
+ client.platform::TouchInput.touch_screen(options)
33
+ end
34
+
35
+ alias_method :touch_up, :touch_release
36
+
37
+ private
38
+ def invert_y(pos, options)
39
+ merge_options(pos, options).tap do |options|
40
+ options[:y] = value_of('height') - options[:y]
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,61 @@
1
+ module Cukunity
2
+ module Unity
3
+ module ScreenHintMethods
4
+ def screen_pos(options = {})
5
+ options = merge_options(options, { :horizontal => :center, :vertical => :center })
6
+ pos = {}
7
+ case options[:horizontal]
8
+ when :left
9
+ pos[:x] = value_of('x').to_i
10
+ when :right
11
+ pos[:x] = (value_of('x') + value_of('width')).to_i
12
+ else
13
+ pos[:x] = (value_of('x') + value_of('width') / 2).to_i
14
+ end
15
+ case options[:vertical]
16
+ when :bottom
17
+ pos[:y] = value_of('y').to_i
18
+ when :top
19
+ pos[:y] = (value_of('y') + value_of('height')).to_i
20
+ else
21
+ pos[:y] = (value_of('y') + value_of('height') / 2).to_i
22
+ end
23
+ pos
24
+ end
25
+
26
+ def rect
27
+ { :x => value_of('x'), :y => value_of('y'),
28
+ :width => value_of('width'), :height => value_of('height') }
29
+ end
30
+
31
+ def on_screen?
32
+ return false unless component.enabled? and gameobject.active?
33
+ intersects?(gameobject.scene.client.screen.json)
34
+ end
35
+
36
+ def intersects?(arg)
37
+ _rect2 =
38
+ if arg.kind_of? Hash
39
+ merge_options(arg, { :x => 0, :y => 0, :width => 0, :height => 0 })
40
+ else
41
+ arg.rect
42
+ end
43
+ _rect = self.rect
44
+ # completely to the left?
45
+ return false if (_rect[:x] + _rect[:width]) <= _rect2[:x]
46
+ # completely to the right?
47
+ return false if _rect[:x] >= (_rect2[:x] + _rect2[:width])
48
+ # completely above?
49
+ return false if (_rect[:y] + _rect[:height]) <= _rect2[:y]
50
+ # completely below?
51
+ return false if _rect[:y] >= (_rect2[:y] + _rect2[:height])
52
+ # prove by contradiction
53
+ true
54
+ end
55
+
56
+ def tap(options = {})
57
+ gameobject.scene.client.screen.tap screen_pos(options), options
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,17 @@
1
+ module Cukunity
2
+ module Unity
3
+ module TextHintMethods
4
+ def text
5
+ json
6
+ end
7
+
8
+ def reads_as?(text)
9
+ text.to_s == self.text
10
+ end
11
+
12
+ def reads_like?(regexp)
13
+ !text.match(regexp).nil?
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ require 'cukunity/unity/command_facade'
2
+ require 'cukunity/unity/client_methods'
3
+ require 'cukunity/unity/json_container'
4
+ require 'cukunity/unity/screen'
5
+ require 'cukunity/unity/level'
6
+ require 'cukunity/unity/scene'
7
+ require 'cukunity/unity/gameobject'
8
+ require 'cukunity/unity/component'
9
+ require 'cukunity/unity/text_hint_methods'
10
+ require 'cukunity/unity/screen_hint_methods'
11
+ require 'cukunity/unity/hint'
@@ -0,0 +1,56 @@
1
+ require 'timeout'
2
+
3
+ module Cukunity
4
+ module Utils
5
+ def check_timeout(max_time, delay = 0.1)
6
+ start = Time.now
7
+ until yield
8
+ if (Time.now > (start + max_time))
9
+ return true
10
+ end
11
+ sleep delay
12
+ end
13
+ false
14
+ end
15
+
16
+ # adapted from Rails
17
+ def to_options(hash)
18
+ raise "Expected a hash but got a #{hash.class}" unless hash.instance_of? Hash
19
+ hash_dup = hash.dup
20
+ hash_dup.keys.each do |key|
21
+ hash_dup[(key.to_sym rescue key) || key] = hash_dup.delete(key)
22
+ end
23
+ hash_dup
24
+ end
25
+
26
+ def merge_options(options, defaults = {})
27
+ to_options(defaults).merge(to_options(options))
28
+ end
29
+
30
+ def restrict_options(options, *restricted_keys)
31
+ restricted_keys = restricted_keys.map do |key|
32
+ (key.to_sym rescue key) || key
33
+ end
34
+ to_options(options).delete_if do |key, value|
35
+ !restricted_keys.include?(key)
36
+ end
37
+ end
38
+
39
+ def wait_connectivity(host, port, max_time)
40
+ begin
41
+ Timeout::timeout(max_time) do
42
+ begin
43
+ s = TCPSocket.new(host, port)
44
+ s.close
45
+ true
46
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
47
+ sleep 0.1
48
+ retry
49
+ end
50
+ end
51
+ rescue Timeout::Error
52
+ false
53
+ end
54
+ end
55
+ end
56
+ end
data/lib/cukunity.rb ADDED
@@ -0,0 +1,19 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'json'
5
+ require 'rspec'
6
+ require 'cucumber'
7
+
8
+ module Cukunity
9
+ end
10
+
11
+ $:.unshift(File.dirname(__FILE__))
12
+ require 'cukunity/exceptions'
13
+ require 'cukunity/utils'
14
+ require 'cukunity/request_line_response_client_methods'
15
+ require 'cukunity/touch_input_methods'
16
+ require 'cukunity/keyboard_input_methods'
17
+ require 'cukunity/unity'
18
+ require 'cukunity/drivers/android'
19
+ require 'cukunity/drivers/iOS'