rugui 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/LICENSE +165 -0
  2. data/README +67 -0
  3. data/README.rdoc +67 -0
  4. data/Rakefile +56 -0
  5. data/VERSION.yml +4 -0
  6. data/bin/rugui +16 -0
  7. data/lib/rugui/base_controller.rb +194 -0
  8. data/lib/rugui/base_model.rb +22 -0
  9. data/lib/rugui/base_object.rb +73 -0
  10. data/lib/rugui/base_view.rb +302 -0
  11. data/lib/rugui/base_view_helper.rb +23 -0
  12. data/lib/rugui/configuration.rb +136 -0
  13. data/lib/rugui/framework_adapters/GTK.rb +233 -0
  14. data/lib/rugui/framework_adapters/Qt4.rb +171 -0
  15. data/lib/rugui/framework_adapters/base_framework_adapter.rb +90 -0
  16. data/lib/rugui/framework_adapters/framework_adapter_support.rb +35 -0
  17. data/lib/rugui/gem_builder.rb +21 -0
  18. data/lib/rugui/gem_dependency.rb +282 -0
  19. data/lib/rugui/initialize_hooks.rb +36 -0
  20. data/lib/rugui/initializer.rb +162 -0
  21. data/lib/rugui/log_support.rb +118 -0
  22. data/lib/rugui/observable_property_proxy.rb +73 -0
  23. data/lib/rugui/observable_property_support.rb +251 -0
  24. data/lib/rugui/plugin/loader.rb +77 -0
  25. data/lib/rugui/property_observer.rb +58 -0
  26. data/lib/rugui/signal_support.rb +57 -0
  27. data/lib/rugui/tasks/gems_application.rake +71 -0
  28. data/lib/rugui/tasks/rugui.rb +8 -0
  29. data/lib/rugui/tasks/rugui_framework.rb +4 -0
  30. data/lib/rugui/tasks/runner_application.rake +4 -0
  31. data/lib/rugui/tasks/spec_application.rake +64 -0
  32. data/lib/rugui/tasks/spec_framework.rake +27 -0
  33. data/lib/rugui/tasks/test_application.rake +77 -0
  34. data/lib/rugui/vendor_gem_source_index.rb +140 -0
  35. data/lib/rugui/version.rb +9 -0
  36. data/lib/rugui.rb +37 -0
  37. data/spec/framework/base_controller_spec.rb +48 -0
  38. data/spec/framework/base_model_spec.rb +13 -0
  39. data/spec/framework/base_view_helper_spec.rb +13 -0
  40. data/spec/framework/base_view_spec.rb +92 -0
  41. data/spec/framework/log_support_spec.rb +16 -0
  42. data/spec/framework/observable_property_proxy_spec.rb +67 -0
  43. data/spec/framework/observable_property_support_spec.rb +283 -0
  44. data/spec/framework/property_observer_spec.rb +88 -0
  45. data/spec/helpers/controllers.rb +29 -0
  46. data/spec/helpers/initialize_hooks_helper.rb +18 -0
  47. data/spec/helpers/models.rb +9 -0
  48. data/spec/helpers/observables.rb +210 -0
  49. data/spec/helpers/view_helpers.rb +9 -0
  50. data/spec/helpers/views.rb +72 -0
  51. data/spec/rcov.opts +1 -0
  52. data/spec/resource_files/my_other_view.glade +46 -0
  53. data/spec/resource_files/my_view.glade +46 -0
  54. data/spec/spec.opts +4 -0
  55. data/spec/spec_helper.rb +15 -0
  56. 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
@@ -0,0 +1,9 @@
1
+ # Defines some models used in specs.
2
+
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'initialize_hooks_helper')
4
+
5
+ class MyModel < RuGUI::BaseModel
6
+ include InitializeHooksHelper
7
+
8
+ observable_property :my_property
9
+ end