cukunity 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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'