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,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::Application do
|
4
|
+
let(:application) { QML.application }
|
5
|
+
describe '.instance' do
|
6
|
+
it 'returns the QML::Application instance' do
|
7
|
+
expect(application).to be_a(QML::Application)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
describe '#engine' do
|
11
|
+
it 'returns the default engine of the application' do
|
12
|
+
expect(application.engine).to be_a(QML::Engine)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
describe '#context' do
|
16
|
+
it 'returns engine.context' do
|
17
|
+
expect(application.context).to be(application.engine.context)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
describe '#load_data' do
|
21
|
+
let(:data) do
|
22
|
+
<<-EOS
|
23
|
+
import QtQuick 2.0
|
24
|
+
QtObject {
|
25
|
+
property string name: 'foo'
|
26
|
+
}
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
it 'loads root object 1from data' do
|
30
|
+
application.load_data data
|
31
|
+
expect(application.root_component.data).to eq data
|
32
|
+
expect(application.root.name).to eq 'foo'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
describe '#load_path' do
|
36
|
+
let(:path) { QML::ROOT_PATH + 'spec/assets/testobj.qml' }
|
37
|
+
it 'loads root object from path' do
|
38
|
+
application.load_path path
|
39
|
+
expect(application.root_component.path).to eq path
|
40
|
+
expect(application.root.name).to eq 'foo'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::Component do
|
4
|
+
|
5
|
+
describe '#create' do
|
6
|
+
|
7
|
+
context 'with string' do
|
8
|
+
let(:data) do
|
9
|
+
<<-EOS
|
10
|
+
import QtQuick 2.0
|
11
|
+
QtObject {
|
12
|
+
property string name: 'foo'
|
13
|
+
}
|
14
|
+
EOS
|
15
|
+
end
|
16
|
+
let(:component) { QML::Component.new data: data }
|
17
|
+
|
18
|
+
it 'instantiates a object' do
|
19
|
+
expect(component.create.name).to eq 'foo'
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#data' do
|
23
|
+
it 'returns its data' do
|
24
|
+
expect(component.data).to eq data
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with file path' do
|
30
|
+
let(:path) { QML::ROOT_PATH + 'spec/assets/testobj.qml' }
|
31
|
+
let(:component) { QML::Component.new path: path }
|
32
|
+
|
33
|
+
it 'instantiates a object' do
|
34
|
+
expect(component.create.name).to eq 'foo'
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#path' do
|
38
|
+
it 'returns its path' do
|
39
|
+
expect(component.path).to eq path
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::Context do
|
4
|
+
|
5
|
+
let(:context) { QML::Context.new }
|
6
|
+
let(:component) do
|
7
|
+
QML::Component.new context: context, data: <<-EOS
|
8
|
+
import QtQuick 2.0
|
9
|
+
QtObject {
|
10
|
+
}
|
11
|
+
EOS
|
12
|
+
end
|
13
|
+
let(:object) { component.create }
|
14
|
+
|
15
|
+
describe '#[]=' do
|
16
|
+
it 'makes a value available to QML context' do
|
17
|
+
context[:foo] = 'foo'
|
18
|
+
expect(object.qml_eval('foo')).to eq 'foo'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'takes ownership of Qt object' do
|
22
|
+
life_checker = lambda do
|
23
|
+
obj = QML::Plugins.test_util.create_test_object
|
24
|
+
context[:obj] = obj
|
25
|
+
QML::TestUtil::ObjectLifeChecker.new(obj)
|
26
|
+
end.call
|
27
|
+
|
28
|
+
QML.application.collect_garbage
|
29
|
+
expect(life_checker.alive?).to eq true
|
30
|
+
|
31
|
+
context[:obj] = nil
|
32
|
+
QML.application.collect_garbage
|
33
|
+
expect(life_checker.alive?).to eq false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#[]' do
|
38
|
+
it 'returns the value previously set by []=' do
|
39
|
+
context[:foo] = 'foo'
|
40
|
+
expect(context[:foo]).to eq 'foo'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
def convert(value)
|
4
|
+
QML::TestUtil.echo_conversion(value)
|
5
|
+
end
|
6
|
+
|
7
|
+
describe 'Conversion between C++ and Ruby' do
|
8
|
+
|
9
|
+
class Foo
|
10
|
+
include QML::Access
|
11
|
+
end
|
12
|
+
|
13
|
+
samples = {
|
14
|
+
'Integer' => 1234,
|
15
|
+
'true' => true,
|
16
|
+
'false' => false,
|
17
|
+
'nil' => nil,
|
18
|
+
'Float' => 3.1416,
|
19
|
+
'String' => 'hoge',
|
20
|
+
'non-ascii String' => 'ほげ',
|
21
|
+
'Array' => [1, "foobar", true],
|
22
|
+
'Hash' => {'one' => 1, 'two' => 2, '三' => 3},
|
23
|
+
'Date' => Date.today,
|
24
|
+
'Access derived' => Foo.new,
|
25
|
+
'QML Point' => QML::Geometry::Point.new(1,2),
|
26
|
+
'QML Size' => QML::Geometry::Size.new(1,2),
|
27
|
+
'QML Rectangle' => QML::Geometry::Rectangle.new(1,2,3,4)
|
28
|
+
}
|
29
|
+
|
30
|
+
samples.each do |k, v|
|
31
|
+
it "can convert #{k}" do
|
32
|
+
actual = convert(v)
|
33
|
+
expect(actual).to eq v
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'can convert Symbol as String' do
|
38
|
+
expected = :hogehoge
|
39
|
+
actual = convert(expected)
|
40
|
+
expect(actual).to eq expected.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
[4/24.to_r, 8/24.to_r].each do |offset|
|
44
|
+
it "can convert DateTime with offset #{offset}" do
|
45
|
+
time = DateTime.now.new_offset(offset)
|
46
|
+
result = convert(time)
|
47
|
+
# QDateTime has msec precision
|
48
|
+
expect((result.to_time.to_r * 1000).to_i).to eq (time.to_time.to_r * 1000).to_i
|
49
|
+
expect(result.offset).to eq(time.offset)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'can convert meta object' do
|
54
|
+
metaobj = QML::MetaObject.new
|
55
|
+
actual = convert(metaobj)
|
56
|
+
expect(actual).to eq metaobj
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::Data::ArrayModel do
|
4
|
+
|
5
|
+
class NoColumnArrayModel < QML::Data::ArrayModel
|
6
|
+
end
|
7
|
+
|
8
|
+
class TestArrayModel < QML::Data::ArrayModel
|
9
|
+
column :title, :number
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:context) { QML::Context.new }
|
13
|
+
|
14
|
+
let(:component) do
|
15
|
+
QML::Component.new context: context, data: <<-EOS
|
16
|
+
import QtQuick 2.0
|
17
|
+
ListView {
|
18
|
+
model: arrayModel
|
19
|
+
delegate: Item {
|
20
|
+
property var itemTitle: title
|
21
|
+
property var itemNumber: number
|
22
|
+
}
|
23
|
+
}
|
24
|
+
EOS
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:list_view) { component.create }
|
28
|
+
|
29
|
+
let(:original_array) do
|
30
|
+
[
|
31
|
+
{title: 'hoge', number: 12},
|
32
|
+
{title: 'piyo', number: 34},
|
33
|
+
{title: 'fuga', number: 1234}
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:additional_array) do
|
38
|
+
[
|
39
|
+
{title: 'foo', number: 56},
|
40
|
+
{title: 'bar', number: 78}
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:expected_array) { original_array.dup }
|
45
|
+
|
46
|
+
let(:model) do
|
47
|
+
TestArrayModel.new.tap do |model|
|
48
|
+
model.push *original_array
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
before do
|
53
|
+
context[:arrayModel] = model
|
54
|
+
end
|
55
|
+
|
56
|
+
shared_examples 'model content' do |text|
|
57
|
+
it text do
|
58
|
+
expect(model.to_a).to eq(expected_array)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
shared_examples 'ListView' do
|
63
|
+
it 'updates QML ListView correctly' do
|
64
|
+
count = list_view.count
|
65
|
+
expect(count).to eq expected_array.size
|
66
|
+
list_view.count.times do |i|
|
67
|
+
list_view.current_index = i
|
68
|
+
current = list_view.current_item
|
69
|
+
expect(current.item_title).to eq(expected_array[i][:title])
|
70
|
+
expect(current.item_number).to eq(expected_array[i][:number])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#initialize' do
|
76
|
+
context 'when columns are not specified' do
|
77
|
+
it 'fails' do
|
78
|
+
expect { NoColumnArrayModel.new }.to raise_error(QML::Data::Error)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#each' do
|
84
|
+
context 'with no block' do
|
85
|
+
it 'returns an Enumerator' do
|
86
|
+
expect(model.each).to be_a Enumerator
|
87
|
+
expect(model.each.to_a).to eq expected_array
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'with block' do
|
92
|
+
it 'iterates each item' do
|
93
|
+
items = []
|
94
|
+
model.each do |item|
|
95
|
+
items << item
|
96
|
+
end
|
97
|
+
expect(items).to eq expected_array
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#to_a' do
|
103
|
+
it 'returns the array the elements are stored in' do
|
104
|
+
expect(model.to_a).to eq expected_array
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#count' do
|
109
|
+
it 'returns the number of items' do
|
110
|
+
expect(model.count).to eq expected_array.size
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#[]' do
|
115
|
+
it 'returns the item for given index' do
|
116
|
+
expect(model[1]).to eq(expected_array[1])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#[]=' do
|
121
|
+
|
122
|
+
it 'returns the assigned item' do
|
123
|
+
item = additional_array[0]
|
124
|
+
expect(model[2] = item).to eq item
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'after called' do
|
128
|
+
before do
|
129
|
+
model[2] = additional_array[0]
|
130
|
+
expected_array[2] = additional_array[0]
|
131
|
+
end
|
132
|
+
include_examples 'model content', 'sets the element to given index'
|
133
|
+
include_examples 'ListView'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '#insert' do
|
138
|
+
|
139
|
+
it 'returns self' do
|
140
|
+
expect(model.insert(1, *additional_array)).to eq model
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'after called' do
|
144
|
+
before do
|
145
|
+
model.insert(1, *additional_array)
|
146
|
+
expected_array.insert(1, *additional_array)
|
147
|
+
end
|
148
|
+
include_examples 'model content', 'inserts item'
|
149
|
+
include_examples 'ListView'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#delete_at' do
|
154
|
+
|
155
|
+
context 'with no number' do
|
156
|
+
it 'deletes 1 item and returns it' do
|
157
|
+
expect(model.delete_at(1)).to eq original_array[1]
|
158
|
+
end
|
159
|
+
context 'after called' do
|
160
|
+
before do
|
161
|
+
model.delete_at(1)
|
162
|
+
expected_array.delete_at(1)
|
163
|
+
end
|
164
|
+
include_examples 'model content', 'deletes item'
|
165
|
+
include_examples 'ListView'
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'with number' do
|
170
|
+
it 'deletes multiple items and returns them as an array' do
|
171
|
+
expect(model.delete_at(1, 2)).to eq original_array[1..2]
|
172
|
+
end
|
173
|
+
context 'after called' do
|
174
|
+
before do
|
175
|
+
model.delete_at(1, 2)
|
176
|
+
2.times { expected_array.delete_at(1) }
|
177
|
+
end
|
178
|
+
include_examples 'model content', 'deletes items'
|
179
|
+
include_examples 'ListView'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe '#unshift' do
|
185
|
+
it 'prepends items' do
|
186
|
+
expect(model.unshift(*additional_array).to_a).to eq expected_array.unshift(*additional_array)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe '#shift' do
|
191
|
+
it 'removes first items and returns them' do
|
192
|
+
expect(model.shift(2)).to eq expected_array[0..1]
|
193
|
+
expect(model.to_a).to eq expected_array.tap { |a| a.shift(2) }
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe '#push' do
|
198
|
+
it 'appends items' do
|
199
|
+
expect(model.push(*additional_array).to_a).to eq expected_array.push(*additional_array)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe '#pop' do
|
204
|
+
it 'removes last items and returns them' do
|
205
|
+
expect(model.pop(2)).to eq expected_array[-2..-1]
|
206
|
+
expect(model.to_a).to eq expected_array.tap { |a| a.pop(2) }
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe '<<' do
|
211
|
+
it 'is an alias of #push' do
|
212
|
+
expect((model << additional_array[0]).to_a).to eq(expected_array << additional_array[0])
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::Dispatchable do
|
4
|
+
class DispatchableFoo
|
5
|
+
include QML::Dispatchable
|
6
|
+
attr_accessor :value
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#later' do
|
10
|
+
it 'queues a method call as a task to the dispatcher' do
|
11
|
+
foo = DispatchableFoo.new
|
12
|
+
foo.later.value = 'hoge'
|
13
|
+
expect(foo.value).to be_nil
|
14
|
+
QML.application.process_events
|
15
|
+
expect(foo.value).to eq 'hoge'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
[QML::Access, QML::QtObjectBase, QML::Data::ListModel].each do |mod|
|
21
|
+
describe mod do
|
22
|
+
it 'includes Dispatchable' do
|
23
|
+
expect(mod.include?(QML::Dispatchable)).to eq true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QML::Dispatcher do
|
4
|
+
|
5
|
+
let(:dispatcher) { QML::Dispatcher.instance }
|
6
|
+
|
7
|
+
describe '#empty?' do
|
8
|
+
context 'when it has no task' do
|
9
|
+
it 'returns true' do
|
10
|
+
dispatcher.run_tasks until dispatcher.empty?
|
11
|
+
expect(dispatcher.empty?).to eq true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context 'when it has tasks' do
|
15
|
+
it 'returns false' do
|
16
|
+
dispatcher.add_task {}
|
17
|
+
expect(dispatcher.empty?).to eq false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#run_tasks' do
|
23
|
+
it 'runs queued tasks' do
|
24
|
+
finished = []
|
25
|
+
2.times.each do |i|
|
26
|
+
dispatcher.add_task do
|
27
|
+
finished[i] = true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
dispatcher.run_tasks until dispatcher.empty?
|
31
|
+
expect(finished).to eq [true, true]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe QML do
|
37
|
+
describe '.later' do
|
38
|
+
it 'adds a task to the dispatcher and do it later in event loop' do
|
39
|
+
finished = false
|
40
|
+
QML.later do
|
41
|
+
finished = true
|
42
|
+
end
|
43
|
+
expect(finished).to eq false
|
44
|
+
QML.application.process_events
|
45
|
+
expect(finished).to eq true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|