Files
rmq/spec/traversing.rb
2015-03-20 19:54:57 -07:00

386 lines
13 KiB
Ruby

describe 'traversing' do
before do
@vc = UIViewController.alloc.init
@root_view = @vc.view
@views_hash = {
v_0: {
klass: UIView,
subs: {
v_0: {
klass: UIView,
subs: {
v_0: { klass: UIView, subs: { } },
v_1: { klass: UIImageView, subs: { } },
v_2: { klass: UIView, subs: { } },
v_3: { klass: UILabel, subs: { } }
}
},
v_1: { klass: UILabel, subs: { } },
v_2: { klass: UIView, subs: { } }
}
},
v_1: { klass: UILabel, subs: { } },
v_2: { klass: UILabel, subs: { } },
v_3: {
klass: UIView,
subs: {
v_0: { klass: UIView, subs: { } },
v_1: { klass: UIView, subs: { } },
v_2: {
klass: UIView,
subs: {
v_0: { klass: UIView,
subs: {
v_0: { klass: UILabel, subs: { } },
v_1: { klass: UIView, subs: { } },
v_2: { klass: UIImageView, subs: { } }
}
}
}
}
}
}
}
@views_hash = hash_to_subviews(@root_view, @views_hash)
@v0 = @views_hash[:v_0][:view]
@v3_v2_v0 = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:view]
@last_image = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_2][:view]
@total_views = 18
end
it 'locate view given view' do
q = @vc.rmq(@last_image)
q.length.should == 1
q.get.should == @last_image
end
it 'should return empty array for root_view closest' do
closest = @vc.rmq(@root_view).closest
closest.should.not == nil
closest.is_a?(RubyMotionQuery::RMQ).should == true
RubyMotionQuery::RMQ.is_blank?(closest).should == true
end
it 'should return root_view of the controller' do
@vc.rmq.root_view.should == @vc.view
end
it 'should return empty array for root_view parent' do
parent = @vc.rmq(@root_view).parent
parent.should.not == nil
parent.is_a?(RubyMotionQuery::RMQ).should == true
RubyMotionQuery::RMQ.is_blank?(parent).should == true
end
it 'should return empty array for root_view parents' do
@vc.rmq(@vc.view).parents.length.should == 0
end
it 'should filter given a block' do
q = @vc.rmq.all.filter { |view| view.is_a?(UIImageView) }
q.is_a?(RubyMotionQuery::RMQ).should == true
q.length.should == 2
q = @vc.rmq.all.filter(return_array: true) { |view| view.is_a?(UIImageView) }
q.is_a?(NSArray).should == true
q = @vc.rmq(UILabel, UIView).filter(limit: 1) do |view|
view.is_a?(UILabel)
end
q.length.should == 1
q = @vc.rmq(UIView).filter do |view|
@vc.rmq(view).find.get
end
q.length.should == 25
q = @vc.rmq(UIView).filter(uniq: true) do |view|
@vc.rmq(view).find.get
end
q.length.should == @total_views - 4 # top level views
end
it 'select all subview children, grandchildren, etc for controller and view' do
rmq = @vc.rmq
rmq.should.not == nil
all = rmq.all.to_a
all.length.should == @total_views
all[0].should == @v0
all[1].should == @views_hash[:v_0][:subs][:v_0][:view]
all[2].should == @views_hash[:v_0][:subs][:v_0][:subs][:v_0][:view]
all[3].should == @views_hash[:v_0][:subs][:v_0][:subs][:v_1][:view]
all[4].should == @views_hash[:v_0][:subs][:v_0][:subs][:v_2][:view]
all[5].should == @views_hash[:v_0][:subs][:v_0][:subs][:v_3][:view]
all[6].should == @views_hash[:v_0][:subs][:v_1][:view]
all.last.should == @last_image
@last_image.is_a?(UIImageView).should == true
end
it 'get closest super view, searching for constant' do
@vc.rmq(@views_hash[:v_0][:subs][:v_1][:view]).closest(UIViewController).get.should == @vc
@vc.rmq(@views_hash[:v_0][:subs][:v_0][:subs][:v_1][:view]).closest(UIView).get.should == @views_hash[:v_0][:subs][:v_0][:view]
end
it 'get closest super view, searching for constant, with multiple selected' do
image_views = @vc.rmq(UIImageView)
closest = image_views.closest(UIView)
closest.length.should == 2
a = closest.to_a
a[0].should == @views_hash[:v_0][:subs][:v_0][:view]
a[1].should == @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:view]
end
it 'should remove views from selected when using .not' do
rmq = @vc.rmq(UIImageView).not(@last_image)
rmq.length.should == 1
rmq.get.should == @views_hash[:v_0][:subs][:v_0][:subs][:v_1][:view]
end
it 'should restrict selected when using .and' do
q = @vc.rmq(@v0).children
q.length.should == 3
q.and(UILabel).length.should == 1
q.and(UILabel).get.is_a?(UILabel).should == true
q.and(UIView).length.should == 3
s = @vc.rmq(@v0).children[0].children
s.length.should == 4
s.and(UILabel).length.should == 1
s.and(UILabel).get.is_a?(UILabel).should == true
s.and(UIImageView).length.should == 1
s.and(UIImageView).get.is_a?(UIImageView).should == true
end
it 'should add parent to selected when using .and_self' do
test_view = @v0
q = @vc.rmq(test_view).children
q.length.should == 3
q.get.should.not.include(test_view)
q = q.add_self
q.length.should == 4
q.get.should.include(test_view)
end
it 'should return parent rmq using .back' do
test_view = @v0
a = @vc.rmq(test_view)
a.get.should == @vc.rmq(test_view).children.back.get
# This is a good example of when you'd use .back
@vc.rmq(test_view).find(UIImageView).tag(:foo).back.find(UILabel).tag(:bar)
@vc.rmq(:foo).get.should == @vc.rmq(test_view).find(UIImageView).get
@vc.rmq(:bar).get.should == @vc.rmq(test_view).find(UILabel).get
end
it 'should return parent / superview' do
@vc.rmq(@last_image).parent.get.should == @v3_v2_v0
@vc.rmq(@last_image).superview.get.should == @v3_v2_v0
@vc.rmq(UIImageView).parent.length.should == 2
end
it 'should return parents / superviews' do
@vc.rmq(@last_image).parents.length.should == 4
@vc.rmq.all.parents.length.should == 6 # All views that have subviews
end
it 'should return children of a view' do
q = @vc.rmq(@v0).children
q.length.should == 3
q = @vc.rmq(@v0).find # children and sub children
q.length.should == 7
q = @vc.rmq(@views_hash[:v_1][:view]).children
q.length.should == 0
end
it 'should return children of multiple views' do
@vc.rmq.all.children.length.should == @total_views - 4 # top views
q = @vc.rmq(@v0, @v3_v2_v0).children
q.length.should == 6
q.get.should.include(@last_image)
q.get.should.not.include(@v3_v2_v0)
q.get.should.not.include(@v0)
end
it 'should return children and sub-children of a view using .find' do
@vc.rmq.find.length.should == @total_views
@vc.rmq.all.find.length.should == @total_views - 4 # top views
@vc.rmq(@v0).find.length.should == 7
@vc.rmq(@v0).find(UILabel).length.should == 2
@vc.rmq(@v3_v2_v0).find(UIImageView).get.should == @last_image
end
it 'should return children and sub-children of multiple views using .find' do
@vc.rmq.all.length.should == @total_views
@vc.rmq(UIView).length.should == @total_views
@vc.rmq.find.length.should == @total_views
@vc.rmq.find(UIView).length.should == @total_views
@vc.rmq.children(UIView).find(UILabel).length.should == 3
end
it 'should return the siblings of a view' do
test_view = @views_hash[:v_0][:subs][:v_0][:subs][:v_1][:view]
q = @vc.rmq(test_view)
q.get.should == test_view
q = q.siblings
q.length.should == (test_view.superview.subviews.length - 1)
q.get.should.not.include(test_view)
end
it 'should return the siblings of multiple views' do
q = @vc.rmq(UIImageView)
q.length.should == 2
qsiblings = q.siblings
qsiblings.length.should == 5
qsiblings.get.should.not.include(q.get)
qsiblings.not(UILabel).length.should == 3
end
it 'should return next sibling of a view' do
test_view = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_1][:view]
@vc.rmq(test_view).next.get.should == @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_2][:view]
end
it 'should return previous sibling of a view' do
test_view = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_1][:view]
@vc.rmq(test_view).prev.get.should == @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_0][:view]
end
it 'next should return empty rmq if it is at the end of the subviews' do
@vc.rmq(@v3_v2_v0).next.length.should == 0
test_view = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_2][:view]
@vc.rmq(test_view).next.length.should == 0
end
it 'next should return empty rmq if it is at the begnning of the subviews' do
@vc.rmq(@v3_v2_v0).prev.length.should == 0
test_view = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_0][:view]
@vc.rmq(test_view).prev.length.should == 0
end
it 'should return next sibling of a multiple views' do
test_view_0 = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_0][:view]
test_view_1 = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_1][:view]
test_view_2 = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_2][:view]
@vc.rmq(test_view_0, test_view_1).next.get.should == [test_view_1, test_view_2]
end
it 'should return next sibling of a multiple views' do
test_view_0 = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_0][:view]
test_view_1 = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_1][:view]
test_view_2 = @views_hash[:v_3][:subs][:v_2][:subs][:v_0][:subs][:v_2][:view]
@vc.rmq(test_view_1, test_view_2).prev.get.should == [test_view_0, test_view_1]
end
it 'should return the window that the controller is sitting in' do
@vc.rmq.window.should == @vc.view.window
end
describe 'rmq.view controller' do
before do
@vc1 = UIViewController.alloc.init
@vc2 = UIViewController.alloc.init
end
it 'should be located if the rmq methods is called from within a controller' do
@vc1.rmq.view_controller.should == @vc1
end
it "should always return the controller that the rmq method is called in, regardless if the view it's wrapping has its own controller" do
@vc2.rmq.view_controller.should == @vc2
view_1 = UIView.alloc.initWithFrame(CGRectZero)
view_1.rmq_data.view_controller = @vc1
# This rmq instance won't be associated with any controller
RubyMotionQuery::RMQ.new.wrap(view_1).view_controller.should == @vc1
@vc2.rmq(view_1).view_controller.should == @vc2
end
it 'should be the current controller, if a view is not in a subview tree and that view has NOT been assigned a view_controller to rmq_data' do
view_4 = UIView.alloc.initWithFrame(CGRectZero)
q = RubyMotionQuery::RMQ.new
q.wrap(view_4).view_controller.should == q.app.window.rootViewController.visibleViewController
end
it 'should be located from any view if the view is in subview tree of a controller' do
@v0.rmq.view_controller.should == @vc
@last_image.rmq.view_controller.should == @vc
view_1 = @vc2.rmq.append(UIView).get
view_1.rmq.view_controller.should == @vc2
view_2 = UIView.alloc.initWithFrame(CGRectZero)
view_1.addSubview(view_2)
view_2.rmq.view_controller.should == @vc2
view_3 = UIView.alloc.initWithFrame(CGRectZero)
view_2.addSubview(view_3)
view_3.rmq.view_controller.should == @vc2
end
it 'should be located if a view is not in a subview tree and that view has been assigned a view_controller to rmq_data' do
view_1 = @vc2.rmq.create(UIView).get
view_1.rmq_data.view_controller.should == @vc2
view_1.rmq.view_controller.should == @vc2
RubyMotionQuery::RMQ.new.wrap(view_1).view_controller.should == @vc2
@vc.rmq.append(view_1)
RubyMotionQuery::RMQ.new.wrap(view_1).view_controller.should == @vc
view_1.rmq_data.view_controller.should == @vc
view_1.rmq.view_controller.should == @vc
view_2 = UIView.alloc.initWithFrame(CGRectZero)
view_2.rmq_data.view_controller = @vc2
RubyMotionQuery::RMQ.new.wrap(view_2).view_controller.should == @vc2
end
it 'should assign a found controller to a view that did not have one' do
orphan_view = UIView.alloc.initWithFrame(CGRectZero)
orphan_view.rmq_data.view_controller.should == nil
vc = orphan_view.rmq.view_controller
data_vc = orphan_view.rmq_data.view_controller
# This fails oddly, so we'll check type ad ID, seems a bug in RM
#data_vc.should == vc
vc.class.should == data_vc.class
vc.object_id.should == data_vc.object_id
end
it 'should not wrap a WeakRef in another WeakRef (was bug)' do
# Many ways to cause this bug, I'll do a few here
q = @vc1.rmq
q.view_controller = @vc1
view = q.append(UIView).get
view.rmq.append(UIView)
q2 = view.rmq.wrap(UIView)
q2.view_controller.is_a?(UIViewController).should == true
view.rmq.context.rmq_data.view_controller.is_a?(UIViewController).should == true
orphan_view = UIView.alloc.initWithFrame(CGRectZero)
orphan_view.rmq_data.view_controller = rmq(orphan_view).view_controller
orphan_view.rmq.view_controller = orphan_view.rmq_data.view_controller
orphan_view.rmq.view_controller.is_a?(UIViewController).should == true
end
end
end