qml 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +46 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/.yardopts +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +351 -0
- data/Rakefile +6 -0
- data/examples/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/examples/fizzbuzz/fizzbuzz.rb +43 -0
- data/examples/fizzbuzz/main.qml +38 -0
- data/examples/imageprovider/imageprovider.rb +57 -0
- data/examples/imageprovider/main.qml +51 -0
- data/examples/todo/main.qml +70 -0
- data/examples/todo/todo.rb +36 -0
- data/examples/twitter/main.qml +36 -0
- data/examples/twitter/twitter.rb +55 -0
- data/ext/qml/accessclass.cpp +71 -0
- data/ext/qml/accessclass.h +19 -0
- data/ext/qml/accessobject.cpp +30 -0
- data/ext/qml/accessobject.h +22 -0
- data/ext/qml/application.cpp +54 -0
- data/ext/qml/application.h +17 -0
- data/ext/qml/common.h +18 -0
- data/ext/qml/ext_accesssupport.cpp +77 -0
- data/ext/qml/ext_accesssupport.h +42 -0
- data/ext/qml/ext_gcmarker.cpp +39 -0
- data/ext/qml/ext_gcmarker.h +27 -0
- data/ext/qml/ext_kernel.cpp +62 -0
- data/ext/qml/ext_kernel.h +11 -0
- data/ext/qml/ext_metaobject.cpp +410 -0
- data/ext/qml/ext_metaobject.h +62 -0
- data/ext/qml/ext_pluginloader.cpp +55 -0
- data/ext/qml/ext_pluginloader.h +32 -0
- data/ext/qml/ext_pointer.cpp +134 -0
- data/ext/qml/ext_pointer.h +43 -0
- data/ext/qml/ext_testutil.cpp +42 -0
- data/ext/qml/ext_testutil.h +11 -0
- data/ext/qml/extconf.rb +84 -0
- data/ext/qml/foreignclass.cpp +72 -0
- data/ext/qml/foreignclass.h +88 -0
- data/ext/qml/foreignmetaobject.cpp +345 -0
- data/ext/qml/foreignmetaobject.h +46 -0
- data/ext/qml/foreignobject.cpp +22 -0
- data/ext/qml/foreignobject.h +21 -0
- data/ext/qml/functioninfo.h +16 -0
- data/ext/qml/init.cpp +69 -0
- data/ext/qml/listmodel.cpp +112 -0
- data/ext/qml/listmodel.h +43 -0
- data/ext/qml/markable.h +12 -0
- data/ext/qml/objectdata.cpp +26 -0
- data/ext/qml/objectdata.h +20 -0
- data/ext/qml/objectgc.cpp +69 -0
- data/ext/qml/objectgc.h +28 -0
- data/ext/qml/plugins/core/applicationextension.cpp +34 -0
- data/ext/qml/plugins/core/applicationextension.h +28 -0
- data/ext/qml/plugins/core/componentextension.cpp +41 -0
- data/ext/qml/plugins/core/componentextension.h +28 -0
- data/ext/qml/plugins/core/contextextension.cpp +39 -0
- data/ext/qml/plugins/core/contextextension.h +29 -0
- data/ext/qml/plugins/core/core.pro +29 -0
- data/ext/qml/plugins/core/coreplugin.cpp +87 -0
- data/ext/qml/plugins/core/coreplugin.h +49 -0
- data/ext/qml/plugins/core/engineextension.cpp +27 -0
- data/ext/qml/plugins/core/engineextension.h +28 -0
- data/ext/qml/plugins/core/imageprovider.cpp +38 -0
- data/ext/qml/plugins/core/imageprovider.h +18 -0
- data/ext/qml/plugins/core/imagerequestpromise.cpp +19 -0
- data/ext/qml/plugins/core/imagerequestpromise.h +21 -0
- data/ext/qml/plugins/core/qmlexception.cpp +11 -0
- data/ext/qml/plugins/core/qmlexception.h +17 -0
- data/ext/qml/plugins/testutil/objectlifechecker.cpp +17 -0
- data/ext/qml/plugins/testutil/objectlifechecker.h +24 -0
- data/ext/qml/plugins/testutil/ownershiptest.cpp +26 -0
- data/ext/qml/plugins/testutil/ownershiptest.h +30 -0
- data/ext/qml/plugins/testutil/testobject.cpp +6 -0
- data/ext/qml/plugins/testutil/testobject.h +108 -0
- data/ext/qml/plugins/testutil/testobjectsubclass.cpp +10 -0
- data/ext/qml/plugins/testutil/testobjectsubclass.h +19 -0
- data/ext/qml/plugins/testutil/testutil.pro +20 -0
- data/ext/qml/plugins/testutil/testutilplugin.cpp +47 -0
- data/ext/qml/plugins/testutil/testutilplugin.h +32 -0
- data/ext/qml/qmltyperegisterer.cpp +74 -0
- data/ext/qml/qmltyperegisterer.h +30 -0
- data/ext/qml/rubyclass.cpp +94 -0
- data/ext/qml/rubyclass.h +234 -0
- data/ext/qml/rubyvalue.cpp +690 -0
- data/ext/qml/rubyvalue.h +256 -0
- data/ext/qml/signalforwarder.cpp +66 -0
- data/ext/qml/signalforwarder.h +29 -0
- data/ext/qml/util.cpp +120 -0
- data/ext/qml/util.h +101 -0
- data/ext/qml/valuereference.cpp +50 -0
- data/ext/qml/valuereference.h +22 -0
- data/ext/qml/weakvaluereference.cpp +27 -0
- data/ext/qml/weakvaluereference.h +19 -0
- data/lib/qml.rb +41 -0
- data/lib/qml/access.rb +137 -0
- data/lib/qml/application.rb +139 -0
- data/lib/qml/class_builder.rb +126 -0
- data/lib/qml/component.rb +53 -0
- data/lib/qml/context.rb +71 -0
- data/lib/qml/data.rb +2 -0
- data/lib/qml/data/array_model.rb +103 -0
- data/lib/qml/data/error.rb +5 -0
- data/lib/qml/data/list_model.rb +146 -0
- data/lib/qml/dispatchable.rb +34 -0
- data/lib/qml/dispatcher.rb +61 -0
- data/lib/qml/engine.rb +54 -0
- data/lib/qml/error_converter.rb +15 -0
- data/lib/qml/errors.rb +26 -0
- data/lib/qml/geometry.rb +3 -0
- data/lib/qml/geometry/point.rb +5 -0
- data/lib/qml/geometry/rectangle.rb +5 -0
- data/lib/qml/geometry/size.rb +5 -0
- data/lib/qml/image_provider.rb +87 -0
- data/lib/qml/meta_object.rb +20 -0
- data/lib/qml/models.rb +1 -0
- data/lib/qml/name_helper.rb +12 -0
- data/lib/qml/platform.rb +15 -0
- data/lib/qml/plugin_loader.rb +46 -0
- data/lib/qml/plugins.rb +26 -0
- data/lib/qml/qml.rb +1 -0
- data/lib/qml/qt.rb +6 -0
- data/lib/qml/qt_classes.rb +9 -0
- data/lib/qml/qt_object_base.rb +108 -0
- data/lib/qml/reactive.rb +8 -0
- data/lib/qml/reactive/bindable.rb +79 -0
- data/lib/qml/reactive/chained_signal.rb +25 -0
- data/lib/qml/reactive/error.rb +5 -0
- data/lib/qml/reactive/object.rb +278 -0
- data/lib/qml/reactive/property.rb +19 -0
- data/lib/qml/reactive/signal.rb +116 -0
- data/lib/qml/reactive/signal_spy.rb +27 -0
- data/lib/qml/reactive/signals/map_signal.rb +21 -0
- data/lib/qml/reactive/signals/merge_signal.rb +21 -0
- data/lib/qml/reactive/signals/select_signal.rb +21 -0
- data/lib/qml/reactive/simple_property.rb +17 -0
- data/lib/qml/reactive/unbound_property.rb +42 -0
- data/lib/qml/reactive/unbound_signal.rb +51 -0
- data/lib/qml/root_path.rb +3 -0
- data/lib/qml/test_util.rb +1 -0
- data/lib/qml/test_util/object_life_checker.rb +17 -0
- data/lib/qml/version.rb +3 -0
- data/lib/qml/wrappable.rb +9 -0
- data/qml.gemspec +28 -0
- data/spec/assets/testobj.qml +5 -0
- data/spec/qml/.access_spec.rb.swp +0 -0
- data/spec/qml/access_spec.rb +162 -0
- data/spec/qml/application_spec.rb +43 -0
- data/spec/qml/component_spec.rb +44 -0
- data/spec/qml/context_spec.rb +43 -0
- data/spec/qml/conversion_spec.rb +59 -0
- data/spec/qml/data/array_model_spec.rb +215 -0
- data/spec/qml/dispatchable_spec.rb +26 -0
- data/spec/qml/dispatcher_spec.rb +48 -0
- data/spec/qml/geometry/point_spec.rb +4 -0
- data/spec/qml/geometry/rectangle_spec.rb +4 -0
- data/spec/qml/geometry/size_spec.rb +4 -0
- data/spec/qml/plugin_loader_spec.rb +33 -0
- data/spec/qml/qt_object_base_spec.rb +119 -0
- data/spec/qml/reactive/object_spec.rb +273 -0
- data/spec/qml/reactive/property_spec.rb +70 -0
- data/spec/qml/reactive/signal_spec.rb +191 -0
- data/spec/qml/reactive/signal_spy_spec.rb +26 -0
- data/spec/qml/test_object_spec.rb +186 -0
- data/spec/qml_spec.rb +7 -0
- data/spec/spec_helper.rb +5 -0
- metadata +321 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::PluginLoader do
|
4
|
+
|
5
|
+
let(:loader) { QML::PluginLoader.new path, 'rubyqml-testutil' }
|
6
|
+
|
7
|
+
describe 'load' do
|
8
|
+
|
9
|
+
context 'with signle path' do
|
10
|
+
let(:path) { QML::ROOT_PATH + 'ext/qml/plugins/testutil' + QML::PluginLoader.lib_filename('rubyqml-testutil') }
|
11
|
+
let(:loader) { QML::PluginLoader.new path }
|
12
|
+
it 'creates an object instance' do
|
13
|
+
loader.load
|
14
|
+
expect(loader.instance).to be_a QML::QtObjectBase
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'with correct file path' do
|
19
|
+
let(:path) { QML::ROOT_PATH + 'ext/qml/plugins/testutil' }
|
20
|
+
it 'creates an object instance' do
|
21
|
+
loader.load
|
22
|
+
expect(loader.instance).to be_a QML::QtObjectBase
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with wrong file path' do
|
27
|
+
let(:path) { QML::ROOT_PATH + 'ext/qml/plugins/wrong' }
|
28
|
+
it 'fails with QML::PluginError' do
|
29
|
+
expect { loader.load }.to raise_error(QML::PluginError)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::QtObjectBase do
|
4
|
+
|
5
|
+
describe '#qml_eval' do
|
6
|
+
|
7
|
+
let(:component) do
|
8
|
+
QML::Component.new data: <<-EOS
|
9
|
+
import QtQuick 2.0
|
10
|
+
QtObject {
|
11
|
+
property string foo: 'foo'
|
12
|
+
property string bar: 'bar'
|
13
|
+
}
|
14
|
+
EOS
|
15
|
+
end
|
16
|
+
let(:object) { component.create }
|
17
|
+
let(:expression) { 'foo + bar' }
|
18
|
+
let(:result) { object.qml_eval(expression) }
|
19
|
+
|
20
|
+
it 'evaluates a JS expression in its QML scope' do
|
21
|
+
expect(result).to eq 'foobar'
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when expression is wrong' do
|
25
|
+
let(:expression) { 'hoge + piyo' }
|
26
|
+
it 'raises QML::QMLError' do
|
27
|
+
expect { result }.to raise_error(QML::QMLError)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when object does not belong to context' do
|
32
|
+
let(:object) { QML::Plugins.test_util.createTestObject }
|
33
|
+
it 'raises QML::QMLError' do
|
34
|
+
expect { result }.to raise_error(QML::QMLError)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'ownership' do
|
40
|
+
let(:ownership_test) { QML::Plugins.test_util.create_ownership_test }
|
41
|
+
|
42
|
+
context 'when it is returned from a method' do
|
43
|
+
it 'gets ownership of the object' do
|
44
|
+
checker = -> { QML::TestUtil::ObjectLifeChecker.new(ownership_test.create_object) }.call
|
45
|
+
QML.application.collect_garbage
|
46
|
+
expect(checker.alive?).to eq false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when it is obtained from a property' do
|
51
|
+
it 'does not get ownership of the object' do
|
52
|
+
checker = -> { QML::TestUtil::ObjectLifeChecker.new(ownership_test.property_object) }.call
|
53
|
+
QML.application.collect_garbage
|
54
|
+
expect(checker.alive?).to eq true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when it has a parent' do
|
59
|
+
it 'does not get ownership of the object' do
|
60
|
+
checker = -> { QML::TestUtil::ObjectLifeChecker.new(ownership_test.sub_object) }.call
|
61
|
+
QML.application.collect_garbage
|
62
|
+
expect(checker.alive?).to eq true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when it is created by component' do
|
67
|
+
let(:component) do
|
68
|
+
QML::Component.new data: <<-EOS
|
69
|
+
import QtQuick 2.0
|
70
|
+
Item {}
|
71
|
+
EOS
|
72
|
+
end
|
73
|
+
it 'gets ownership' do
|
74
|
+
checker = -> { QML::TestUtil::ObjectLifeChecker.new(component.create) }.call
|
75
|
+
QML.application.collect_garbage
|
76
|
+
expect(checker.alive?).to eq false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#managed?' do
|
81
|
+
[true, false].each do |cond|
|
82
|
+
context "when managed = #{cond}" do
|
83
|
+
it "returns #{cond}" do
|
84
|
+
obj = ownership_test.create_object
|
85
|
+
obj.managed = cond
|
86
|
+
expect(obj.managed?).to eq cond
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'on garbage collection' do
|
93
|
+
|
94
|
+
context 'when managed' do
|
95
|
+
it 'gets destroyed' do
|
96
|
+
checker = -> {
|
97
|
+
obj = ownership_test.create_object
|
98
|
+
obj.managed = true
|
99
|
+
QML::TestUtil::ObjectLifeChecker.new(obj)
|
100
|
+
}.call
|
101
|
+
QML.application.collect_garbage
|
102
|
+
expect(checker.alive?).to eq false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'when not managed' do
|
107
|
+
it 'does not get destroyed' do
|
108
|
+
checker = -> {
|
109
|
+
obj = ownership_test.create_object
|
110
|
+
obj.managed = false
|
111
|
+
QML::TestUtil::ObjectLifeChecker.new(obj)
|
112
|
+
}.call
|
113
|
+
QML.application.collect_garbage
|
114
|
+
expect(checker.alive?).to eq true
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,273 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::Reactive::Object do
|
4
|
+
|
5
|
+
class Button
|
6
|
+
include QML::Reactive::Object
|
7
|
+
signal :pressed, [:pos]
|
8
|
+
variadic_signal :message
|
9
|
+
property :name, 'button'
|
10
|
+
property :id, 0
|
11
|
+
property :name_double do
|
12
|
+
name + name
|
13
|
+
end
|
14
|
+
on :pressed do |pos|
|
15
|
+
self.name = pos
|
16
|
+
end
|
17
|
+
on_changed :id do
|
18
|
+
self.name = "ID: #{id}"
|
19
|
+
end
|
20
|
+
on_changed :id do
|
21
|
+
end
|
22
|
+
alias_property :title, :name
|
23
|
+
alias_signal :clicked, :pressed
|
24
|
+
end
|
25
|
+
|
26
|
+
class ToggleButton < Button
|
27
|
+
signal :pressed, [:x, :y]
|
28
|
+
signal :toggled, [:on]
|
29
|
+
property(:name) { 'toggle button' }
|
30
|
+
property(:info) { 'some info' }
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:button) { Button.new }
|
34
|
+
let(:toggle_button) { ToggleButton.new }
|
35
|
+
|
36
|
+
describe '.property' do
|
37
|
+
|
38
|
+
it 'defines getter' do
|
39
|
+
expect(button.name).to eq('button')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'defines setter' do
|
43
|
+
button.name = 'hoge'
|
44
|
+
expect(button.name).to eq('hoge')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'can set property binding' do
|
48
|
+
button.name = 'poyo'
|
49
|
+
expect(button.name_double).to eq 'poyopoyo'
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'defines notify signal' do
|
53
|
+
spy = QML::Reactive::SignalSpy.new(button.name_changed)
|
54
|
+
button.name = 'hoge'
|
55
|
+
expect(spy.args.last).to eq(['hoge'])
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'returns the name' do
|
59
|
+
result = nil
|
60
|
+
Class.new do
|
61
|
+
include QML::Reactive::Object
|
62
|
+
result = property :foo
|
63
|
+
end
|
64
|
+
expect(result).to eq :foo
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'in subclass' do
|
68
|
+
|
69
|
+
it 'defines property in subclass' do
|
70
|
+
expect(toggle_button.info).to eq('some info')
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'does not define property in superclass' do
|
74
|
+
expect(button.properties).not_to include(:info)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'overrides superclass property' do
|
78
|
+
expect(toggle_button.name).to eq('toggle button')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '.alias_property' do
|
84
|
+
it 'returns the name' do
|
85
|
+
result = nil
|
86
|
+
Class.new do
|
87
|
+
include QML::Reactive::Object
|
88
|
+
property :foo
|
89
|
+
result = alias_property :bar, :foo
|
90
|
+
end
|
91
|
+
expect(result).to eq :bar
|
92
|
+
end
|
93
|
+
it 'aliases a property' do
|
94
|
+
expect(button.property(:title)).to eq button.property(:name)
|
95
|
+
expect(button.signal(:title_changed)).to eq button.signal(:name_changed)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '.signal' do
|
100
|
+
|
101
|
+
it 'defines a signal' do
|
102
|
+
spy = button.pressed.spy
|
103
|
+
button.pressed.emit([10, 22])
|
104
|
+
expect(spy.args.last).to eq([[10, 22]])
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'returns the name' do
|
108
|
+
result = nil
|
109
|
+
Class.new do
|
110
|
+
include QML::Reactive::Object
|
111
|
+
result = signal :sig, []
|
112
|
+
end
|
113
|
+
expect(result).to eq(:sig)
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when the args parameter is not passed' do
|
117
|
+
it 'defines a variadic signal' do
|
118
|
+
spy = button.message.spy
|
119
|
+
button.message.emit(*%w{emitting some message})
|
120
|
+
expect(spy.args.last).to eq(%w{emitting some message})
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'in subclass' do
|
125
|
+
|
126
|
+
it 'defines signal in subclass' do
|
127
|
+
spy = toggle_button.toggled.spy
|
128
|
+
toggle_button.toggled.emit(true)
|
129
|
+
expect(spy.args.last).to eq([true])
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'does not define signal in superclass' do
|
133
|
+
expect(button.signals).not_to include(:toggled)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'overrides superclass signal' do
|
137
|
+
signal = toggle_button.pressed
|
138
|
+
expect(signal.arity).to eq(2)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'defines overridden signal in subclass' do
|
142
|
+
spy = toggle_button.pressed.spy
|
143
|
+
toggle_button.pressed.emit(10, 20)
|
144
|
+
expect(spy.args.last).to eq([10, 20])
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe '.alias_signal' do
|
150
|
+
|
151
|
+
it 'returns the name' do
|
152
|
+
result = nil
|
153
|
+
Class.new do
|
154
|
+
include QML::Reactive::Object
|
155
|
+
signal :foo, []
|
156
|
+
result = alias_signal :bar, :foo
|
157
|
+
end
|
158
|
+
expect(result).to eq :bar
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'aliases a signal' do
|
162
|
+
expect(button.clicked).to eq button.pressed
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe '.on' do
|
167
|
+
it 'adds signal handler' do
|
168
|
+
button.pressed.emit "pressed at top"
|
169
|
+
expect(button.name).to eq "pressed at top"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '.on_changed' do
|
174
|
+
it 'add property changed signal handler' do
|
175
|
+
button.id = 2
|
176
|
+
expect(button.name).to eq "ID: 2"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe '.instance_signals' do
|
181
|
+
context 'when include_super is false' do
|
182
|
+
it 'returns all signal definitions of the class' do
|
183
|
+
signals = ToggleButton.instance_signals(false)
|
184
|
+
expect(signals).to match_array %i{pressed toggled name_changed info_changed}
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'when include_super is not specified' do
|
189
|
+
it 'returns all signal definitions of the class and its superclasses' do
|
190
|
+
signals = ToggleButton.instance_signals
|
191
|
+
expect(signals).to match_array %i{pressed message toggled name_changed id_changed info_changed name_double_changed clicked title_changed}
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '.instance_properties' do
|
197
|
+
context 'when include_super is false' do
|
198
|
+
it 'returns all property definitions of the class' do
|
199
|
+
properties = ToggleButton.instance_properties(false)
|
200
|
+
expect(properties).to match_array %i{name info}
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'when include_super is not specified' do
|
205
|
+
it 'returns all property definitions of the class and its superclasses' do
|
206
|
+
properties = ToggleButton.instance_properties
|
207
|
+
expect(properties).to match_array %i{name id info name_double title}
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe '.instance_signal' do
|
213
|
+
it 'returns the UnboundSignal for name' do
|
214
|
+
s = ToggleButton.instance_signal(:pressed)
|
215
|
+
expect(s).to be_a QML::Reactive::UnboundSignal
|
216
|
+
expect(s.name).to eq :pressed
|
217
|
+
expect(s.arity).to eq 2
|
218
|
+
end
|
219
|
+
context 'when signal does not exist' do
|
220
|
+
it 'fails with NameError' do
|
221
|
+
expect { ToggleButton.instance_signal(:non_existent) }.to raise_error(NameError)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe '.instance_property' do
|
227
|
+
it 'returns the UnboundProperty for name' do
|
228
|
+
p = ToggleButton.instance_property(:name)
|
229
|
+
expect(p).to be_a QML::Reactive::UnboundProperty
|
230
|
+
expect(p.name).to eq :name
|
231
|
+
expect(p.initial_binding.call).to eq 'toggle button'
|
232
|
+
end
|
233
|
+
context 'when property does not exist' do
|
234
|
+
it 'fails with NameError' do
|
235
|
+
expect { ToggleButton.instance_property(:non_existent) }.to raise_error(NameError)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe '#signals' do
|
241
|
+
it 'returns signal names for object' do
|
242
|
+
expect(toggle_button.signals).to match_array %i{pressed message toggled id_changed name_changed info_changed name_double_changed clicked title_changed}
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe '#properties' do
|
247
|
+
it 'return property names for object' do
|
248
|
+
expect(toggle_button.properties).to match_array %i{name id info name_double title}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe '#signal' do
|
253
|
+
it 'returns Signal for name' do
|
254
|
+
expect(toggle_button.signal(:pressed)).to eq toggle_button.pressed
|
255
|
+
end
|
256
|
+
context 'when signal does not exist' do
|
257
|
+
it 'fails with NameError' do
|
258
|
+
expect { toggle_button.signal(:non_existent) }.to raise_error(NameError)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe '#property' do
|
264
|
+
it 'returns Property for name' do
|
265
|
+
expect(toggle_button.property(:name).value).to eq toggle_button.name
|
266
|
+
end
|
267
|
+
context 'when property does not exist' do
|
268
|
+
it 'fails with NameError' do
|
269
|
+
expect { toggle_button.property(:non_existent) }.to raise_error(NameError)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::Reactive::Property do
|
4
|
+
|
5
|
+
describe '#initialize' do
|
6
|
+
|
7
|
+
context 'when a value is given' do
|
8
|
+
it 'initializes with the value' do
|
9
|
+
p = QML::Reactive::Property.new(2)
|
10
|
+
expect(p.value).to eq(2)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when a block is given' do
|
15
|
+
it 'initializes with the property binding' do
|
16
|
+
p1 = QML::Reactive::Property.new(2)
|
17
|
+
p2 = QML::Reactive::Property.new { p1.value + 2 }
|
18
|
+
p1.value = 10
|
19
|
+
expect(p2.value).to eq(12)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'access to the value' do
|
25
|
+
describe '#value, #value=' do
|
26
|
+
it 'sets and gets the contained value' do
|
27
|
+
property = QML::Reactive::Property.new
|
28
|
+
property.value = '(´・_・`)'
|
29
|
+
expect(property.value).to eq('(´・_・`)')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'property binding' do
|
35
|
+
|
36
|
+
describe '#bind' do
|
37
|
+
|
38
|
+
it 'sets a property binding' do
|
39
|
+
p1 = QML::Reactive::Property.new 'foo'
|
40
|
+
p2 = QML::Reactive::Property.new 'bar'
|
41
|
+
p3 = QML::Reactive::Property.new
|
42
|
+
p4 = QML::Reactive::Property.new
|
43
|
+
p3.bind { p1.value + p2.value }
|
44
|
+
p4.bind { p3.value }
|
45
|
+
p1.value = 'hoge'
|
46
|
+
p2.value = 'piyo'
|
47
|
+
expect(p3.value).to eq('hogepiyo')
|
48
|
+
expect(p4.value).to eq('hogepiyo')
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when binding is recursive' do
|
52
|
+
it 'raises error' do
|
53
|
+
property = QML::Reactive::Property.new
|
54
|
+
expect{ property.bind { property.value } }.to raise_error(QML::Reactive::Error)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#changed' do
|
61
|
+
it 'returns a signal that is emitted when the value is changed' do
|
62
|
+
property = QML::Reactive::Property.new
|
63
|
+
changed_value = nil
|
64
|
+
property.changed.connect { |val| changed_value = val }
|
65
|
+
|
66
|
+
property.value = 'piyopiyo'
|
67
|
+
expect(changed_value).to eq('piyopiyo')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|