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,58 @@
1
+ module RuGUI
2
+ # Adds observer functionality for any class which has support for observable
3
+ # properties.
4
+ #
5
+ # The observer class should implement a method name
6
+ # 'property_property_name_changed', where 'property_name' is
7
+ # the name of the observable property, that will be called whenever that
8
+ # property value has changed. If it does not declare a method with this
9
+ # name, it will be silently ignored.
10
+ #
11
+ # The method signature is:
12
+ #
13
+ # property_foo_changed(model, new_value, old_value)
14
+ #
15
+ # for a property named 'foo'.
16
+ #
17
+ # If the observer class declares a method with this signature:
18
+ #
19
+ # property_my_class_foo_changed(model, new_value, old_value)
20
+ #
21
+ # it will be called whenever the property _foo_ of an observable of the
22
+ # class <code>MyClass</code> has changed.
23
+ #
24
+ # Also, if the observer class declares a method with this signature:
25
+ #
26
+ # property_my_named_observable_foo_changed(model, new_value, old_value)
27
+ #
28
+ # it will be called whenever the property _foo_ of the observable named
29
+ # _my_named_observable_ has changed. To declare named observers, you must
30
+ # register the observer passing a name to the
31
+ # ObservablePropertySupport#register_observer method.
32
+ #
33
+ module PropertyObserver
34
+ include RuGUI::FrameworkAdapters::FrameworkAdapterSupport
35
+
36
+ def property_updated(observable, property, new_value, old_value)
37
+ queue_method_call_if_exists("property_#{property}_changed", observable, new_value, old_value)
38
+ queue_method_call_if_exists("property_#{observable.class.name.underscore}_#{property}_changed", observable, new_value, old_value)
39
+ end
40
+
41
+ def named_observable_property_updated(observable_name, observable, property, new_value, old_value)
42
+ queue_method_call_if_exists("property_#{observable_name}_#{property}_changed", observable, new_value, old_value) unless named_observable_collides_with_class_name?(observable_name, observable)
43
+ end
44
+
45
+ private
46
+ def queue_method_call_if_exists(method_name, *args)
47
+ if respond_to?(method_name)
48
+ self.framework_adapter.queue do
49
+ send(method_name, *args)
50
+ end
51
+ end
52
+ end
53
+
54
+ def named_observable_collides_with_class_name?(observable_name, observable)
55
+ observable_name == observable.class.name.underscore
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,57 @@
1
+ module RuGUI
2
+ module SignalSupport
3
+ module ClassMethods
4
+ # Declares a signal handler for the given signal of the widget. The
5
+ # handler may be a method of this class or a block, which will be run with
6
+ # the instance of this class as context.
7
+ #
8
+ # If the signal has arguments they are passed to the receiver method or
9
+ # the block.
10
+ def on(widget_name, signal_name, receiver_method_name = nil, &block)
11
+ if receiver_method_name.nil? and not block_given?
12
+ logger.warn "Either a block or a receiver_method_name must be given to on(#{widget_name}, #{signal_name}), ignoring call."
13
+ return
14
+ end
15
+
16
+ signal_connection = RuGUI::SignalSupport::SignalConnection.new
17
+ signal_connection.widget_name = widget_name
18
+ signal_connection.signal_name = signal_name
19
+ signal_connection.receiver_method_name = receiver_method_name
20
+ signal_connection.receiver_block = block if block_given?
21
+ signal_connection.receiver_class = self
22
+
23
+ self.signal_connections << signal_connection
24
+ end
25
+ end
26
+
27
+ # Autoconnects declared signal handlers for the widgets in the sender to
28
+ # methods in this instance, or to blocks which have this instance as context.
29
+ def autoconnect_declared_signals(sender)
30
+ self.signal_connections.each do |signal_connection|
31
+ if sender.respond_to?(signal_connection.widget_name)
32
+ widget = sender.send(signal_connection.widget_name)
33
+
34
+ if (not signal_connection.receiver_block.nil?) and self.is_a?(signal_connection.receiver_class)
35
+ sender.framework_adapter.connect_declared_signal_block(widget, signal_connection.signal_name, self, signal_connection.receiver_block)
36
+ elsif not signal_connection.receiver_method_name.nil? and self.respond_to?(signal_connection.receiver_method_name)
37
+ sender.framework_adapter.connect_declared_signal(widget, signal_connection.signal_name, self, signal_connection.receiver_method_name)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ def self.included(base)
44
+ base.class_inheritable_accessor :signal_connections
45
+ base.signal_connections = []
46
+ base.extend(ClassMethods)
47
+ end
48
+
49
+ class SignalConnection
50
+ attr_accessor :widget_name
51
+ attr_accessor :signal_name
52
+ attr_accessor :receiver_method_name
53
+ attr_accessor :receiver_block
54
+ attr_accessor :receiver_class
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,71 @@
1
+ task :rake_environment do
2
+ $rails_rake_task = true
3
+ require(File.join(APPLICATION_ROOT, 'config', 'environment'))
4
+ RuGUI.configuration.logger[:level] = :error
5
+ end
6
+
7
+ desc "List the gems that this RuGUI application depends on"
8
+ task :gems => 'gems:base' do
9
+ RuGUI.configuration.gems.each do |gem|
10
+ print_gem_status(gem)
11
+ end
12
+ puts
13
+ puts "I = Installed"
14
+ puts "F = Frozen"
15
+ puts "R = Framework (loaded before RuGUI starts)"
16
+ end
17
+
18
+ namespace :gems do
19
+ task :base do
20
+ $gems_rake_task = true
21
+ require 'rubygems'
22
+ require 'rubygems/gem_runner'
23
+ Rake::Task[:rake_environment].invoke
24
+ end
25
+
26
+ desc "Build any native extensions for unpacked gems"
27
+ task :build do
28
+ $gems_build_rake_task = true
29
+ Rake::Task['gems:unpack'].invoke
30
+ current_gems.each &:build
31
+ end
32
+
33
+ desc "Installs all required gems."
34
+ task :install => :base do
35
+ current_gems.each &:install
36
+ end
37
+
38
+ desc "Unpacks all required gems into vendor/gems."
39
+ task :unpack => :install do
40
+ current_gems.each &:unpack
41
+ end
42
+
43
+ namespace :unpack do
44
+ desc "Unpacks all required gems and their dependencies into vendor/gems."
45
+ task :dependencies => :install do
46
+ current_gems.each { |gem| gem.unpack(:recursive => true) }
47
+ end
48
+ end
49
+
50
+ desc "Regenerate gem specifications in correct format."
51
+ task :refresh_specs => :base do
52
+ current_gems.each &:refresh
53
+ end
54
+ end
55
+
56
+ def current_gems
57
+ gems = RuGUI.configuration.gems
58
+ gems = gems.select { |gem| gem.name == ENV['GEM'] } unless ENV['GEM'].blank?
59
+ gems
60
+ end
61
+
62
+ def print_gem_status(gem, indent=1)
63
+ code = case
64
+ when gem.framework_gem? then 'R'
65
+ when gem.frozen? then 'F'
66
+ when gem.installed? then 'I'
67
+ else ' '
68
+ end
69
+ puts " "*(indent-1)+" - [#{code}] #{gem.name} #{gem.requirement.to_s}"
70
+ gem.dependencies.each { |g| print_gem_status(g, indent+1) }
71
+ end
@@ -0,0 +1,8 @@
1
+ $VERBOSE = nil
2
+
3
+ # Load RuGUI rakefile extensions
4
+ Dir["#{File.dirname(__FILE__)}/*_application.rake"].each { |ext| load ext }
5
+
6
+ # Load any custom rakefile extensions
7
+ Dir["#{APPLICATION_ROOT}/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
8
+ Dir["#{APPLICATION_ROOT}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext }
@@ -0,0 +1,4 @@
1
+ $VERBOSE = nil
2
+
3
+ # Load RuGUI framework rakefile extensions
4
+ Dir["#{File.dirname(__FILE__)}/*_framework.rake"].each { |ext| load ext }
@@ -0,0 +1,4 @@
1
+ desc 'Runs the application.'
2
+ task :run do
3
+ require 'main'
4
+ end
@@ -0,0 +1,64 @@
1
+ require 'rubygems'
2
+ require 'spec/rake/spectask'
3
+
4
+ task :stats => "spec:statsetup"
5
+
6
+ desc "Run all specs in spec directory (excluding plugin specs)"
7
+ Spec::Rake::SpecTask.new(:spec) do |t|
8
+ t.spec_opts = ['--options', "\"#{APPLICATION_ROOT}/spec/spec.opts\""]
9
+ t.spec_files = FileList['spec/**/*_spec.rb']
10
+ end
11
+
12
+ namespace :spec do
13
+ desc "Run all specs in spec directory with RCov (excluding plugin specs)"
14
+ Spec::Rake::SpecTask.new(:rcov) do |t|
15
+ t.spec_opts = ['--options', "\"#{APPLICATION_ROOT}/spec/spec.opts\""]
16
+ t.spec_files = FileList['spec/**/*_spec.rb']
17
+ t.rcov = true
18
+ t.rcov_opts = lambda do
19
+ IO.readlines("#{APPLICATION_ROOT}/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
20
+ end
21
+ end
22
+
23
+ desc "Print Specdoc for all specs (excluding plugin specs)"
24
+ Spec::Rake::SpecTask.new(:doc) do |t|
25
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
26
+ t.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ desc "Print Specdoc for all plugin specs"
30
+ Spec::Rake::SpecTask.new(:plugin_doc) do |t|
31
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
32
+ t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*')
33
+ end
34
+
35
+ [:models, :controllers, :views, :view_helpers, :lib].each do |sub|
36
+ desc "Run the specs under spec/#{sub}"
37
+ Spec::Rake::SpecTask.new(sub) do |t|
38
+ t.spec_opts = ['--options', "\"#{APPLICATION_ROOT}/spec/spec.opts\""]
39
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
40
+ end
41
+ end
42
+
43
+ desc "Run the specs under vendor/plugins (except RSpec's own)"
44
+ Spec::Rake::SpecTask.new(:plugins) do |t|
45
+ t.spec_opts = ['--options', "\"#{APPLICATION_ROOT}/spec/spec.opts\""]
46
+ t.spec_files = FileList['vendor/plugins/**/spec/**/*_spec.rb'].exclude('vendor/plugins/rspec/*')
47
+ end
48
+
49
+ # Setup specs for stats
50
+ task :statsetup do
51
+ require 'code_statistics'
52
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models) if File.exist?('spec/models')
53
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views) if File.exist?('spec/views')
54
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) if File.exist?('spec/controllers')
55
+ ::STATS_DIRECTORIES << %w(ViewHelper\ specs spec/helpers) if File.exist?('spec/view_helpers')
56
+ ::STATS_DIRECTORIES << %w(Library\ specs spec/lib) if File.exist?('spec/lib')
57
+ ::CodeStatistics::TEST_TYPES << "Model specs" if File.exist?('spec/models')
58
+ ::CodeStatistics::TEST_TYPES << "View specs" if File.exist?('spec/views')
59
+ ::CodeStatistics::TEST_TYPES << "Controller specs" if File.exist?('spec/controllers')
60
+ ::CodeStatistics::TEST_TYPES << "ViewHelper specs" if File.exist?('spec/view_helpers')
61
+ ::CodeStatistics::TEST_TYPES << "Library specs" if File.exist?('spec/lib')
62
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
63
+ end
64
+ end
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'spec/rake/spectask'
3
+
4
+ RUGUI_ROOT = File.join(File.expand_path(File.dirname(__FILE__)), '..', '..', '..')
5
+
6
+ task :stats => "spec:statsetup"
7
+
8
+ desc "Run all specs in spec directory"
9
+ Spec::Rake::SpecTask.new(:spec) do |t|
10
+ t.spec_opts = ['--options', "\"#{RUGUI_ROOT}/spec/spec.opts\""]
11
+ t.spec_files = FileList['spec/**/*_spec.rb']
12
+ end
13
+
14
+ namespace :spec do
15
+ desc "Print Specdoc for all specs"
16
+ Spec::Rake::SpecTask.new(:doc) do |t|
17
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
18
+ t.spec_files = FileList['spec/**/*_spec.rb']
19
+ end
20
+
21
+ # Setup specs for stats
22
+ task :statsetup do
23
+ require 'code_statistics'
24
+ ::STATS_DIRECTORIES << %w(RuGUI\ specs) if File.exist?('spec')
25
+ ::CodeStatistics::TEST_TYPES << "RuGUI specs" if File.exist?('spec')
26
+ end
27
+ end
@@ -0,0 +1,77 @@
1
+ TEST_CHANGES_SINCE = Time.now - 600
2
+
3
+ # Look up tests for recently modified sources.
4
+ def recent_tests(source_pattern, test_path, touched_since = 10.minutes.ago)
5
+ FileList[source_pattern].map do |path|
6
+ if File.mtime(path) > touched_since
7
+ tests = []
8
+ source_dir = File.dirname(path).split("/")
9
+ source_file = File.basename(path, '.rb')
10
+
11
+ # Support subdirs in app/models and app/controllers
12
+ modified_test_path = source_dir.length > 2 ? "#{test_path}/" << source_dir[1..source_dir.length].join('/') : test_path
13
+
14
+ # For modified files in app/ run the tests for it. ex. /test/models/account_controller.rb
15
+ test = "#{modified_test_path}/#{source_file}_test.rb"
16
+ tests.push test if File.exist?(test)
17
+
18
+ # For modified files in app, run tests in subdirs too. ex. /test/functional/account/*_test.rb
19
+ test = "#{modified_test_path}/#{File.basename(path, '.rb').sub("_controller","")}"
20
+ FileList["#{test}/*_test.rb"].each { |f| tests.push f } if File.exist?(test)
21
+
22
+ return tests
23
+
24
+ end
25
+ end.flatten.compact
26
+ end
27
+
28
+ desc 'Run all models, controllers and libs tests'
29
+ task :test do
30
+ errors = %w(test:models test:controllers test:libs).collect do |task|
31
+ begin
32
+ Rake::Task[task].invoke
33
+ nil
34
+ rescue => e
35
+ task
36
+ end
37
+ end.compact
38
+ abort "Errors running #{errors.to_sentence}!" if errors.any?
39
+ end
40
+
41
+ namespace :test do
42
+
43
+ Rake::TestTask.new(:recent) do |t|
44
+ since = TEST_CHANGES_SINCE
45
+ touched = FileList['test/**/*_test.rb'].select { |path| File.mtime(path) > since } +
46
+ recent_tests('app/models/**/*.rb', 'test/models', since) +
47
+ recent_tests('app/controllers/**/*.rb', 'test/controllers', since) +
48
+ recent_tests('lib/**/*.rb', 'test/libs', since)
49
+
50
+ t.libs << 'test'
51
+ t.verbose = true
52
+ t.test_files = touched.uniq
53
+ end
54
+ Rake::Task['test:recent'].comment = "Test recent changes"
55
+
56
+ Rake::TestTask.new(:models) do |t|
57
+ t.libs << "test"
58
+ t.pattern = 'test/models/**/*_test.rb'
59
+ t.verbose = true
60
+ end
61
+ Rake::Task['test:models'].comment = "Run the models tests in test/models"
62
+
63
+ Rake::TestTask.new(:controllers) do |t|
64
+ t.libs << "test"
65
+ t.pattern = 'test/controllers/**/*_test.rb'
66
+ t.verbose = true
67
+ end
68
+ Rake::Task['test:controllers'].comment = "Run the controllers tests in test/unit"
69
+
70
+ Rake::TestTask.new(:libs) do |t|
71
+ t.libs << "test"
72
+ t.pattern = 'test/lib/**/*_test.rb'
73
+ t.verbose = true
74
+ end
75
+ Rake::Task['test:libs'].comment = "Run the libs tests in test/unit"
76
+
77
+ end
@@ -0,0 +1,140 @@
1
+ require 'rubygems'
2
+ require 'yaml'
3
+
4
+ module RuGUI
5
+
6
+ class VendorGemSourceIndex
7
+ # VendorGemSourceIndex acts as a proxy for the Gem source index, allowing
8
+ # gems to be loaded from vendor/gems. Rather than the standard gem repository format,
9
+ # vendor/gems contains unpacked gems, with YAML specifications in .specification in
10
+ # each gem directory.
11
+ include Enumerable
12
+
13
+ attr_reader :installed_source_index
14
+ attr_reader :vendor_source_index
15
+
16
+ @@silence_spec_warnings = false
17
+
18
+ def self.silence_spec_warnings
19
+ @@silence_spec_warnings
20
+ end
21
+
22
+ def self.silence_spec_warnings=(v)
23
+ @@silence_spec_warnings = v
24
+ end
25
+
26
+ def initialize(installed_index, vendor_dir=RuGUI::GemDependency.unpacked_path)
27
+ @installed_source_index = installed_index
28
+ @vendor_dir = vendor_dir
29
+ refresh!
30
+ end
31
+
32
+ def refresh!
33
+ # reload the installed gems
34
+ @installed_source_index.refresh!
35
+ vendor_gems = {}
36
+
37
+ # handle vendor RuGUI gems - they are identified by having loaded_from set to ""
38
+ # we add them manually to the list, so that other gems can find them via dependencies
39
+ Gem.loaded_specs.each do |n, s|
40
+ next unless s.loaded_from.empty?
41
+ vendor_gems[s.full_name] = s
42
+ end
43
+
44
+ # load specifications from vendor/gems
45
+ Dir[File.join(RuGUI::GemDependency.unpacked_path, '*')].each do |d|
46
+ dir_name = File.basename(d)
47
+ dir_version = version_for_dir(dir_name)
48
+ spec = load_specification(d)
49
+ if spec
50
+ if spec.full_name != dir_name
51
+ # mismatched directory name and gem spec - produced by 2.1.0-era unpack code
52
+ if dir_version
53
+ # fix the spec version - this is not optimal (spec.files may be wrong)
54
+ # but it's better than breaking apps. Complain to remind users to get correct specs.
55
+ # use ActiveSupport::Deprecation.warn, as the logger is not set yet
56
+ $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems has a mismatched specification file."+
57
+ " Run 'rake gems:refresh_specs' to fix this.") unless @@silence_spec_warnings
58
+ spec.version = dir_version
59
+ else
60
+ $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems is not in a versioned directory"+
61
+ "(should be #{spec.full_name}).") unless @@silence_spec_warnings
62
+ # continue, assume everything is OK
63
+ end
64
+ end
65
+ else
66
+ # no spec - produced by early-2008 unpack code
67
+ # emulate old behavior, and complain.
68
+ $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems has no specification file."+
69
+ " Run 'rake gems:refresh_specs' to fix this.") unless @@silence_spec_warnings
70
+ if dir_version
71
+ spec = Gem::Specification.new
72
+ spec.version = dir_version
73
+ spec.require_paths = ['lib']
74
+ ext_path = File.join(d, 'ext')
75
+ spec.require_paths << 'ext' if File.exist?(ext_path)
76
+ spec.name = /^(.*)-[^-]+$/.match(dir_name)[1]
77
+ files = ['lib']
78
+ # set files to everything in lib/
79
+ files += Dir[File.join(d, 'lib', '*')].map { |v| v.gsub(/^#{d}\//, '') }
80
+ files += Dir[File.join(d, 'ext', '*')].map { |v| v.gsub(/^#{d}\//, '') } if ext_path
81
+ spec.files = files
82
+ else
83
+ $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems not in a versioned directory."+
84
+ " Giving up.") unless @@silence_spec_warnings
85
+ next
86
+ end
87
+ end
88
+ spec.loaded_from = File.join(d, '.specification')
89
+ # finally, swap out full_gem_path
90
+ # it would be better to use a Gem::Specification subclass, but the YAML loads an explicit class
91
+ class << spec
92
+ def full_gem_path
93
+ path = File.join installation_path, full_name
94
+ return path if File.directory? path
95
+ File.join installation_path, original_name
96
+ end
97
+ end
98
+ vendor_gems[File.basename(d)] = spec
99
+ end
100
+ @vendor_source_index = Gem::SourceIndex.new(vendor_gems)
101
+ end
102
+
103
+ def version_for_dir(d)
104
+ matches = /-([^-]+)$/.match(d)
105
+ Gem::Version.new(matches[1]) if matches
106
+ end
107
+
108
+ def load_specification(gem_dir)
109
+ spec_file = File.join(gem_dir, '.specification')
110
+ YAML.load_file(spec_file) if File.exist?(spec_file)
111
+ end
112
+
113
+ def find_name(*args)
114
+ @installed_source_index.find_name(*args) + @vendor_source_index.find_name(*args)
115
+ end
116
+
117
+ def search(*args)
118
+ # look for vendor gems, and then installed gems - later elements take priority
119
+ @installed_source_index.search(*args) + @vendor_source_index.search(*args)
120
+ end
121
+
122
+ def each(&block)
123
+ @vendor_source_index.each(&block)
124
+ @installed_source_index.each(&block)
125
+ end
126
+
127
+ def add_spec(spec)
128
+ @vendor_source_index.add_spec spec
129
+ end
130
+
131
+ def remove_spec(spec)
132
+ @vendor_source_index.remove_spec spec
133
+ end
134
+
135
+ def size
136
+ @vendor_source_index.size + @installed_source_index.size
137
+ end
138
+
139
+ end
140
+ end
@@ -0,0 +1,9 @@
1
+ module RuGUI
2
+ module VERSION #:nodoc:
3
+ MAJOR = 1
4
+ MINOR = 2
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
data/lib/rugui.rb ADDED
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'activesupport'
3
+
4
+ module RuGUI
5
+ class << self
6
+ # The Configuration instance used to configure the RuGUI environment
7
+ def configuration
8
+ @@configuration
9
+ end
10
+
11
+ def configuration=(configuration)
12
+ @@configuration = configuration
13
+ end
14
+
15
+ def root
16
+ if defined?(APPLICATION_ROOT)
17
+ Pathname.new(File.expand_path(APPLICATION_ROOT))
18
+ else
19
+ nil
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ require 'rugui/configuration'
26
+ require 'rugui/log_support'
27
+ require 'rugui/plugin/loader'
28
+ require 'rugui/framework_adapters/framework_adapter_support'
29
+ require 'rugui/base_object'
30
+ require 'rugui/observable_property_support'
31
+ require 'rugui/property_observer'
32
+ require 'rugui/initialize_hooks'
33
+ require 'rugui/signal_support'
34
+ require 'rugui/base_controller'
35
+ require 'rugui/base_model'
36
+ require 'rugui/base_view_helper'
37
+ require 'rugui/base_view'
@@ -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