reflexion 0.5.2 → 0.6.0
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 +4 -4
- data/.doc/ext/reflex/application.cpp +19 -1
- data/.doc/ext/reflex/chase_constraint.cpp +84 -0
- data/.doc/ext/reflex/clipboard.cpp +65 -0
- data/.doc/ext/reflex/constraint.cpp +135 -0
- data/.doc/ext/reflex/key_event.cpp +6 -6
- data/.doc/ext/reflex/link_constraint.cpp +178 -0
- data/.doc/ext/reflex/menu.cpp +302 -0
- data/.doc/ext/reflex/native.cpp +22 -4
- data/.doc/ext/reflex/pin.cpp +156 -0
- data/.doc/ext/reflex/pointer.cpp +2 -0
- data/.doc/ext/reflex/pointer_event.cpp +1 -1
- data/.doc/ext/reflex/reflex.cpp +42 -7
- data/.doc/ext/reflex/selector.cpp +4 -4
- data/.doc/ext/reflex/snap_constraint.cpp +125 -0
- data/.doc/ext/reflex/style_length.cpp +3 -2
- data/.doc/ext/reflex/view.cpp +96 -23
- data/.doc/ext/reflex/wheel_constraint.cpp +142 -0
- data/.doc/ext/reflex/window.cpp +59 -17
- data/.github/workflows/release-gem.yml +10 -1
- data/.github/workflows/test.yml +9 -0
- data/ChangeLog.md +30 -0
- data/README.md +1 -0
- data/VERSION +1 -1
- data/ext/reflex/application.cpp +21 -1
- data/ext/reflex/chase_constraint.cpp +89 -0
- data/ext/reflex/clipboard.cpp +69 -0
- data/ext/reflex/constraint.cpp +146 -0
- data/ext/reflex/key_event.cpp +6 -6
- data/ext/reflex/link_constraint.cpp +194 -0
- data/ext/reflex/menu.cpp +330 -0
- data/ext/reflex/native.cpp +22 -4
- data/ext/reflex/pin.cpp +165 -0
- data/ext/reflex/pointer.cpp +2 -0
- data/ext/reflex/pointer_event.cpp +1 -1
- data/ext/reflex/reflex.cpp +42 -7
- data/ext/reflex/selector.cpp +4 -4
- data/ext/reflex/selector.h +1 -1
- data/ext/reflex/snap_constraint.cpp +135 -0
- data/ext/reflex/style_length.cpp +3 -2
- data/ext/reflex/view.cpp +117 -37
- data/ext/reflex/wheel_constraint.cpp +154 -0
- data/ext/reflex/window.cpp +65 -18
- data/include/reflex/application.h +9 -0
- data/include/reflex/clipboard.h +53 -0
- data/include/reflex/constraint.h +275 -0
- data/include/reflex/defs.h +204 -195
- data/include/reflex/event.h +2 -0
- data/include/reflex/menu.h +120 -0
- data/include/reflex/pin.h +68 -0
- data/include/reflex/pointer.h +4 -0
- data/include/reflex/ruby/clipboard.h +23 -0
- data/include/reflex/ruby/constraint.h +94 -0
- data/include/reflex/ruby/menu.h +103 -0
- data/include/reflex/ruby/pin.h +40 -0
- data/include/reflex/ruby/view.h +36 -0
- data/include/reflex/ruby/window.h +36 -18
- data/include/reflex/view.h +39 -12
- data/include/reflex/window.h +17 -4
- data/include/reflex.h +5 -0
- data/lib/reflex/chase_constraint.rb +15 -0
- data/lib/reflex/clipboard.rb +19 -0
- data/lib/reflex/constraint.rb +29 -0
- data/lib/reflex/extension.rb +1 -1
- data/lib/reflex/helper.rb +28 -0
- data/lib/reflex/key_event.rb +7 -12
- data/lib/reflex/link_constraint.rb +31 -0
- data/lib/reflex/menu.rb +76 -0
- data/lib/reflex/pin.rb +39 -0
- data/lib/reflex/pointer.rb +18 -0
- data/lib/reflex/pointer_event.rb +1 -1
- data/lib/reflex/snap_constraint.rb +28 -0
- data/lib/reflex/view.rb +56 -4
- data/lib/reflex/wheel_constraint.rb +28 -0
- data/lib/reflex/wheel_event.rb +9 -0
- data/lib/reflex.rb +15 -6
- data/pod.rake +4 -2
- data/reflex.gemspec +3 -3
- data/samples/constraint.rb +152 -0
- data/samples/menu.rb +29 -0
- data/src/application.cpp +21 -2
- data/src/application.h +5 -0
- data/src/clipboard.cpp +81 -0
- data/src/constraint.cpp +1662 -0
- data/src/constraint.h +64 -0
- data/src/event.cpp +7 -1
- data/src/event.h +1 -2
- data/src/ios/application.mm +5 -0
- data/src/ios/clipboard.mm +44 -0
- data/src/ios/event.h +6 -2
- data/src/ios/event.mm +31 -12
- data/src/ios/menu.mm +36 -0
- data/src/ios/view_controller.mm +45 -12
- data/src/ios/window.mm +6 -0
- data/src/menu.cpp +325 -0
- data/src/menu.h +65 -0
- data/src/osx/app_delegate.mm +74 -125
- data/src/osx/application.mm +16 -0
- data/src/osx/clipboard.mm +45 -0
- data/src/osx/event.mm +40 -10
- data/src/osx/menu.h +25 -0
- data/src/osx/menu.mm +372 -0
- data/src/osx/native_window.mm +27 -0
- data/src/osx/opengl_view.mm +51 -0
- data/src/osx/window.mm +11 -0
- data/src/pin.cpp +137 -0
- data/src/pointer.cpp +27 -16
- data/src/pointer.h +6 -0
- data/src/sdl/application.cpp +5 -0
- data/src/sdl/clipboard.cpp +39 -0
- data/src/sdl/event.cpp +20 -3
- data/src/sdl/event.h +6 -3
- data/src/sdl/menu.cpp +35 -0
- data/src/sdl/window.cpp +26 -8
- data/src/view.cpp +313 -52
- data/src/view.h +18 -2
- data/src/win32/application.cpp +5 -0
- data/src/win32/clipboard.cpp +210 -0
- data/src/win32/event.cpp +11 -1
- data/src/win32/event.h +2 -0
- data/src/win32/menu.cpp +352 -0
- data/src/win32/menu.h +27 -0
- data/src/win32/window.cpp +62 -0
- data/src/win32/window.h +3 -0
- data/src/window.cpp +235 -22
- data/src/window.h +13 -2
- data/src/world.cpp +77 -14
- data/src/world.h +9 -2
- data/test/helper.rb +7 -0
- data/test/test_application.rb +11 -0
- data/test/test_chase_constraint.rb +124 -0
- data/test/test_clipboard.rb +54 -0
- data/test/test_constraint.rb +186 -0
- data/test/test_key_event.rb +6 -0
- data/test/test_link_constraint.rb +239 -0
- data/test/test_menu.rb +207 -0
- data/test/test_pin.rb +65 -0
- data/test/test_pointer.rb +23 -9
- data/test/test_pointer_event.rb +1 -1
- data/test/test_snap_constraint.rb +142 -0
- data/test/test_view.rb +113 -23
- data/test/test_wheel_constraint.rb +127 -0
- data/test/test_wheel_event.rb +15 -9
- data/test/test_window.rb +10 -0
- metadata +82 -8
data/test/test_application.rb
CHANGED
|
@@ -11,6 +11,17 @@ class TestApplication < Test::Unit::TestCase
|
|
|
11
11
|
assert_equal 'AppName', @@app.name
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
def test_menu()
|
|
15
|
+
m = Reflex::Menu.new
|
|
16
|
+
assert_nil @@app.menu
|
|
17
|
+
@@app.menu = m
|
|
18
|
+
assert_equal m, @@app.menu
|
|
19
|
+
@@app.menu = nil
|
|
20
|
+
assert_nil @@app.menu
|
|
21
|
+
|
|
22
|
+
assert_raise(TypeError) {@@app.menu = 1}
|
|
23
|
+
end
|
|
24
|
+
|
|
14
25
|
def test_inspect()
|
|
15
26
|
assert_match %r|#<Reflex::Application:0x\w{16}>|, @@app.inspect
|
|
16
27
|
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestChaseConstraint < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def window()
|
|
7
|
+
Reflex::Window.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def view(x = 0, y = 0, w = 50, h = 50, **options, &block)
|
|
11
|
+
Reflex::View.new(
|
|
12
|
+
frame: [x, y, w, h],
|
|
13
|
+
shape: Reflex::RectShape.new(density: 1),
|
|
14
|
+
**options, &block)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def point(...)
|
|
18
|
+
Reflex::Point.new(...)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def setup_views(win = window)
|
|
22
|
+
v1 = view 100, 100, dynamic: true
|
|
23
|
+
v2 = view 200, 100, static: true
|
|
24
|
+
win&.add v1
|
|
25
|
+
win&.add v2
|
|
26
|
+
[v1, v2, win, win&.root]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_initial_state()
|
|
30
|
+
v1, v2, = setup_views
|
|
31
|
+
|
|
32
|
+
assert_equal v1, v1.chase(v2) .pins[0].view
|
|
33
|
+
assert_nil v1.chase(v2) .pins[1].view
|
|
34
|
+
assert_equal v2, v1.chase(v2) .target.view
|
|
35
|
+
assert_nil v1.chase(v2) .force
|
|
36
|
+
assert_equal 1, v1.chase(v2, force: 1) .force
|
|
37
|
+
assert_equal 5, v1.chase(v2) .spring
|
|
38
|
+
assert_equal 2, v1.chase(v2, spring: 2) .spring
|
|
39
|
+
assert_in_delta 0.7, v1.chase(v2) .damping
|
|
40
|
+
assert_in_delta 0.1, v1.chase(v2, damping: 0.1).damping
|
|
41
|
+
assert_false v1.chase(v2) .collide?
|
|
42
|
+
assert_true v1.chase(v2) .active?
|
|
43
|
+
assert_false v1.chase(v2) .removed?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_chase_view()
|
|
47
|
+
v1, v2, _, root = setup_views
|
|
48
|
+
|
|
49
|
+
c = v1.chase v2
|
|
50
|
+
assert_equal v2, c.target.view
|
|
51
|
+
|
|
52
|
+
root.update_world
|
|
53
|
+
assert_operator v1.linear_velocity.x, :>, 0
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_chase_world_point()
|
|
57
|
+
v1, _, _, root = setup_views
|
|
58
|
+
|
|
59
|
+
c = v1.chase [300, 300]
|
|
60
|
+
assert_nil c.target.view
|
|
61
|
+
assert_equal_point point(300, 300), c.target.pos
|
|
62
|
+
|
|
63
|
+
root.update_world
|
|
64
|
+
assert_operator v1.linear_velocity.x, :>, 0
|
|
65
|
+
assert_operator v1.linear_velocity.y, :>, 0
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_grabbing_corner_creates_torque()
|
|
69
|
+
v1, _, _, root = setup_views
|
|
70
|
+
|
|
71
|
+
c = v1.pin(0, 0).chase [300, 100], spring: 8
|
|
72
|
+
assert_equal_point point(0, 0), c.pins[0].pos
|
|
73
|
+
|
|
74
|
+
3.times {root.update_world}
|
|
75
|
+
assert_operator v1.angular_velocity.abs, :>, 1
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_chase_to_itself_error()
|
|
79
|
+
v1, v2, = setup_views
|
|
80
|
+
|
|
81
|
+
assert_raise(ArgumentError) {v1.chase v1}
|
|
82
|
+
assert_raise(ArgumentError) {v1.chase(v2).target = v1}
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_target()
|
|
86
|
+
v1, v2, = setup_views
|
|
87
|
+
|
|
88
|
+
c = v1.chase [300, 300]
|
|
89
|
+
assert_nil c.target.view
|
|
90
|
+
assert_equal_point point(300, 300), c.target.pos
|
|
91
|
+
|
|
92
|
+
c.target = v2
|
|
93
|
+
assert_equal v2, c.target.view
|
|
94
|
+
assert_nil c.target.pos
|
|
95
|
+
|
|
96
|
+
c.target = v2.pin(0, 0)
|
|
97
|
+
assert_equal v2, c.target.view
|
|
98
|
+
assert_equal_point point(0, 0), c.target.pos
|
|
99
|
+
|
|
100
|
+
c.target = [v2, 5, 5]
|
|
101
|
+
assert_equal v2, c.target.view
|
|
102
|
+
assert_equal_point point(5, 5), c.target.pos
|
|
103
|
+
|
|
104
|
+
c.target = nil
|
|
105
|
+
assert_nil c.target.view
|
|
106
|
+
assert_nil c.target.pos
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_force()
|
|
110
|
+
v1, = setup_views
|
|
111
|
+
|
|
112
|
+
c = v1.chase [300, 100], force: 500
|
|
113
|
+
assert_equal 500, c.force
|
|
114
|
+
|
|
115
|
+
c.force = nil
|
|
116
|
+
assert_nil c.force
|
|
117
|
+
|
|
118
|
+
c.force = 100
|
|
119
|
+
assert_equal 100, c.force
|
|
120
|
+
|
|
121
|
+
assert_raise(ArgumentError) {c.force = -1}
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end# TestChaseConstraint
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestClipboard < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def setup()
|
|
7
|
+
@saved_text = Reflex::Clipboard.text
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def teardown()
|
|
11
|
+
if @saved_text
|
|
12
|
+
Reflex::Clipboard.text = @saved_text
|
|
13
|
+
else
|
|
14
|
+
Reflex::Clipboard.clear
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_initialize()
|
|
19
|
+
assert_raise(Reflex::ReflexError) {Reflex::Clipboard.new}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_text()
|
|
23
|
+
Reflex::Clipboard.text = 'ABC'
|
|
24
|
+
assert_equal 'ABC', Reflex::Clipboard.text
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_text_utf8()
|
|
28
|
+
Reflex::Clipboard.text = 'あいう'
|
|
29
|
+
assert_equal 'あいう', Reflex::Clipboard.text
|
|
30
|
+
assert_equal Encoding::UTF_8, Reflex::Clipboard.text.encoding
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_text_multiline()
|
|
34
|
+
Reflex::Clipboard.text = "A\nB\nC"
|
|
35
|
+
assert_equal "A\nB\nC", Reflex::Clipboard.text
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_universal_accessor()
|
|
39
|
+
Reflex::Clipboard.text 'ABC'
|
|
40
|
+
assert_equal 'ABC', Reflex::Clipboard.text
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def test_clear()
|
|
44
|
+
Reflex::Clipboard.text = 'ABC'
|
|
45
|
+
Reflex::Clipboard.clear
|
|
46
|
+
assert_nil Reflex::Clipboard.text
|
|
47
|
+
end unless linux?
|
|
48
|
+
|
|
49
|
+
def test_empty_text()
|
|
50
|
+
Reflex::Clipboard.text = ''
|
|
51
|
+
assert_equal '', Reflex::Clipboard.text
|
|
52
|
+
end unless linux?
|
|
53
|
+
|
|
54
|
+
end# TestClipboard
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestConstraint < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
R = Reflex
|
|
7
|
+
|
|
8
|
+
def window()
|
|
9
|
+
R::Window.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def view(x = 0, y = 0, w = 50, h = 50, **options, &block)
|
|
13
|
+
R::View.new(
|
|
14
|
+
frame: [x, y, w, h],
|
|
15
|
+
shape: R::RectShape.new(density: 1),
|
|
16
|
+
**options, &block)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def point(...)
|
|
20
|
+
R::Point.new(...)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def setup_views(win = window)
|
|
24
|
+
v1 = view 100, 100, dynamic: true
|
|
25
|
+
v2 = view 200, 100, static: true
|
|
26
|
+
win&.add v1
|
|
27
|
+
win&.add v2
|
|
28
|
+
[v1, v2, win, win&.root]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_activation()
|
|
32
|
+
v1, v2, = setup_views nil
|
|
33
|
+
w = window
|
|
34
|
+
|
|
35
|
+
c = v1.link v2; assert_false c.active?
|
|
36
|
+
w.add v1; assert_false c.active?
|
|
37
|
+
w.add v2; assert_true c.active?
|
|
38
|
+
w.remove v1; assert_false c.active?
|
|
39
|
+
w.add v1; assert_true c.active?
|
|
40
|
+
c = v1.link v2; assert_true c.active?
|
|
41
|
+
|
|
42
|
+
assert_in_delta 100, c.current_distance
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_pins()
|
|
46
|
+
v1, v2, = setup_views
|
|
47
|
+
|
|
48
|
+
c = v1.pin(10, 20).snap v2.pin(30, 40)
|
|
49
|
+
assert_equal v1, c.pins[0].view
|
|
50
|
+
assert_equal_point point(10, 20), c.pins[0].pos
|
|
51
|
+
assert_equal v2, c.pins[1].view
|
|
52
|
+
assert_equal_point point(30, 40), c.pins[1].pos
|
|
53
|
+
assert_equal [v1, v2], c.views
|
|
54
|
+
assert_equal [v1, v2], c.pins.map(&:view)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_resolved_positions()
|
|
58
|
+
v1, v2, = setup_views
|
|
59
|
+
|
|
60
|
+
assert_equal_point point( 25, 25), v1.pin .snap(v2) .pins[0].pos
|
|
61
|
+
assert_equal_point point(-75, 25), v1.pin .snap(v2) .pins[1].pos
|
|
62
|
+
assert_equal_point point( 10, 20), v1.pin(10, 20).snap(v2) .pins[0].pos
|
|
63
|
+
assert_equal_point point(-90, 20), v1.pin(10, 20).snap(v2) .pins[1].pos
|
|
64
|
+
assert_equal_point point( 130, 40), v1.pin .snap(v2, 30, 40).pins[0].pos
|
|
65
|
+
assert_equal_point point( 30, 40), v1.pin .snap(v2, 30, 40).pins[1].pos
|
|
66
|
+
assert_equal_point point( 50, 60), v1.pin(50, 60).snap(v2, 70, 80).pins[0].pos
|
|
67
|
+
assert_equal_point point( 70, 80), v1.pin(50, 60).snap(v2, 70, 80).pins[1].pos
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_spring()
|
|
71
|
+
v1, v2, = setup_views
|
|
72
|
+
|
|
73
|
+
c = v1.link v2, spring: 4, damping: 0.5
|
|
74
|
+
assert_in_delta 4, c.spring
|
|
75
|
+
assert_in_delta 0.5, c.damping
|
|
76
|
+
|
|
77
|
+
c.spring = nil; assert_nil c.spring
|
|
78
|
+
c.spring = 8; assert_in_delta 8, c.spring
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_collide()
|
|
82
|
+
v1, v2, = setup_views
|
|
83
|
+
|
|
84
|
+
assert_false v1.snap(v2) .collide?
|
|
85
|
+
assert_false v1.snap(v2, collide: false).collide?
|
|
86
|
+
assert_true v1.snap(v2, collide: true) .collide?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_selector()
|
|
90
|
+
v1, v2, = setup_views
|
|
91
|
+
|
|
92
|
+
c = v1.link v2, name: :name1, tag: [:tag1, :tag2]
|
|
93
|
+
assert_equal 'name1', c.name
|
|
94
|
+
assert_equal ['tag1', 'tag2'], c.tags.to_a
|
|
95
|
+
assert_true c.tag?(:tag1)
|
|
96
|
+
assert_true c.tag?('tag1')
|
|
97
|
+
assert_true c.tag?(:tag2)
|
|
98
|
+
assert_false c.tag?(:tag3)
|
|
99
|
+
|
|
100
|
+
c.name = :name2
|
|
101
|
+
assert_equal 'name2', c.name
|
|
102
|
+
|
|
103
|
+
assert_false c.tag?(:tag9)
|
|
104
|
+
c.add_tag :tag9
|
|
105
|
+
assert_true c.tag?(:tag9)
|
|
106
|
+
assert_equal ['tag1', 'tag2', 'tag9'], c.tags.to_a
|
|
107
|
+
c.remove_tag :tag9
|
|
108
|
+
assert_false c.tag?(:tag9)
|
|
109
|
+
assert_equal ['tag1', 'tag2'], c.tags.to_a
|
|
110
|
+
|
|
111
|
+
c.clear_tags
|
|
112
|
+
assert_equal [], c.tags.to_a
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_block()
|
|
116
|
+
v1, v2, = setup_views
|
|
117
|
+
|
|
118
|
+
c = v1.link v2 do
|
|
119
|
+
distance 80
|
|
120
|
+
spring 4
|
|
121
|
+
end
|
|
122
|
+
assert_equal 80, c.distance
|
|
123
|
+
assert_in_delta 4, c.spring
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def test_constraints()
|
|
127
|
+
v1, v2, = setup_views
|
|
128
|
+
|
|
129
|
+
c1 = v1.link v2
|
|
130
|
+
c2 = v1.snap v2
|
|
131
|
+
assert_equal [c1, c2], v1.constraints.to_a
|
|
132
|
+
assert_equal [c1, c2], v2.constraints.to_a
|
|
133
|
+
assert_equal [R::LinkConstraint, R::SnapConstraint], v1.constraints.map(&:class)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def test_remove()
|
|
137
|
+
v1, v2, _, parent = setup_views
|
|
138
|
+
|
|
139
|
+
c = v1.link v2
|
|
140
|
+
c.remove
|
|
141
|
+
assert_false c.active?
|
|
142
|
+
assert_true c.removed?
|
|
143
|
+
assert_equal [], v1.constraints.to_a
|
|
144
|
+
assert_equal [], v2.constraints.to_a
|
|
145
|
+
|
|
146
|
+
c.remove # idempotent
|
|
147
|
+
|
|
148
|
+
parent.remove v1
|
|
149
|
+
parent.add v1
|
|
150
|
+
assert_false c.active? # never comes back
|
|
151
|
+
|
|
152
|
+
assert_nothing_raised do
|
|
153
|
+
c.spring = 4
|
|
154
|
+
c.damping = 0.5
|
|
155
|
+
c.distance = 50
|
|
156
|
+
end
|
|
157
|
+
assert_false c.active? # removed constraint is inert
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def test_constrain_to_itself_error()
|
|
161
|
+
setup_views.tap do |v,|
|
|
162
|
+
assert_raise(ArgumentError) {v.snap v}
|
|
163
|
+
end
|
|
164
|
+
setup_views.tap do |v,|
|
|
165
|
+
assert_raise(ArgumentError) {v.chase v}
|
|
166
|
+
assert_equal [], v.constraints.to_a # rejected self-constraint leaves no orphan
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def test_world_mismatch_error()
|
|
171
|
+
win = window
|
|
172
|
+
parent1, child1 = view(0, 0, 500, 500), view(100, 100, dynamic: true)
|
|
173
|
+
parent2, child2 = view(0, 0, 500, 500), view(100, 100, dynamic: true)
|
|
174
|
+
parent1.add child1
|
|
175
|
+
parent2.add child2
|
|
176
|
+
win.add parent1
|
|
177
|
+
win.add parent2
|
|
178
|
+
child1.meter2pixel # create parent1 world
|
|
179
|
+
child2.meter2pixel # create parent2 world
|
|
180
|
+
|
|
181
|
+
assert_raise(R::PhysicsError) {child1.snap child2}
|
|
182
|
+
assert_equal [], child1.constraints.to_a # rejected pins leave no trace
|
|
183
|
+
assert_equal [], child2.constraints.to_a
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
end# TestConstraint
|
data/test/test_key_event.rb
CHANGED
|
@@ -43,4 +43,10 @@ class TestKeyEvent < Test::Unit::TestCase
|
|
|
43
43
|
assert_nil event(DOWN, nil, 1, 2, 3).chars
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
+
def test_modifiers()
|
|
47
|
+
e = event DOWN, 'a', 1, Reflex::MOD_CONTROL | Reflex::MOD_CAPS, 0
|
|
48
|
+
assert_equal [:control, :caps], e.modifiers
|
|
49
|
+
assert_equal [:control], e.modifiers(locks: false)
|
|
50
|
+
end
|
|
51
|
+
|
|
46
52
|
end# TestKeyEvent
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestLinkConstraint < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def window()
|
|
7
|
+
Reflex::Window.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def view(x = 0, y = 0, w = 50, h = 50, **options, &block)
|
|
11
|
+
Reflex::View.new(
|
|
12
|
+
frame: [x, y, w, h],
|
|
13
|
+
shape: Reflex::RectShape.new(density: 1),
|
|
14
|
+
**options, &block)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def point(...)
|
|
18
|
+
Reflex::Point.new(...)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def setup_views(win = window)
|
|
22
|
+
v1 = view 100, 100, dynamic: true
|
|
23
|
+
v2 = view 200, 100, static: true
|
|
24
|
+
win&.add v1
|
|
25
|
+
win&.add v2
|
|
26
|
+
[v1, v2, win, win&.root]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_initial_state()
|
|
30
|
+
v1, v2, = setup_views
|
|
31
|
+
|
|
32
|
+
assert_equal v1, v1.link(v2) .pins[0].view
|
|
33
|
+
assert_equal v2, v1.link(v2) .pins[1].view
|
|
34
|
+
assert_nil v1.link(v2) .axis
|
|
35
|
+
assert_equal_point point(1, 0), v1.link(v2, axis: [1, 0]).axis
|
|
36
|
+
assert_equal 100, v1.link(v2) .distance
|
|
37
|
+
assert_equal 1, v1.link(v2, distance: 1) .distance
|
|
38
|
+
assert_equal 2, v1.link(v2, dist: 2) .distance
|
|
39
|
+
assert_nil v1.link(v2) .range
|
|
40
|
+
assert_equal 3..3, v1.link(v2, range: 3) .range
|
|
41
|
+
assert_equal 4..5, v1.link(v2, range: 4..5) .range
|
|
42
|
+
assert_nil v1.link(v2) .motor
|
|
43
|
+
assert_equal 6, v1.link(v2, motor: 6) .motor
|
|
44
|
+
assert_nil v1.link(v2) .force
|
|
45
|
+
assert_equal 8, v1.link(v2, force: 8) .force
|
|
46
|
+
assert_nil v1.link(v2) .spring
|
|
47
|
+
assert_equal 7, v1.link(v2, spring: 7) .spring
|
|
48
|
+
assert_in_delta 0.7, v1.link(v2) .damping
|
|
49
|
+
assert_in_delta 0.1, v1.link(v2, damping: 0.1).damping
|
|
50
|
+
assert_false v1.link(v2) .collide?
|
|
51
|
+
assert_true v1.link(v2) .active?
|
|
52
|
+
assert_false v1.link(v2) .removed?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_link_to_view()
|
|
56
|
+
v1, v2, _, root = setup_views
|
|
57
|
+
root.gravity(-900, 0)
|
|
58
|
+
|
|
59
|
+
c = v1.link v2, dist: 50
|
|
60
|
+
assert_equal v2, c.pins[1].view
|
|
61
|
+
|
|
62
|
+
60.times {root.update_world}
|
|
63
|
+
assert_equal_point point(150, 100), v1.pos
|
|
64
|
+
assert_in_delta 50, c.current_distance, 0.01
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def test_link_to_world()
|
|
68
|
+
v1, _, _, root = setup_views
|
|
69
|
+
root.gravity(-900, 0)
|
|
70
|
+
|
|
71
|
+
c = v1.pin.link [200, 125], dist: 50
|
|
72
|
+
assert_nil c.pins[1].view
|
|
73
|
+
|
|
74
|
+
60.times {root.update_world}
|
|
75
|
+
assert_equal_point point(125, 100), v1.pos
|
|
76
|
+
assert_in_delta 50, c.current_distance, 0.01
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_distance()
|
|
80
|
+
v1, v2, = setup_views
|
|
81
|
+
|
|
82
|
+
c = v1.link v2, dist: 80, spring: 4
|
|
83
|
+
assert_equal 80, c.distance
|
|
84
|
+
assert_equal 80, c.dist
|
|
85
|
+
|
|
86
|
+
c.dist = 90
|
|
87
|
+
assert_equal 90, c.distance
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_range()
|
|
91
|
+
v1, v2, _, root = setup_views
|
|
92
|
+
root.gravity 0, 900
|
|
93
|
+
|
|
94
|
+
c = v1.link v2, distance: 100, range: 0..120, spring: 1, damping: 0
|
|
95
|
+
60.times {root.update_world}
|
|
96
|
+
assert_operator c.current_distance, :<=, 121
|
|
97
|
+
|
|
98
|
+
c.range = nil
|
|
99
|
+
assert_nil c.range
|
|
100
|
+
|
|
101
|
+
assert_raise(ArgumentError) {c.range = 'invalid'}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_motor()
|
|
105
|
+
v1, v2, = setup_views
|
|
106
|
+
|
|
107
|
+
c = v1.link v2, motor: 10
|
|
108
|
+
assert_equal 10, c.motor
|
|
109
|
+
|
|
110
|
+
c.motor = nil
|
|
111
|
+
assert_nil c.motor
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_force()
|
|
115
|
+
v1, v2, = setup_views
|
|
116
|
+
|
|
117
|
+
c = v1.link v2, motor: 10, force: 500
|
|
118
|
+
assert_equal 500, c.force
|
|
119
|
+
|
|
120
|
+
c.force = nil
|
|
121
|
+
assert_nil c.force
|
|
122
|
+
|
|
123
|
+
c.force = 100
|
|
124
|
+
assert_equal 100, c.force
|
|
125
|
+
|
|
126
|
+
assert_raise(ArgumentError) {c.force = -1}
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def test_axis_to_view()
|
|
130
|
+
v1, v2, _, root = setup_views
|
|
131
|
+
root.gravity 900, 900
|
|
132
|
+
|
|
133
|
+
c = v1.link v2, axis: [1, 0]
|
|
134
|
+
assert_equal_point point(1, 0), c.axis
|
|
135
|
+
assert_equal v2, c.pins[1].view
|
|
136
|
+
|
|
137
|
+
root.update_world
|
|
138
|
+
assert_operator v1.linear_velocity.x, :>, 0
|
|
139
|
+
assert_in_delta 0, v1.linear_velocity.y # locked to the axis
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def test_axis_to_world()
|
|
143
|
+
v1, _, _, root = setup_views
|
|
144
|
+
root.gravity 900, 900
|
|
145
|
+
|
|
146
|
+
c = v1.pin.link axis: [1, 0]
|
|
147
|
+
assert_nil c.pins[1].view
|
|
148
|
+
|
|
149
|
+
root.update_world
|
|
150
|
+
assert_operator v1.linear_velocity.x, :>, 0
|
|
151
|
+
assert_in_delta 0, v1.linear_velocity.y
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_axis_locks_rotation()
|
|
155
|
+
v1, v2, _, root = setup_views
|
|
156
|
+
|
|
157
|
+
v1.link v2, axis: [1, 0]
|
|
158
|
+
|
|
159
|
+
v1.angular_velocity = 90
|
|
160
|
+
3.times {root.update_world}
|
|
161
|
+
assert_in_delta 0, v1.angular_velocity # prismatic locks relative rotation
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def test_axis_change()
|
|
165
|
+
v1, v2, _, root = setup_views
|
|
166
|
+
root.gravity 900, 900
|
|
167
|
+
|
|
168
|
+
c = v1.link v2, axis: [1, 0]
|
|
169
|
+
root.update_world
|
|
170
|
+
assert_operator v1.linear_velocity.x, :>, 0
|
|
171
|
+
assert_in_delta 0, v1.linear_velocity.y
|
|
172
|
+
|
|
173
|
+
c.axis = [0, 1]
|
|
174
|
+
assert_equal_point point(0, 1), c.axis
|
|
175
|
+
|
|
176
|
+
root.update_world
|
|
177
|
+
assert_operator v1.linear_velocity.y, :>, 0
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_axis_morphs_between_distance_and_rail()
|
|
181
|
+
v1, v2, = setup_views
|
|
182
|
+
|
|
183
|
+
c = v1.link v2
|
|
184
|
+
assert_nil c.axis # a distance joint has no axis
|
|
185
|
+
|
|
186
|
+
c.axis = [1, 0]
|
|
187
|
+
assert_equal_point point(1, 0), c.axis # now a rail
|
|
188
|
+
|
|
189
|
+
c.axis = nil
|
|
190
|
+
assert_nil c.axis # back to a distance joint
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def test_axis_distance()
|
|
194
|
+
v1, v2, _, root = setup_views
|
|
195
|
+
|
|
196
|
+
c = v1.link v2, axis: [1, 0], distance: 30, spring: 4, damping: 1
|
|
197
|
+
assert_equal 30, c.distance
|
|
198
|
+
|
|
199
|
+
60.times {root.update_world}
|
|
200
|
+
assert_in_delta 30, c.current_distance, 1 # the spring drives to the rest
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def test_axis_distance_is_rest_not_translation()
|
|
204
|
+
v1, v2, _, root = setup_views
|
|
205
|
+
root.gravity 900, 0
|
|
206
|
+
|
|
207
|
+
c = v1.link v2, axis: [1, 0]
|
|
208
|
+
3.times {root.update_world}
|
|
209
|
+
assert_operator c.current_distance.abs, :>, 0 # slides along the axis
|
|
210
|
+
assert_in_delta 0, c.distance # but the rest stays put
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def test_axis_range()
|
|
214
|
+
v1, v2, _, root = setup_views
|
|
215
|
+
root.gravity 0, 900
|
|
216
|
+
|
|
217
|
+
c = v1.pin(25, 25).link v2.pin(25, 25), axis: [0, 1], range: 100..200
|
|
218
|
+
assert_equal 100..200, c.range
|
|
219
|
+
|
|
220
|
+
60.times {root.update_world}
|
|
221
|
+
assert_equal_point point(200, 300), v1.pos
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def test_axis_motor()
|
|
225
|
+
v1, v2, _, root = setup_views
|
|
226
|
+
root.gravity(-900, 0)
|
|
227
|
+
|
|
228
|
+
c = v1.link v2, axis: [1, 0], motor: 100
|
|
229
|
+
assert_equal 100, c.motor
|
|
230
|
+
|
|
231
|
+
3.times {root.update_world}
|
|
232
|
+
assert_operator v1.linear_velocity.x, :>, 1
|
|
233
|
+
assert_in_delta 0, v1.linear_velocity.y
|
|
234
|
+
|
|
235
|
+
c.motor = nil
|
|
236
|
+
assert_nil c.motor
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
end# TestLinkConstraint
|