rugui 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +165 -0
- data/README +67 -0
- data/README.rdoc +67 -0
- data/Rakefile +56 -0
- data/VERSION.yml +4 -0
- data/bin/rugui +16 -0
- data/lib/rugui/base_controller.rb +194 -0
- data/lib/rugui/base_model.rb +22 -0
- data/lib/rugui/base_object.rb +73 -0
- data/lib/rugui/base_view.rb +302 -0
- data/lib/rugui/base_view_helper.rb +23 -0
- data/lib/rugui/configuration.rb +136 -0
- data/lib/rugui/framework_adapters/GTK.rb +233 -0
- data/lib/rugui/framework_adapters/Qt4.rb +171 -0
- data/lib/rugui/framework_adapters/base_framework_adapter.rb +90 -0
- data/lib/rugui/framework_adapters/framework_adapter_support.rb +35 -0
- data/lib/rugui/gem_builder.rb +21 -0
- data/lib/rugui/gem_dependency.rb +282 -0
- data/lib/rugui/initialize_hooks.rb +36 -0
- data/lib/rugui/initializer.rb +162 -0
- data/lib/rugui/log_support.rb +118 -0
- data/lib/rugui/observable_property_proxy.rb +73 -0
- data/lib/rugui/observable_property_support.rb +251 -0
- data/lib/rugui/plugin/loader.rb +77 -0
- data/lib/rugui/property_observer.rb +58 -0
- data/lib/rugui/signal_support.rb +57 -0
- data/lib/rugui/tasks/gems_application.rake +71 -0
- data/lib/rugui/tasks/rugui.rb +8 -0
- data/lib/rugui/tasks/rugui_framework.rb +4 -0
- data/lib/rugui/tasks/runner_application.rake +4 -0
- data/lib/rugui/tasks/spec_application.rake +64 -0
- data/lib/rugui/tasks/spec_framework.rake +27 -0
- data/lib/rugui/tasks/test_application.rake +77 -0
- data/lib/rugui/vendor_gem_source_index.rb +140 -0
- data/lib/rugui/version.rb +9 -0
- data/lib/rugui.rb +37 -0
- data/spec/framework/base_controller_spec.rb +48 -0
- data/spec/framework/base_model_spec.rb +13 -0
- data/spec/framework/base_view_helper_spec.rb +13 -0
- data/spec/framework/base_view_spec.rb +92 -0
- data/spec/framework/log_support_spec.rb +16 -0
- data/spec/framework/observable_property_proxy_spec.rb +67 -0
- data/spec/framework/observable_property_support_spec.rb +283 -0
- data/spec/framework/property_observer_spec.rb +88 -0
- data/spec/helpers/controllers.rb +29 -0
- data/spec/helpers/initialize_hooks_helper.rb +18 -0
- data/spec/helpers/models.rb +9 -0
- data/spec/helpers/observables.rb +210 -0
- data/spec/helpers/view_helpers.rb +9 -0
- data/spec/helpers/views.rb +72 -0
- data/spec/rcov.opts +1 -0
- data/spec/resource_files/my_other_view.glade +46 -0
- data/spec/resource_files/my_view.glade +46 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +15 -0
- metadata +149 -0
@@ -0,0 +1,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,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
|
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
|