qml 0.0.1

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 (170) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +46 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +15 -0
  5. data/.yardopts +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +351 -0
  9. data/Rakefile +6 -0
  10. data/examples/assets/fonts/fontawesome-webfont.ttf +0 -0
  11. data/examples/fizzbuzz/fizzbuzz.rb +43 -0
  12. data/examples/fizzbuzz/main.qml +38 -0
  13. data/examples/imageprovider/imageprovider.rb +57 -0
  14. data/examples/imageprovider/main.qml +51 -0
  15. data/examples/todo/main.qml +70 -0
  16. data/examples/todo/todo.rb +36 -0
  17. data/examples/twitter/main.qml +36 -0
  18. data/examples/twitter/twitter.rb +55 -0
  19. data/ext/qml/accessclass.cpp +71 -0
  20. data/ext/qml/accessclass.h +19 -0
  21. data/ext/qml/accessobject.cpp +30 -0
  22. data/ext/qml/accessobject.h +22 -0
  23. data/ext/qml/application.cpp +54 -0
  24. data/ext/qml/application.h +17 -0
  25. data/ext/qml/common.h +18 -0
  26. data/ext/qml/ext_accesssupport.cpp +77 -0
  27. data/ext/qml/ext_accesssupport.h +42 -0
  28. data/ext/qml/ext_gcmarker.cpp +39 -0
  29. data/ext/qml/ext_gcmarker.h +27 -0
  30. data/ext/qml/ext_kernel.cpp +62 -0
  31. data/ext/qml/ext_kernel.h +11 -0
  32. data/ext/qml/ext_metaobject.cpp +410 -0
  33. data/ext/qml/ext_metaobject.h +62 -0
  34. data/ext/qml/ext_pluginloader.cpp +55 -0
  35. data/ext/qml/ext_pluginloader.h +32 -0
  36. data/ext/qml/ext_pointer.cpp +134 -0
  37. data/ext/qml/ext_pointer.h +43 -0
  38. data/ext/qml/ext_testutil.cpp +42 -0
  39. data/ext/qml/ext_testutil.h +11 -0
  40. data/ext/qml/extconf.rb +84 -0
  41. data/ext/qml/foreignclass.cpp +72 -0
  42. data/ext/qml/foreignclass.h +88 -0
  43. data/ext/qml/foreignmetaobject.cpp +345 -0
  44. data/ext/qml/foreignmetaobject.h +46 -0
  45. data/ext/qml/foreignobject.cpp +22 -0
  46. data/ext/qml/foreignobject.h +21 -0
  47. data/ext/qml/functioninfo.h +16 -0
  48. data/ext/qml/init.cpp +69 -0
  49. data/ext/qml/listmodel.cpp +112 -0
  50. data/ext/qml/listmodel.h +43 -0
  51. data/ext/qml/markable.h +12 -0
  52. data/ext/qml/objectdata.cpp +26 -0
  53. data/ext/qml/objectdata.h +20 -0
  54. data/ext/qml/objectgc.cpp +69 -0
  55. data/ext/qml/objectgc.h +28 -0
  56. data/ext/qml/plugins/core/applicationextension.cpp +34 -0
  57. data/ext/qml/plugins/core/applicationextension.h +28 -0
  58. data/ext/qml/plugins/core/componentextension.cpp +41 -0
  59. data/ext/qml/plugins/core/componentextension.h +28 -0
  60. data/ext/qml/plugins/core/contextextension.cpp +39 -0
  61. data/ext/qml/plugins/core/contextextension.h +29 -0
  62. data/ext/qml/plugins/core/core.pro +29 -0
  63. data/ext/qml/plugins/core/coreplugin.cpp +87 -0
  64. data/ext/qml/plugins/core/coreplugin.h +49 -0
  65. data/ext/qml/plugins/core/engineextension.cpp +27 -0
  66. data/ext/qml/plugins/core/engineextension.h +28 -0
  67. data/ext/qml/plugins/core/imageprovider.cpp +38 -0
  68. data/ext/qml/plugins/core/imageprovider.h +18 -0
  69. data/ext/qml/plugins/core/imagerequestpromise.cpp +19 -0
  70. data/ext/qml/plugins/core/imagerequestpromise.h +21 -0
  71. data/ext/qml/plugins/core/qmlexception.cpp +11 -0
  72. data/ext/qml/plugins/core/qmlexception.h +17 -0
  73. data/ext/qml/plugins/testutil/objectlifechecker.cpp +17 -0
  74. data/ext/qml/plugins/testutil/objectlifechecker.h +24 -0
  75. data/ext/qml/plugins/testutil/ownershiptest.cpp +26 -0
  76. data/ext/qml/plugins/testutil/ownershiptest.h +30 -0
  77. data/ext/qml/plugins/testutil/testobject.cpp +6 -0
  78. data/ext/qml/plugins/testutil/testobject.h +108 -0
  79. data/ext/qml/plugins/testutil/testobjectsubclass.cpp +10 -0
  80. data/ext/qml/plugins/testutil/testobjectsubclass.h +19 -0
  81. data/ext/qml/plugins/testutil/testutil.pro +20 -0
  82. data/ext/qml/plugins/testutil/testutilplugin.cpp +47 -0
  83. data/ext/qml/plugins/testutil/testutilplugin.h +32 -0
  84. data/ext/qml/qmltyperegisterer.cpp +74 -0
  85. data/ext/qml/qmltyperegisterer.h +30 -0
  86. data/ext/qml/rubyclass.cpp +94 -0
  87. data/ext/qml/rubyclass.h +234 -0
  88. data/ext/qml/rubyvalue.cpp +690 -0
  89. data/ext/qml/rubyvalue.h +256 -0
  90. data/ext/qml/signalforwarder.cpp +66 -0
  91. data/ext/qml/signalforwarder.h +29 -0
  92. data/ext/qml/util.cpp +120 -0
  93. data/ext/qml/util.h +101 -0
  94. data/ext/qml/valuereference.cpp +50 -0
  95. data/ext/qml/valuereference.h +22 -0
  96. data/ext/qml/weakvaluereference.cpp +27 -0
  97. data/ext/qml/weakvaluereference.h +19 -0
  98. data/lib/qml.rb +41 -0
  99. data/lib/qml/access.rb +137 -0
  100. data/lib/qml/application.rb +139 -0
  101. data/lib/qml/class_builder.rb +126 -0
  102. data/lib/qml/component.rb +53 -0
  103. data/lib/qml/context.rb +71 -0
  104. data/lib/qml/data.rb +2 -0
  105. data/lib/qml/data/array_model.rb +103 -0
  106. data/lib/qml/data/error.rb +5 -0
  107. data/lib/qml/data/list_model.rb +146 -0
  108. data/lib/qml/dispatchable.rb +34 -0
  109. data/lib/qml/dispatcher.rb +61 -0
  110. data/lib/qml/engine.rb +54 -0
  111. data/lib/qml/error_converter.rb +15 -0
  112. data/lib/qml/errors.rb +26 -0
  113. data/lib/qml/geometry.rb +3 -0
  114. data/lib/qml/geometry/point.rb +5 -0
  115. data/lib/qml/geometry/rectangle.rb +5 -0
  116. data/lib/qml/geometry/size.rb +5 -0
  117. data/lib/qml/image_provider.rb +87 -0
  118. data/lib/qml/meta_object.rb +20 -0
  119. data/lib/qml/models.rb +1 -0
  120. data/lib/qml/name_helper.rb +12 -0
  121. data/lib/qml/platform.rb +15 -0
  122. data/lib/qml/plugin_loader.rb +46 -0
  123. data/lib/qml/plugins.rb +26 -0
  124. data/lib/qml/qml.rb +1 -0
  125. data/lib/qml/qt.rb +6 -0
  126. data/lib/qml/qt_classes.rb +9 -0
  127. data/lib/qml/qt_object_base.rb +108 -0
  128. data/lib/qml/reactive.rb +8 -0
  129. data/lib/qml/reactive/bindable.rb +79 -0
  130. data/lib/qml/reactive/chained_signal.rb +25 -0
  131. data/lib/qml/reactive/error.rb +5 -0
  132. data/lib/qml/reactive/object.rb +278 -0
  133. data/lib/qml/reactive/property.rb +19 -0
  134. data/lib/qml/reactive/signal.rb +116 -0
  135. data/lib/qml/reactive/signal_spy.rb +27 -0
  136. data/lib/qml/reactive/signals/map_signal.rb +21 -0
  137. data/lib/qml/reactive/signals/merge_signal.rb +21 -0
  138. data/lib/qml/reactive/signals/select_signal.rb +21 -0
  139. data/lib/qml/reactive/simple_property.rb +17 -0
  140. data/lib/qml/reactive/unbound_property.rb +42 -0
  141. data/lib/qml/reactive/unbound_signal.rb +51 -0
  142. data/lib/qml/root_path.rb +3 -0
  143. data/lib/qml/test_util.rb +1 -0
  144. data/lib/qml/test_util/object_life_checker.rb +17 -0
  145. data/lib/qml/version.rb +3 -0
  146. data/lib/qml/wrappable.rb +9 -0
  147. data/qml.gemspec +28 -0
  148. data/spec/assets/testobj.qml +5 -0
  149. data/spec/qml/.access_spec.rb.swp +0 -0
  150. data/spec/qml/access_spec.rb +162 -0
  151. data/spec/qml/application_spec.rb +43 -0
  152. data/spec/qml/component_spec.rb +44 -0
  153. data/spec/qml/context_spec.rb +43 -0
  154. data/spec/qml/conversion_spec.rb +59 -0
  155. data/spec/qml/data/array_model_spec.rb +215 -0
  156. data/spec/qml/dispatchable_spec.rb +26 -0
  157. data/spec/qml/dispatcher_spec.rb +48 -0
  158. data/spec/qml/geometry/point_spec.rb +4 -0
  159. data/spec/qml/geometry/rectangle_spec.rb +4 -0
  160. data/spec/qml/geometry/size_spec.rb +4 -0
  161. data/spec/qml/plugin_loader_spec.rb +33 -0
  162. data/spec/qml/qt_object_base_spec.rb +119 -0
  163. data/spec/qml/reactive/object_spec.rb +273 -0
  164. data/spec/qml/reactive/property_spec.rb +70 -0
  165. data/spec/qml/reactive/signal_spec.rb +191 -0
  166. data/spec/qml/reactive/signal_spy_spec.rb +26 -0
  167. data/spec/qml/test_object_spec.rb +186 -0
  168. data/spec/qml_spec.rb +7 -0
  169. data/spec/spec_helper.rb +5 -0
  170. metadata +321 -0
