qml 0.0.1

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