intelitiva-rugui 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog +54 -0
- data/LICENSE +165 -0
- data/README +67 -0
- data/Rakefile +11 -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/rugui_generators/controller/USAGE +1 -0
- data/rugui_generators/controller/controller_generator.rb +35 -0
- data/rugui_generators/controller/templates/controller.erb +3 -0
- data/rugui_generators/generators_support.rb +75 -0
- data/rugui_generators/model/USAGE +1 -0
- data/rugui_generators/model/model_generator.rb +35 -0
- data/rugui_generators/model/templates/model.erb +3 -0
- data/rugui_generators/pack/USAGE +1 -0
- data/rugui_generators/pack/pack_generator.rb +40 -0
- data/rugui_generators/pack/templates/README +3 -0
- data/rugui_generators/rugui/USAGE +1 -0
- data/rugui_generators/rugui/rugui_generator.rb +163 -0
- data/rugui_generators/rugui/templates/GTK/application_controller.rb +4 -0
- data/rugui_generators/rugui/templates/GTK/application_view.rb +4 -0
- data/rugui_generators/rugui/templates/GTK/application_view_helper.rb +4 -0
- data/rugui_generators/rugui/templates/GTK/environment.rb +39 -0
- data/rugui_generators/rugui/templates/GTK/main.rc +23 -0
- data/rugui_generators/rugui/templates/GTK/main_controller.rb +17 -0
- data/rugui_generators/rugui/templates/GTK/main_view.glade +33 -0
- data/rugui_generators/rugui/templates/GTK/main_view.rb +10 -0
- data/rugui_generators/rugui/templates/GTK/main_view_helper.rb +3 -0
- data/rugui_generators/rugui/templates/Qt4/application_controller.rb +4 -0
- data/rugui_generators/rugui/templates/Qt4/application_view.rb +4 -0
- data/rugui_generators/rugui/templates/Qt4/application_view_helper.rb +4 -0
- data/rugui_generators/rugui/templates/Qt4/environment.rb +39 -0
- data/rugui_generators/rugui/templates/Qt4/main_controller.rb +13 -0
- data/rugui_generators/rugui/templates/Qt4/main_view.rb +10 -0
- data/rugui_generators/rugui/templates/Qt4/main_view.ui +37 -0
- data/rugui_generators/rugui/templates/Qt4/main_view_helper.rb +3 -0
- data/rugui_generators/rugui/templates/README +3 -0
- data/rugui_generators/rugui/templates/Rakefile +7 -0
- data/rugui_generators/rugui/templates/boot.rb +81 -0
- data/rugui_generators/rugui/templates/development.rb.sample +21 -0
- data/rugui_generators/rugui/templates/main.rb +11 -0
- data/rugui_generators/rugui/templates/main_executable.bat.erb +8 -0
- data/rugui_generators/rugui/templates/main_executable.erb +17 -0
- data/rugui_generators/rugui/templates/production.rb.sample +21 -0
- data/rugui_generators/rugui/templates/rcov.opts +1 -0
- data/rugui_generators/rugui/templates/spec.opts +4 -0
- data/rugui_generators/rugui/templates/spec_helper.rb +12 -0
- data/rugui_generators/rugui/templates/test.rb.sample +21 -0
- data/rugui_generators/rugui/templates/test_helper.rb +12 -0
- data/rugui_generators/view/USAGE +1 -0
- data/rugui_generators/view/templates/toplevels/about_dialog.glade +32 -0
- data/rugui_generators/view/templates/toplevels/assistant.glade +30 -0
- data/rugui_generators/view/templates/toplevels/color_selection_dialog.glade +60 -0
- data/rugui_generators/view/templates/toplevels/dialog_box.glade +35 -0
- data/rugui_generators/view/templates/toplevels/file_chooser_dialog.glade +35 -0
- data/rugui_generators/view/templates/toplevels/font_selection_dialog.glade +58 -0
- data/rugui_generators/view/templates/toplevels/input_dialog.glade +35 -0
- data/rugui_generators/view/templates/toplevels/message_dialog.glade +35 -0
- data/rugui_generators/view/templates/toplevels/recent_chooser_dialog.glade +33 -0
- data/rugui_generators/view/templates/toplevels/window.glade +11 -0
- data/rugui_generators/view/templates/view.erb +11 -0
- data/rugui_generators/view/templates/view.glade +4 -0
- data/rugui_generators/view/templates/view.ui +18 -0
- data/rugui_generators/view/templates/view_helper.erb +3 -0
- data/rugui_generators/view/view_generator.rb +36 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -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 +211 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../generators_support")
|
2
|
+
|
3
|
+
class ViewGenerator < RubiGen::Base
|
4
|
+
include GeneratorsSupport
|
5
|
+
|
6
|
+
default_options :author => nil
|
7
|
+
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(runtime_args, runtime_options = {})
|
11
|
+
@uses_builder = true
|
12
|
+
super
|
13
|
+
usage if args.empty?
|
14
|
+
@name = args.shift
|
15
|
+
extract_options
|
16
|
+
end
|
17
|
+
|
18
|
+
def manifest
|
19
|
+
record do |m|
|
20
|
+
build_view_templates(m)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
def banner
|
26
|
+
<<-EOS
|
27
|
+
Creates a RuGUI view with its resources.
|
28
|
+
|
29
|
+
USAGE: script/generate view YOUR_VIEW_NAME [options]
|
30
|
+
EOS
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_options!(opts)
|
34
|
+
view_add_options!(opts)
|
35
|
+
end
|
36
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/rugui-newgem.rb'}"
|
9
|
+
puts "Loading rugui-newgem gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'controllers')
|
4
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'views')
|
5
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'models')
|
6
|
+
|
7
|
+
describe RuGUI::BaseController do
|
8
|
+
before(:each) do
|
9
|
+
@controller = MyController.new
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "with view registering" do
|
13
|
+
it "should make the view available in a views hash and in an attribute" do
|
14
|
+
@controller.views[:my_view].should be_an_instance_of(MyView)
|
15
|
+
@controller.my_view.should be_an_instance_of(MyView)
|
16
|
+
@controller.views[:my_view].should == @controller.my_view
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "with model registering" do
|
21
|
+
it "should make the model available in a models hash and in an attribute" do
|
22
|
+
@controller.models[:my_model].should be_an_instance_of(MyModel)
|
23
|
+
@controller.my_model.should be_an_instance_of(MyModel)
|
24
|
+
@controller.models[:my_model].should == @controller.my_model
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be notified using named observable property change calls" do
|
28
|
+
@controller.my_other_model_instance.my_property = 1
|
29
|
+
@controller.message.should == "Property my_property of named observable my_other_model_instance changed from to 1."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "with controller registering" do
|
34
|
+
it "should make the controller available in a controllers hash and in an attribute" do
|
35
|
+
@controller.controllers[:my_child_controller].should be_an_instance_of(MyChildController)
|
36
|
+
@controller.my_child_controller.should be_an_instance_of(MyChildController)
|
37
|
+
@controller.controllers[:my_child_controller].should == @controller.my_child_controller
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "with initialization hooks" do
|
42
|
+
it "should call before initialize and after initialize methods" do
|
43
|
+
controller = MyController.new
|
44
|
+
controller.before_initialize_called?.should be_true
|
45
|
+
controller.after_initialize_called?.should be_true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'models')
|
4
|
+
|
5
|
+
describe RuGUI::BaseModel do
|
6
|
+
describe "with initialization hooks" do
|
7
|
+
it "should call before initialize and after initialize methods" do
|
8
|
+
model = MyModel.new
|
9
|
+
model.before_initialize_called?.should be_true
|
10
|
+
model.after_initialize_called?.should be_true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'spec_helper')
|
2
|
+
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'helpers', 'view_helpers')
|
4
|
+
|
5
|
+
describe RuGUI::BaseViewHelper do
|
6
|
+
describe "with initialization hooks" do
|
7
|
+
it "should call before initialize and after initialize methods" do
|
8
|
+
view_helper = MyViewHelper.new
|
9
|
+
view_helper.before_initialize_called?.should be_true
|
10
|
+
view_helper.after_initialize_called?.should be_true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -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
|