rugui 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +165 -0
- data/README +67 -0
- data/README.rdoc +67 -0
- data/Rakefile +56 -0
- data/VERSION.yml +4 -0
- data/bin/rugui +16 -0
- data/lib/rugui/base_controller.rb +194 -0
- data/lib/rugui/base_model.rb +22 -0
- data/lib/rugui/base_object.rb +73 -0
- data/lib/rugui/base_view.rb +302 -0
- data/lib/rugui/base_view_helper.rb +23 -0
- data/lib/rugui/configuration.rb +136 -0
- data/lib/rugui/framework_adapters/GTK.rb +233 -0
- data/lib/rugui/framework_adapters/Qt4.rb +171 -0
- data/lib/rugui/framework_adapters/base_framework_adapter.rb +90 -0
- data/lib/rugui/framework_adapters/framework_adapter_support.rb +35 -0
- data/lib/rugui/gem_builder.rb +21 -0
- data/lib/rugui/gem_dependency.rb +282 -0
- data/lib/rugui/initialize_hooks.rb +36 -0
- data/lib/rugui/initializer.rb +162 -0
- data/lib/rugui/log_support.rb +118 -0
- data/lib/rugui/observable_property_proxy.rb +73 -0
- data/lib/rugui/observable_property_support.rb +251 -0
- data/lib/rugui/plugin/loader.rb +77 -0
- data/lib/rugui/property_observer.rb +58 -0
- data/lib/rugui/signal_support.rb +57 -0
- data/lib/rugui/tasks/gems_application.rake +71 -0
- data/lib/rugui/tasks/rugui.rb +8 -0
- data/lib/rugui/tasks/rugui_framework.rb +4 -0
- data/lib/rugui/tasks/runner_application.rake +4 -0
- data/lib/rugui/tasks/spec_application.rake +64 -0
- data/lib/rugui/tasks/spec_framework.rake +27 -0
- data/lib/rugui/tasks/test_application.rake +77 -0
- data/lib/rugui/vendor_gem_source_index.rb +140 -0
- data/lib/rugui/version.rb +9 -0
- data/lib/rugui.rb +37 -0
- data/spec/framework/base_controller_spec.rb +48 -0
- data/spec/framework/base_model_spec.rb +13 -0
- data/spec/framework/base_view_helper_spec.rb +13 -0
- data/spec/framework/base_view_spec.rb +92 -0
- data/spec/framework/log_support_spec.rb +16 -0
- data/spec/framework/observable_property_proxy_spec.rb +67 -0
- data/spec/framework/observable_property_support_spec.rb +283 -0
- data/spec/framework/property_observer_spec.rb +88 -0
- data/spec/helpers/controllers.rb +29 -0
- data/spec/helpers/initialize_hooks_helper.rb +18 -0
- data/spec/helpers/models.rb +9 -0
- data/spec/helpers/observables.rb +210 -0
- data/spec/helpers/view_helpers.rb +9 -0
- data/spec/helpers/views.rb +72 -0
- data/spec/rcov.opts +1 -0
- data/spec/resource_files/my_other_view.glade +46 -0
- data/spec/resource_files/my_view.glade +46 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +15 -0
- metadata +149 -0
@@ -0,0 +1,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
|