rugui 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +165 -0
- data/README +67 -0
- data/README.rdoc +67 -0
- data/Rakefile +56 -0
- data/VERSION.yml +4 -0
- data/bin/rugui +16 -0
- data/lib/rugui/base_controller.rb +194 -0
- data/lib/rugui/base_model.rb +22 -0
- data/lib/rugui/base_object.rb +73 -0
- data/lib/rugui/base_view.rb +302 -0
- data/lib/rugui/base_view_helper.rb +23 -0
- data/lib/rugui/configuration.rb +136 -0
- data/lib/rugui/framework_adapters/GTK.rb +233 -0
- data/lib/rugui/framework_adapters/Qt4.rb +171 -0
- data/lib/rugui/framework_adapters/base_framework_adapter.rb +90 -0
- data/lib/rugui/framework_adapters/framework_adapter_support.rb +35 -0
- data/lib/rugui/gem_builder.rb +21 -0
- data/lib/rugui/gem_dependency.rb +282 -0
- data/lib/rugui/initialize_hooks.rb +36 -0
- data/lib/rugui/initializer.rb +162 -0
- data/lib/rugui/log_support.rb +118 -0
- data/lib/rugui/observable_property_proxy.rb +73 -0
- data/lib/rugui/observable_property_support.rb +251 -0
- data/lib/rugui/plugin/loader.rb +77 -0
- data/lib/rugui/property_observer.rb +58 -0
- data/lib/rugui/signal_support.rb +57 -0
- data/lib/rugui/tasks/gems_application.rake +71 -0
- data/lib/rugui/tasks/rugui.rb +8 -0
- data/lib/rugui/tasks/rugui_framework.rb +4 -0
- data/lib/rugui/tasks/runner_application.rake +4 -0
- data/lib/rugui/tasks/spec_application.rake +64 -0
- data/lib/rugui/tasks/spec_framework.rake +27 -0
- data/lib/rugui/tasks/test_application.rake +77 -0
- data/lib/rugui/vendor_gem_source_index.rb +140 -0
- data/lib/rugui/version.rb +9 -0
- data/lib/rugui.rb +37 -0
- data/spec/framework/base_controller_spec.rb +48 -0
- data/spec/framework/base_model_spec.rb +13 -0
- data/spec/framework/base_view_helper_spec.rb +13 -0
- data/spec/framework/base_view_spec.rb +92 -0
- data/spec/framework/log_support_spec.rb +16 -0
- data/spec/framework/observable_property_proxy_spec.rb +67 -0
- data/spec/framework/observable_property_support_spec.rb +283 -0
- data/spec/framework/property_observer_spec.rb +88 -0
- data/spec/helpers/controllers.rb +29 -0
- data/spec/helpers/initialize_hooks_helper.rb +18 -0
- data/spec/helpers/models.rb +9 -0
- data/spec/helpers/observables.rb +210 -0
- data/spec/helpers/view_helpers.rb +9 -0
- data/spec/helpers/views.rb +72 -0
- data/spec/rcov.opts +1 -0
- data/spec/resource_files/my_other_view.glade +46 -0
- data/spec/resource_files/my_view.glade +46 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +15 -0
- metadata +149 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'views')
|
4
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'view_helpers')
|
5
|
+
|
6
|
+
describe RuGUI::BaseView do
|
7
|
+
before(:each) do
|
8
|
+
@my_view = MyView.new
|
9
|
+
@my_child_view = MyChildView.new
|
10
|
+
@my_other_view = MyOtherView.new
|
11
|
+
@my_other_view_instance = MyOtherView.new
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "with view widget registering" do
|
15
|
+
it "should make widgets available as attributes in the view class instance" do
|
16
|
+
@my_view.top_window.should be_an_instance_of(Gtk::Window)
|
17
|
+
@my_view.vertical_container.should be_an_instance_of(Gtk::VBox)
|
18
|
+
@my_view.button_above.should be_an_instance_of(Gtk::Button)
|
19
|
+
@my_view.button_below.should be_an_instance_of(Gtk::Button)
|
20
|
+
@my_view.label.should be_an_instance_of(Gtk::Label)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "with builder file accessor" do
|
25
|
+
it "should return different value for different view classes" do
|
26
|
+
@my_view.builder_file.should_not == @my_other_view.builder_file
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return the same value for same view classes" do
|
30
|
+
@my_other_view.builder_file.should == @my_other_view_instance.builder_file
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return the same value for subclasses which don't override it" do
|
34
|
+
@my_view.builder_file.should == @my_child_view.builder_file
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "when creating a view without builder file" do
|
39
|
+
it "should not raise error" do
|
40
|
+
lambda {
|
41
|
+
@no_builder_view_instance = NoBuilderView.new
|
42
|
+
}.should_not raise_error(RuGUI::BuilderFileNotFoundError)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "when including a child view into a parent view" do
|
47
|
+
it "should include the root widget of the child view into the specified widget in the parent view" do
|
48
|
+
@my_view.include_view :vertical_container, @my_child_view
|
49
|
+
@my_view.vertical_container.children.include?(@my_child_view.root_widget).should be_true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "whent removing a child view from a parent view" do
|
54
|
+
before do
|
55
|
+
@my_view.include_view :vertical_container, @my_child_view
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should remove the root widget of the child view from the specified widget in the parent view" do
|
59
|
+
@my_view.remove_view :vertical_container, @my_child_view
|
60
|
+
@my_view.vertical_container.children.include?(@my_child_view.root_widget).should_not be_true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "with view helpers" do
|
65
|
+
it "should include a default view helper automatically if it exists" do
|
66
|
+
@my_view.respond_to?(:helper).should be_true
|
67
|
+
@my_view.helper.should be_an_instance_of(MyViewHelper)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should not include a default view helper automatically if it does not exists" do
|
71
|
+
@my_other_view.respond_to?(:helper).should be_false
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should notify the view when an observable property is changed in the view helper" do
|
75
|
+
@my_view.helper.message = "another message"
|
76
|
+
@my_view.message.should == "MyViewHelper property message changed from Some label in the middle to another message"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should be notified using named observable property change calls" do
|
80
|
+
@my_view.my_other_view_helper_instance.message = "foo"
|
81
|
+
@my_view.message.should == "Property message of my_other_view_helper_instance changed from Some label in the middle to foo"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "with initialization hooks" do
|
86
|
+
it "should call before initialize and after initialize methods" do
|
87
|
+
view = MyView.new
|
88
|
+
view.before_initialize_called?.should be_true
|
89
|
+
view.after_initialize_called?.should be_true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
2
|
+
|
3
|
+
class MyObjectWithLogSupport
|
4
|
+
include RuGUI::LogSupport
|
5
|
+
end
|
6
|
+
|
7
|
+
describe RuGUI::LogSupport do
|
8
|
+
before(:each) do
|
9
|
+
@my_object_with_log_support = MyObjectWithLogSupport.new
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should have a default logger if it is not initialized" do
|
13
|
+
@my_object_with_log_support.respond_to?(:logger).should be_true
|
14
|
+
@my_object_with_log_support.logger.should be_an_instance_of(Logger)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'observables')
|
3
|
+
|
4
|
+
describe RuGUI::ObservablePropertyProxy do
|
5
|
+
before(:each) do
|
6
|
+
@observable = FakeObservable.new
|
7
|
+
@custom_type = CustomType.new
|
8
|
+
@custom_type.custom_property = "initial_value"
|
9
|
+
|
10
|
+
@observable_properties = {
|
11
|
+
:object => RuGUI::ObservablePropertyProxy.new(Object.new, @observable, :my_object_observable_property),
|
12
|
+
:string => RuGUI::ObservablePropertyProxy.new("some_value", @observable, :my_string_observable_property),
|
13
|
+
:fixnum => RuGUI::ObservablePropertyProxy.new(1, @observable, :my_fixnum_observable_property),
|
14
|
+
:float => RuGUI::ObservablePropertyProxy.new(1.1, @observable, :my_float_observable_property),
|
15
|
+
:array => RuGUI::ObservablePropertyProxy.new([], @observable, :my_array_observable_property),
|
16
|
+
:hash => RuGUI::ObservablePropertyProxy.new({}, @observable, :my_hash_observable_property),
|
17
|
+
:custom_type => RuGUI::ObservablePropertyProxy.new(@custom_type, @observable, :my_custom_type_observable_property),
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
[:object, :string, :fixnum, :float, :array, :hash, :custom_type].each do |type|
|
22
|
+
describe "with #{type.to_s.camelize} observable properties" do
|
23
|
+
it "should work as proxy for #{type.to_s.camelize} methods" do
|
24
|
+
@observable_properties[type].should be_an_instance_of(type.to_s.camelize.constantize)
|
25
|
+
type.to_s.camelize.constantize.instance_methods.each do |method_name|
|
26
|
+
@observable_properties[type].respond_to?(method_name).should be_true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "with notification" do
|
33
|
+
it "should notifiy the observable when calling methods that changes the observable property" do
|
34
|
+
@observable_properties[:string].reverse! # reversing a string
|
35
|
+
@observable.property_changed_message.should == "my_string_observable_property changed from some_value to eulav_emos"
|
36
|
+
|
37
|
+
@observable_properties[:array] << 1 # adding an element into an array
|
38
|
+
@observable.property_changed_message.should == "my_array_observable_property changed from to 1"
|
39
|
+
|
40
|
+
@observable_properties[:hash][:key] = "value" # setting or changing a value in a hash
|
41
|
+
@observable.property_changed_message.should == "my_hash_observable_property changed from to keyvalue"
|
42
|
+
|
43
|
+
@observable_properties[:custom_type].change_custom_property("new_value") # calling a custom method which changes the property
|
44
|
+
@observable.property_changed_message.should == "my_custom_type_observable_property changed from initial_value to new_value"
|
45
|
+
|
46
|
+
@observable_properties[:custom_type].custom_property = "another_new_value" # changing a custom property with setter method
|
47
|
+
@observable.property_changed_message.should == "my_custom_type_observable_property changed from new_value to another_new_value"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should not notifiy the observable when calling methods that does not changes the observable property" do
|
51
|
+
@observable_properties[:string].reverse # reversing a string and returning a new copy of it
|
52
|
+
@observable.property_changed_message.should be_nil
|
53
|
+
|
54
|
+
@observable_properties[:array].index("some_value") # getting an element in the array
|
55
|
+
@observable.property_changed_message.should be_nil
|
56
|
+
|
57
|
+
@observable_properties[:hash].include?("some_key") # checking if a key is included in a hash
|
58
|
+
@observable.property_changed_message.should be_nil
|
59
|
+
|
60
|
+
@observable_properties[:custom_type].custom_method # calling a custom method which does not change
|
61
|
+
@observable.property_changed_message.should be_nil
|
62
|
+
|
63
|
+
@observable_properties[:custom_type].custom_method_with_parameters("something", "something else", "arg1", "arg2", "arg...") # calling a custom method which does not change
|
64
|
+
@observable.property_changed_message.should be_nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,283 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'observables')
|
4
|
+
|
5
|
+
describe RuGUI::ObservablePropertySupport do
|
6
|
+
before(:each) do
|
7
|
+
@observable = AnotherFakeObservable.new
|
8
|
+
@observer = AnotherFakeObserver.new
|
9
|
+
@observable.register_observer(@observer)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "with notification" do
|
13
|
+
it "should notify the observer when setting a new value in a observable property" do
|
14
|
+
@observable.my_observable_property = "something"
|
15
|
+
@observer.property_updated_message.should == "AnotherFakeObservable property my_observable_property changed from to something"
|
16
|
+
|
17
|
+
@observable.my_observable_property = 1
|
18
|
+
@observer.property_updated_message.should == "AnotherFakeObservable property my_observable_property changed from something to 1"
|
19
|
+
|
20
|
+
@observable.my_observable_property = ["somearray"]
|
21
|
+
@observer.property_updated_message.should == "AnotherFakeObservable property my_observable_property changed from 1 to somearray"
|
22
|
+
|
23
|
+
@observable.my_observable_property = {'key' => "value"}
|
24
|
+
@observer.property_updated_message.should == "AnotherFakeObservable property my_observable_property changed from somearray to key"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should notify the observer when changing the value of a observable property" do
|
28
|
+
@observable.my_observable_property = "something"
|
29
|
+
@observable.my_observable_property << "_else"
|
30
|
+
@observer.property_updated_message.should == "AnotherFakeObservable property my_observable_property changed from something to something_else"
|
31
|
+
|
32
|
+
@observable.my_observable_property = ["somearray"]
|
33
|
+
@observable.my_observable_property << "another_value"
|
34
|
+
@observer.property_updated_message.should == "AnotherFakeObservable property my_observable_property changed from somearray to somearrayanother_value"
|
35
|
+
|
36
|
+
@observable.my_observable_property = {'key' => "value"}
|
37
|
+
@observable.my_observable_property['another_key'] = "another_value"
|
38
|
+
@observer.property_updated_message.should == "AnotherFakeObservable property my_observable_property changed from key to another_keykey"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should not notify the observer when setting the same value in a observable property" do
|
42
|
+
set_same_value_twice_clearing_property_updated_message("something")
|
43
|
+
@observer.property_updated_message.should be_nil
|
44
|
+
|
45
|
+
set_same_value_twice_clearing_property_updated_message(["somearray"])
|
46
|
+
@observer.property_updated_message.should be_nil
|
47
|
+
|
48
|
+
set_same_value_twice_clearing_property_updated_message({'key' => "value"})
|
49
|
+
@observer.property_updated_message.should be_nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_same_value_twice_clearing_property_updated_message(value)
|
53
|
+
@observable.my_observable_property = value
|
54
|
+
@observer.property_updated_message = nil
|
55
|
+
@observable.my_observable_property = value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "with CustomType observable properties" do
|
60
|
+
it "should notify the observer when changing the CustomType instance changes" do
|
61
|
+
custom_type_fake_observable = CustomTypeFakeObservable.new
|
62
|
+
custom_type_fake_observable.register_observer(@observer)
|
63
|
+
|
64
|
+
# Setting a value.
|
65
|
+
custom_type_fake_observable.custom_type_observable_property.core_observable_property = "foo"
|
66
|
+
|
67
|
+
# The observer must be notified, the message itself does not need to be meaniful
|
68
|
+
@observer.property_updated_message.should == "CustomTypeFakeObservable property custom_type_observable_property changed from AnotherFakeObservable to AnotherFakeObservable"
|
69
|
+
|
70
|
+
# Clearing the observer property_updated_message
|
71
|
+
@observer.property_updated_message = nil
|
72
|
+
|
73
|
+
# Reseting
|
74
|
+
custom_type_fake_observable.reset!
|
75
|
+
|
76
|
+
# The observer must be notified, the message itself does not need to be meaniful
|
77
|
+
@observer.property_updated_message.should == "CustomTypeFakeObservable property custom_type_observable_property changed from AnotherFakeObservable to AnotherFakeObservable"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "with observable property options" do
|
82
|
+
it "should initialize properties configured with an initial value properly" do
|
83
|
+
@observable.initialized_observable_property.should == "some_initial_value"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should set the configured reset_value when reseting an observable" do
|
87
|
+
@observable.resetable_observable_property.should be_nil
|
88
|
+
@observable.reset!
|
89
|
+
@observable.resetable_observable_property.should == "some_reset_value"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should set the inital_value and the reset_value as appropriate" do
|
93
|
+
@observable.initialized_and_resetable_observable_property.should == "some_initial_value"
|
94
|
+
@observable.reset!
|
95
|
+
@observable.initialized_and_resetable_observable_property.should == "some_reset_value"
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should not be shared among different observable classes" do
|
99
|
+
observable_properties_options = {
|
100
|
+
:core_observable_property => { :core => true, :initial_value => "some_initial_value", :reset_value => "some_initial_value" },
|
101
|
+
:initialized_observable_property => { :core => false, :initial_value => "some_initial_value", :reset_value => "some_initial_value" },
|
102
|
+
:resetable_observable_property => { :core => false, :initial_value => nil, :reset_value => "some_reset_value" },
|
103
|
+
:initialized_and_resetable_observable_property => { :core => false, :initial_value => "some_initial_value", :reset_value => "some_reset_value" },
|
104
|
+
:my_observable_property => { :core => false, :initial_value => nil, :reset_value => nil },
|
105
|
+
:my_array_observable_property => { :reset_value => [], :initial_value => [], :core => false },
|
106
|
+
:my_hash_observable_property => { :reset_value => {}, :initial_value => {}, :core => false },
|
107
|
+
}
|
108
|
+
AnotherFakeObservable.observable_properties_options.should == observable_properties_options
|
109
|
+
|
110
|
+
observable_properties_options = {
|
111
|
+
:another_observable_property => {:core => false, :initial_value => "some_other_initial_value", :reset_value => "some_other_initial_value"},
|
112
|
+
:first_core_observable_property => {:core => true, :initial_value => "first", :reset_value => "first"},
|
113
|
+
:second_core_observable_property => {:core => true, :initial_value => "second", :reset_value => "second"},
|
114
|
+
}
|
115
|
+
SomeOtherFakeObservable.observable_properties_options.should == observable_properties_options
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should not let initial_value and reset_value be modified when the property value changes" do
|
119
|
+
AnotherFakeObservable.observable_properties_options[:my_array_observable_property][:initial_value].should == []
|
120
|
+
AnotherFakeObservable.observable_properties_options[:my_array_observable_property][:reset_value].should == []
|
121
|
+
|
122
|
+
AnotherFakeObservable.observable_properties_options[:my_hash_observable_property][:initial_value].should == {}
|
123
|
+
AnotherFakeObservable.observable_properties_options[:my_hash_observable_property][:reset_value].should == {}
|
124
|
+
|
125
|
+
@observable.my_array_observable_property << 1
|
126
|
+
AnotherFakeObservable.observable_properties_options[:my_array_observable_property][:initial_value].should == []
|
127
|
+
AnotherFakeObservable.observable_properties_options[:my_array_observable_property][:reset_value].should == []
|
128
|
+
|
129
|
+
@observable.my_hash_observable_property[:foo] = 'bar'
|
130
|
+
AnotherFakeObservable.observable_properties_options[:my_hash_observable_property][:initial_value].should == {}
|
131
|
+
AnotherFakeObservable.observable_properties_options[:my_hash_observable_property][:reset_value].should == {}
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should prevent properties from being reset if configured" do
|
135
|
+
observable = ResetPreventedFakeObservable.new
|
136
|
+
observable.reset_prevented_observable_property = 'bar'
|
137
|
+
observable.reset!
|
138
|
+
observable.reset_prevented_observable_property.should == 'bar'
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should prevent properties from being reset even if a :reset_value was configured" do
|
142
|
+
observable = ResetPreventedFakeObservable.new
|
143
|
+
observable.reset_prevented_with_reset_value_observable_property = 'bar'
|
144
|
+
observable.reset!
|
145
|
+
observable.reset_prevented_with_reset_value_observable_property.should == 'bar'
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should create 'question' methods for configured boolean properties" do
|
149
|
+
observable = BooleanPropertiesFakeObservable.new
|
150
|
+
observable.boolean_observable_property = true
|
151
|
+
observable.respond_to?(:boolean_observable_property?).should be_true
|
152
|
+
observable.boolean_observable_property?.should be_true
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should not create 'question' methods for non boolean properties" do
|
156
|
+
observable = BooleanPropertiesFakeObservable.new
|
157
|
+
observable.non_boolean_observable_property = "any other value"
|
158
|
+
observable.respond_to?(:non_boolean_observable_property?).should be_false
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "with two instances comparison" do
|
163
|
+
it "should be equals when all configured core observable properties are equals" do
|
164
|
+
some_other_observable = AnotherFakeObservable.new
|
165
|
+
some_other_observable.should == @observable
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should not be equals when at least one of the configured core observable properties are not equals" do
|
169
|
+
some_other_observable1 = SomeOtherFakeObservable.new
|
170
|
+
some_other_observable1.first_core_observable_property = "different_value"
|
171
|
+
some_other_observable2 = SomeOtherFakeObservable.new
|
172
|
+
some_other_observable1.should_not == some_other_observable2
|
173
|
+
|
174
|
+
some_other_observable1 = SomeOtherFakeObservable.new
|
175
|
+
some_other_observable2 = SomeOtherFakeObservable.new
|
176
|
+
some_other_observable2.first_core_observable_property = "different_value"
|
177
|
+
some_other_observable1.should_not == some_other_observable2
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "with observable properties copy" do
|
182
|
+
before(:each) do
|
183
|
+
@parent = ParentFakeObservable.new
|
184
|
+
@child = ChildFakeObservable.new
|
185
|
+
@parent.child_observable_property = @child
|
186
|
+
|
187
|
+
@parent.my_own_observable_property = "parent"
|
188
|
+
@child.my_observable_property = "child"
|
189
|
+
|
190
|
+
@another_parent = ParentFakeObservable.new
|
191
|
+
@another_child = ChildFakeObservable.new
|
192
|
+
@another_parent.child_observable_property = @another_child
|
193
|
+
|
194
|
+
@another_parent.my_own_observable_property = "another_parent"
|
195
|
+
@another_child.my_observable_property = "another child"
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should copy all observable properties from observables which have common properties" do
|
199
|
+
@parent.copy_observable_properties_from(@another_parent)
|
200
|
+
@parent.my_own_observable_property.should == @another_parent.my_own_observable_property
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should perform deep copy of observable properties which holds observables" do
|
204
|
+
@parent.copy_observable_properties_from(@another_parent)
|
205
|
+
@parent.child_observable_property.should == @another_parent.child_observable_property
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should not perform deep copy if 'deep' parameter is false" do
|
209
|
+
@parent.copy_observable_properties_from(@another_parent, false)
|
210
|
+
@parent.my_own_observable_property.should == @another_parent.my_own_observable_property
|
211
|
+
@parent.child_observable_property.should_not == @another_parent.child_observable_property
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "with observable properties mapped for an instance" do
|
216
|
+
before(:each) do
|
217
|
+
@observable = SomeOtherFakeObservable.new
|
218
|
+
@observable.first_core_observable_property = "first value"
|
219
|
+
@observable.second_core_observable_property = "second value"
|
220
|
+
@observable.another_observable_property = "another observable value"
|
221
|
+
|
222
|
+
@mock_observable_properties = {
|
223
|
+
:first_core_observable_property => "first value",
|
224
|
+
:second_core_observable_property => "second value",
|
225
|
+
:another_observable_property => "another observable value"
|
226
|
+
}
|
227
|
+
|
228
|
+
@another_mock_observable_properties = {
|
229
|
+
:another_observable_property => "another",
|
230
|
+
:first_core_observable_property => "first",
|
231
|
+
:second_core_observable_property => "second"
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should return a map of all observable properties with theirs values" do
|
236
|
+
@observable.observable_properties.should == @mock_observable_properties
|
237
|
+
end
|
238
|
+
|
239
|
+
describe "with initial value in initialization method" do
|
240
|
+
it "should set observable properties values" do
|
241
|
+
observable = SomeOtherFakeObservable.new(@mock_observable_properties)
|
242
|
+
observable.observable_properties.should == @mock_observable_properties
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "without initial value in initialization method" do
|
247
|
+
it "should use :initial_value for observable properties values" do
|
248
|
+
observable = SomeOtherFakeObservable.new :another_observable_property => "another"
|
249
|
+
observable.observable_properties.should == @another_mock_observable_properties
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe "updating observable properties values" do
|
254
|
+
before do
|
255
|
+
@observable = SomeOtherFakeObservable.new :another_observable_property => "fake data"
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should update values" do
|
259
|
+
@observable.update_observable_properties({ :another_observable_property => "another" })
|
260
|
+
@observable.observable_properties.should == @another_mock_observable_properties
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should ignore non observable properties values" do
|
264
|
+
@observable.update_observable_properties({ :another_observable_property => "another", :id => 151 })
|
265
|
+
@observable.observable_properties.should == @another_mock_observable_properties
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
describe "with indifferent hash access" do
|
270
|
+
it "should accept property names with both string or symbol keys" do
|
271
|
+
observable = SomeOtherFakeObservable.new :another_observable_property => "fake data"
|
272
|
+
observable.another_observable_property.should == "fake data"
|
273
|
+
observable.update_observable_properties({ :another_observable_property => "another" })
|
274
|
+
observable.another_observable_property.should == "another"
|
275
|
+
|
276
|
+
observable = SomeOtherFakeObservable.new 'another_observable_property' => "fake data"
|
277
|
+
observable.another_observable_property.should == "fake data"
|
278
|
+
observable.update_observable_properties({ 'another_observable_property' => "another" })
|
279
|
+
observable.another_observable_property.should == "another"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'observables')
|
4
|
+
|
5
|
+
describe RuGUI::PropertyObserver do
|
6
|
+
before(:each) do
|
7
|
+
@observer = FakeObserverForPropertyObserverTest.new
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "with notification" do
|
11
|
+
it "should be notified when setting a new value in a observable property" do
|
12
|
+
@observer.observable.my_observable_property = "something"
|
13
|
+
@observer.property_updated_message.should == "FakeObservableForPropertyObserverTest property my_observable_property changed from to something"
|
14
|
+
|
15
|
+
@observer.observable.my_observable_property = 1
|
16
|
+
@observer.property_updated_message.should == "FakeObservableForPropertyObserverTest property my_observable_property changed from something to 1"
|
17
|
+
|
18
|
+
@observer.observable.my_observable_property = ["somearray"]
|
19
|
+
@observer.property_updated_message.should == "FakeObservableForPropertyObserverTest property my_observable_property changed from 1 to somearray"
|
20
|
+
|
21
|
+
@observer.observable.my_observable_property = {'key' => "value"}
|
22
|
+
@observer.property_updated_message.should == "FakeObservableForPropertyObserverTest property my_observable_property changed from somearray to key"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be notified when changing the value of a observable property" do
|
26
|
+
@observer.observable.my_observable_property = "something"
|
27
|
+
@observer.observable.my_observable_property << "_else"
|
28
|
+
@observer.property_updated_message.should == "FakeObservableForPropertyObserverTest property my_observable_property changed from something to something_else"
|
29
|
+
|
30
|
+
@observer.observable.my_observable_property = ["somearray"]
|
31
|
+
@observer.observable.my_observable_property << "another_value"
|
32
|
+
@observer.property_updated_message.should == "FakeObservableForPropertyObserverTest property my_observable_property changed from somearray to somearrayanother_value"
|
33
|
+
|
34
|
+
@observer.observable.my_observable_property = {'key' => "value"}
|
35
|
+
@observer.observable.my_observable_property['another_key'] = "another_value"
|
36
|
+
@observer.property_updated_message.should == "FakeObservableForPropertyObserverTest property my_observable_property changed from key to another_keykey"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not be notified when setting the same value in a observable property" do
|
40
|
+
set_same_value_twice_clearing_property_updated_message("something")
|
41
|
+
@observer.property_updated_message.should be_nil
|
42
|
+
|
43
|
+
set_same_value_twice_clearing_property_updated_message(["somearray"])
|
44
|
+
@observer.property_updated_message.should be_nil
|
45
|
+
|
46
|
+
set_same_value_twice_clearing_property_updated_message({'key' => "value"})
|
47
|
+
@observer.property_updated_message.should be_nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_same_value_twice_clearing_property_updated_message(value)
|
51
|
+
@observer.observable.my_observable_property = value
|
52
|
+
@observer.property_updated_message = nil
|
53
|
+
@observer.observable.my_observable_property = value
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "class specific methods" do
|
58
|
+
it "should be called when observable property changes" do
|
59
|
+
@observer.observable.my_observable_property = "something"
|
60
|
+
@observer.class_specific_method_called_message.should == "Property my_observable_property changed, called from class specific method"
|
61
|
+
|
62
|
+
# clearing message
|
63
|
+
@observer.class_specific_method_called_message = nil
|
64
|
+
|
65
|
+
@observer.observable.my_observable_property << "something"
|
66
|
+
@observer.class_specific_method_called_message.should == "Property my_observable_property changed, called from class specific method"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "named instance specific methods" do
|
71
|
+
it "should be called when observable property changes" do
|
72
|
+
@observer.named_observable.my_observable_property = "something"
|
73
|
+
@observer.instance_specific_method_called_message.should == "Property my_observable_property changed, called from named instance specific method"
|
74
|
+
|
75
|
+
# clearing message
|
76
|
+
@observer.instance_specific_method_called_message = nil
|
77
|
+
|
78
|
+
@observer.named_observable.my_observable_property << "something"
|
79
|
+
@observer.instance_specific_method_called_message.should == "Property my_observable_property changed, called from named instance specific method"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should not be called when the instance name collides with the class name" do
|
83
|
+
lambda {
|
84
|
+
@observer.fake_named_observable_test.my_observable_property = "something"
|
85
|
+
}.should change(@observer, :property_changed_counter).by(1) # Should call only the class method
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Defines some controllers used in specs.
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'initialize_hooks_helper')
|
4
|
+
|
5
|
+
class MyController < RuGUI::BaseController
|
6
|
+
include InitializeHooksHelper
|
7
|
+
|
8
|
+
attr_accessor :message
|
9
|
+
|
10
|
+
def setup_views
|
11
|
+
register_view :my_view
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup_models
|
15
|
+
register_model :my_model
|
16
|
+
register_model :my_model, :my_other_model_instance
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup_controllers
|
20
|
+
register_controller :my_child_controller
|
21
|
+
end
|
22
|
+
|
23
|
+
def property_my_other_model_instance_my_property_changed(model, new_value, old_value)
|
24
|
+
@message = "Property my_property of named observable my_other_model_instance changed from #{old_value} to #{new_value}."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class MyChildController < RuGUI::BaseController
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module InitializeHooksHelper
|
2
|
+
def before_initialize_called?
|
3
|
+
@before_initialize_called == true
|
4
|
+
end
|
5
|
+
|
6
|
+
def after_initialize_called?
|
7
|
+
@after_initialize_called == true
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
def before_initialize
|
12
|
+
@before_initialize_called = true
|
13
|
+
end
|
14
|
+
|
15
|
+
def after_initialize
|
16
|
+
@after_initialize_called = true
|
17
|
+
end
|
18
|
+
end
|