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.
- 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
|