@@ -0,0 +1,19 @@
1
+ require 'qml/reactive/error'
2
+ require 'qml/reactive/simple_property'
3
+ require 'qml/reactive/bindable'
4
+
5
+ module QML
6
+ module Reactive
7
+ class Property < SimpleProperty
8
+ include Bindable
9
+
10
+ # @param initial_value the initial value.
11
+ # @yield the initial property binding (optional).
12
+ def initialize(initial_value = nil, &block)
13
+ super()
14
+ self.value = initial_value if initial_value
15
+ bind(&block) if block
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,116 @@
1
+ module QML
2
+ module Reactive
3
+
4
+ class Signal
5
+
6
+ class Connection
7
+ def initialize(signal, listener)
8
+ @signal = signal
9
+ @listener = listener
10
+ end
11
+
12
+ # Disconnects the connection.
13
+ def disconnect
14
+ @signal.disconnect(@listener)
15
+ end
16
+ end
17
+
18
+ attr_reader :arity
19
+
20
+ # Initializes the Signal.
21
+ # The signal will be variadic if an empty array is given.
22
+ # @param [Array<#to_sym>, Array<()>] params The parameter names.
23
+ def initialize(*params, variadic: false)
24
+ @listeners = []
25
+ if variadic
26
+ @params = nil
27
+ @arity = -1
28
+ else
29
+ @params = params.map(&:to_sym)
30
+ @arity = params.size
31
+ end
32
+ end
33
+
34
+ # Calls every connected procedure with given arguments.
35
+ # Raises an ArgumentError when the arity is wrong.
36
+ # @param args the arguments.
37
+ def emit(*args)
38
+ if @arity >= 0 && args.size != @arity
39
+ fail ::ArgumentError ,"wrong number of arguments for signal (#{args.size} for #{@arity})"
40
+ end
41
+ @listeners.each do |listener|
42
+ listener.call(*args)
43
+ end
44
+ end
45
+
46
+ alias_method :call, :emit
47
+ alias_method :[], :emit
48
+
49
+ # Returns the format of the parameters in the same format as Proc#parameters.
50
+ # @return [Array<Array<Symbol>>]
51
+ def parameters
52
+ @params ? @params.map { |arg| [:req, arg] } : [[:rest, :args]]
53
+ end
54
+
55
+ # Converts the signal into a Proc.
56
+ # @return [Proc]
57
+ def to_proc
58
+ method(:emit).to_proc
59
+ end
60
+
61
+ # Returns the number of connections.
62
+ # @return [Integer]
63
+ def connection_count
64
+ @listeners.size
65
+ end
66
+
67
+ # Connects a procedure.
68
+ # @yield called when #emit is called.
69
+ # @return [QML::Reactive::Signal::Connection]
70
+ def connect(&listener)
71
+ @listeners << listener
72
+ connected(listener)
73
+ Connection.new(self, listener)
74
+ end
75
+
76
+ alias_method :each, :connect
77
+
78
+ # Disconnects a procedure.
79
+ # @param listener
80
+ # @return [self]
81
+ def disconnect(listener)
82
+ @listeners.delete(listener)
83
+ disconnected(listener)
84
+ self
85
+ end
86
+
87
+ # Creates a transformed version of the signal.
88
+ # @return [QML::Reactive::Signal]
89
+ def map(&block)
90
+ Signals::MapSignal.new(self, block)
91
+ end
92
+
93
+ alias_method :collect, :map
94
+
95
+ # Creates a filtered version of the signal.
96
+ # @return [QML::Reactive::Signal]
97
+ def select(&block)
98
+ Signals::SelectSignal.new(self, block)
99
+ end
100
+
101
+ # Creates a merged signal.
102
+ # @return [QML::Reactive::Signal]
103
+ def merge(*others)
104
+ Signals::MergeSignal.new([self] + others)
105
+ end
106
+
107
+ private
108
+
109
+ def connected(listener)
110
+ end
111
+
112
+ def disconnected(listener)
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,27 @@
1
+ module QML
2
+ module Reactive
3
+
4
+ class Signal
5
+ def spy
6
+ SignalSpy.new(self)
7
+ end
8
+ end
9
+
10
+ class SignalSpy
11
+
12
+ attr_reader :args
13
+
14
+ def initialize(signal)
15
+ @args = []
16
+ signal.connect(&method(:on_emitted))
17
+ end
18
+
19
+ private
20
+
21
+ def on_emitted(*args)
22
+ @args << args
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ require 'qml/reactive/chained_signal'
2
+
3
+ module QML
4
+ module Reactive
5
+ module Signals
6
+ class MapSignal < ChainedSignal
7
+ def initialize(source, func)
8
+ super(:mapped)
9
+ @source = source
10
+ @func = func
11
+ end
12
+
13
+ def connect_to_sources
14
+ @source.connect do |*args|
15
+ emit(@func[*args])
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'qml/reactive/chained_signal'
2
+
3
+ module QML
4
+ module Reactive
5
+ module Signals
6
+ class MergeSignal < ChainedSignal
7
+ def initialize(sources)
8
+ param_count = sources.map(&:arity).max
9
+ super(*param_count.times.map { |i| :"arg#{i}" })
10
+ @sources = sources
11
+ end
12
+
13
+ def connect_to_sources
14
+ @sources.each do |source|
15
+ source.connect(&method(:emit))
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'qml/reactive/chained_signal'
2
+
3
+ module QML
4
+ module Reactive
5
+ module Signals
6
+ class SelectSignal < ChainedSignal
7
+ def initialize(source, pred)
8
+ super(*source.parameters.map(&:last))
9
+ @source = source
10
+ @pred = pred
11
+ end
12
+
13
+ def connect_to_sources
14
+ @source.connect do |*args|
15
+ emit(*args) if @pred.call(*args)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ require 'qml/reactive/signal'
2
+
3
+ module QML
4
+ module Reactive
5
+ class SimpleProperty
6
+ attr_accessor :value
7
+
8
+ # @!attribute [r] changed
9
+ # @return [QML::Reactive::Signal] The notification signal that is emitted when the value is changed
10
+ attr_reader :changed
11
+
12
+ def initialize
13
+ @changed = Signal.new(:new_value)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,42 @@
1
+ require 'qml/reactive/property'
2
+ require 'qml/reactive/unbound_signal'
3
+
4
+ module QML
5
+ module Reactive
6
+ class UnboundProperty
7
+ attr_reader :name, :initial_value, :initial_binding, :owner, :notifier_signal, :original
8
+
9
+ def initialize(name, initial_value, initial_binding, owner, factory = nil)
10
+ @name = name
11
+ @initial_value = initial_value
12
+ @initial_binding = initial_binding
13
+ @owner = owner
14
+ @notifier_signal = UnboundSignal.new(:"#{name}_changed", [:new_value], false, owner)
15
+ @factory = factory
16
+ @original = name
17
+ end
18
+
19
+ def alias(name)
20
+ notifier_signal_orig = @notifier_signal
21
+ dup.tap do |property|
22
+ property.instance_eval do
23
+ @name = name
24
+ @notifier_signal = notifier_signal_orig.alias(:"#{name}_changed")
25
+ end
26
+ end
27
+ end
28
+
29
+ def alias?
30
+ @original != @name
31
+ end
32
+
33
+ def bind(obj)
34
+ return @factory.call(obj, self) if @factory
35
+ Property.new.tap do |p|
36
+ p.value = @initial_value if @initial_value
37
+ p.bind { obj.instance_eval &@initial_binding } if @initial_binding
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,51 @@
1
+ require 'qml/reactive/signal'
2
+
3
+ module QML
4
+ module Reactive
5
+ class UnboundSignal
6
+ attr_reader :name, :owner, :original
7
+
8
+ def initialize(name, params, variadic, owner, factory = nil)
9
+ @name = name
10
+ @params = params
11
+ @variadic = variadic
12
+ @owner = owner
13
+ @factory = factory
14
+ @original = name
15
+ end
16
+
17
+ def alias(name)
18
+ dup.tap do |signal|
19
+ signal.instance_eval do
20
+ @name = name
21
+ end
22
+ end
23
+ end
24
+
25
+ def variadic?
26
+ @variadic
27
+ end
28
+
29
+ def alias?
30
+ @original != @name
31
+ end
32
+
33
+ def arity
34
+ @params ? @params.size : -1
35
+ end
36
+
37
+ def parameters
38
+ @params ? @params.map { |arg| [:req, arg] } : [[:rest, :args]]
39
+ end
40
+
41
+ def bind(obj)
42
+ return @factory.call(obj, self) if @factory
43
+ if @variadic
44
+ Signal.new(variadic: true)
45
+ else
46
+ Signal.new(*@params)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,3 @@
1
+ module QML
2
+ ROOT_PATH = Pathname.new(__FILE__) + '../../..'
3
+ end
@@ -0,0 +1 @@
1
+ require 'qml/test_util/object_life_checker'
@@ -0,0 +1,17 @@
1
+ require 'qml/plugins'
2
+
3
+ module QML
4
+ module TestUtil
5
+
6
+ ObjectLifeChecker = Plugins.test_util.meta_objects['RubyQml::ObjectLifeChecker'].build_class
7
+
8
+ class ObjectLifeChecker
9
+
10
+ def self.new(obj)
11
+ Plugins.test_util.create_object_life_checker(obj)
12
+ end
13
+ alias_method :alive?, :is_alive
14
+ alias_method :owned_by_qml?, :is_owned_by_qml
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module QML
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ module QML
2
+ module Wrappable
3
+ # @abstract
4
+ # @return [QtObjectBase] The created wrapper Qt Object
5
+ def create_wrapper
6
+ fail ::NotImplementedError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'qml/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "qml"
8
+ spec.version = QML::VERSION
9
+ spec.authors = ["Ryohei Ikegami"]
10
+ spec.email = ["iofg2100@gmail.com"]
11
+ spec.summary = %q{A QML / Qt Quick wrapper for Ruby}
12
+ spec.description = "ruby-qml provides bindings between QML and Ruby and enables you to use Qt Quick-based GUI from Ruby."
13
+ spec.homepage = "https://github.com/seanchas116/ruby-qml"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+ spec.extensions = ["ext/qml/extconf.rb"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.5"
23
+ spec.add_development_dependency "rake", "~> 10.3"
24
+ spec.add_development_dependency "rspec", "~> 3.0"
25
+ spec.add_development_dependency 'pry'
26
+ spec.add_development_dependency 'celluloid'
27
+ spec.add_development_dependency 'twitter'
28
+ end
@@ -0,0 +1,5 @@
1
+ import QtQuick 2.0
2
+
3
+ QtObject {
4
+ property string name: 'foo'
5
+ }
@@ -0,0 +1,162 @@
1
+ require 'spec_helper'
2
+
3
+ describe QML::Access do
4
+ class Foo
5
+ include QML::Access
6
+
7
+ property :text
8
+ signal :some_signal, [:arg]
9
+
10
+ def some_method(a, b)
11
+ a + b
12
+ end
13
+
14
+ def variadic_method(*args)
15
+ end
16
+ end
17
+
18
+ class Bar < Foo
19
+ def some_method(a, b)
20
+ 'overridden'
21
+ end
22
+
23
+ def bar_method
24
+ 'bar'
25
+ end
26
+ end
27
+
28
+ let(:context) { QML::Context.new }
29
+ let(:component) { QML::Component.new context: context, data: data }
30
+ let(:root) { component.create }
31
+
32
+ describe '.register_to_qml' do
33
+
34
+ context 'when namespace, version, name are given' do
35
+
36
+ class Hoge
37
+ include QML::Access
38
+
39
+ register_to_qml under: 'HogeNS', version: '1.2', name: 'Hoge'
40
+
41
+ property :text
42
+
43
+ def some_method(a, b)
44
+ a + b
45
+ end
46
+ end
47
+
48
+ let(:data) do
49
+ <<-EOS
50
+ import QtQuick 2.2
51
+ import HogeNS 1.2
52
+ Item {
53
+ id: root
54
+ property var bound: hoge.text + hoge.text
55
+ Hoge { id: hoge }
56
+ }
57
+ EOS
58
+ end
59
+ it 'registers the class as a QML type' do
60
+ expect { component.create }.not_to raise_error
61
+ end
62
+ describe 'Hoge#some_method' do
63
+ it 'returns value' do
64
+ expect(root.qml_eval('hoge.some_method(100, 200)')).to eq 300
65
+ end
66
+ end
67
+ describe 'Hoge text property' do
68
+ it 'can be used to property binding' do
69
+ root.qml_eval('hoge').text = "foo"
70
+ expect(root.qml_eval('root').bound).to eq 'foofoo'
71
+ root.qml_eval('hoge').text = "bar"
72
+ expect(root.qml_eval('root').bound).to eq 'barbar'
73
+ end
74
+ end
75
+ end
76
+
77
+ context 'when arguments are omitted' do
78
+
79
+ module HogeModule
80
+ VERSION = '0.1.0'
81
+ class Hoge
82
+ include QML::Access
83
+ register_to_qml
84
+ end
85
+ end
86
+
87
+ let(:data) do
88
+ <<-EOS
89
+ import HogeModule 0.1
90
+ Hoge {}
91
+ EOS
92
+ end
93
+
94
+ it 'guesses them from the Ruby class name, namespace and VERSION constant' do
95
+ expect { component.create }.not_to raise_error
96
+ end
97
+ end
98
+ end
99
+
100
+ context 'when used in context' do
101
+
102
+ let(:data) do
103
+ <<-EOS
104
+ import QtQuick 2.2
105
+ Item {
106
+ id: root
107
+ property string text: foo.text + foo.text
108
+ Connections {
109
+ id: connections
110
+ target: foo
111
+ property var args
112
+ onSome_signal: {
113
+ args = [arg]
114
+ }
115
+ }
116
+ }
117
+ EOS
118
+ end
119
+ let(:foo) { Foo.new }
120
+ let(:bar) { Bar.new }
121
+
122
+ before do
123
+ context[:foo] = foo
124
+ context[:bar] = bar
125
+ root
126
+ end
127
+
128
+ describe 'Foo#some_method' do
129
+ it 'returns value' do
130
+ expect(root.qml_eval('foo.some_method(100, 200)')).to eq 300
131
+ end
132
+ end
133
+ describe 'Bar#some_method' do
134
+ it 'returns value' do
135
+ expect(root.qml_eval('bar.some_method(100, 200)')).to eq 'overridden'
136
+ end
137
+ end
138
+ describe 'Foo#variadic_method' do
139
+ it 'will not be exported' do
140
+ expect { root.qml_eval('foo.variadic_method()') }.to raise_error(QML::QMLError)
141
+ end
142
+ end
143
+ describe 'Foo text property' do
144
+ it 'can get and set value' do
145
+ root.qml_eval('foo').text = 'test'
146
+ expect(root.qml_eval('foo').text).to eq 'test'
147
+ end
148
+ it 'can be used for property binding' do
149
+ foo.text = 'hoge'
150
+ expect(root.qml_eval('root.text')).to eq 'hogehoge'
151
+ foo.text = 'piyo'
152
+ expect(root.qml_eval('root.text')).to eq 'piyopiyo'
153
+ end
154
+ end
155
+ describe 'Foo some_signal signal' do
156
+ it 'can be connected' do
157
+ foo.some_signal.emit('foo')
158
+ expect(root.qml_eval('connections.args')).to eq ['foo']
159
+ end
160
+ end
161
+ end
162
+ end