cucumba 0.0.5

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.
Files changed (80) hide show
  1. data/History.md +33 -0
  2. data/Manifest.txt +79 -0
  3. data/PostInstall.txt +7 -0
  4. data/README.rdoc +59 -0
  5. data/Rakefile +33 -0
  6. data/config/website.yml.sample +2 -0
  7. data/cucumba.gemspec +52 -0
  8. data/generators/cucumba/USAGE +9 -0
  9. data/generators/cucumba/cucumba_generator.rb +23 -0
  10. data/generators/cucumba/templates/config.yml +15 -0
  11. data/generators/cucumba/templates/cucumba +18 -0
  12. data/lib/cucumba.rb +49 -0
  13. data/lib/cucumba/drb.rb +52 -0
  14. data/lib/cucumba/rails.rb +60 -0
  15. data/lib/cucumba/rails/model.rb +26 -0
  16. data/lib/cucumba/rails/runner.rb +73 -0
  17. data/lib/cucumba/server.rb +14 -0
  18. data/script/console +10 -0
  19. data/script/destroy +14 -0
  20. data/script/generate +14 -0
  21. data/script/txt2html +71 -0
  22. data/spec/cucumba_configuration_spec.rb +97 -0
  23. data/spec/cucumba_spec_rails.rb +59 -0
  24. data/spec/spec.opts +1 -0
  25. data/spec/spec_helper.rb +23 -0
  26. data/spec/support/sample_app/README +1 -0
  27. data/spec/support/sample_app/Rakefile +10 -0
  28. data/spec/support/sample_app/app/controllers/application_controller.rb +4 -0
  29. data/spec/support/sample_app/app/controllers/users_controller.rb +83 -0
  30. data/spec/support/sample_app/app/helpers/application_helper.rb +2 -0
  31. data/spec/support/sample_app/app/helpers/users_helper.rb +2 -0
  32. data/spec/support/sample_app/app/models/user.rb +9 -0
  33. data/spec/support/sample_app/app/views/layouts/users.html.erb +17 -0
  34. data/spec/support/sample_app/app/views/users/edit.html.erb +20 -0
  35. data/spec/support/sample_app/app/views/users/index.html.erb +22 -0
  36. data/spec/support/sample_app/app/views/users/new.html.erb +19 -0
  37. data/spec/support/sample_app/app/views/users/show.html.erb +13 -0
  38. data/spec/support/sample_app/config/boot.rb +110 -0
  39. data/spec/support/sample_app/config/database.yml +22 -0
  40. data/spec/support/sample_app/config/environment.rb +12 -0
  41. data/spec/support/sample_app/config/environments/development.rb +17 -0
  42. data/spec/support/sample_app/config/environments/production.rb +28 -0
  43. data/spec/support/sample_app/config/environments/test.rb +29 -0
  44. data/spec/support/sample_app/config/initializers/cookie_verification_secret.rb +7 -0
  45. data/spec/support/sample_app/config/initializers/new_rails_defaults.rb +21 -0
  46. data/spec/support/sample_app/config/initializers/session_store.rb +15 -0
  47. data/spec/support/sample_app/config/routes.rb +6 -0
  48. data/spec/support/sample_app/db/schema.rb +21 -0
  49. data/spec/support/sample_app/public/404.html +30 -0
  50. data/spec/support/sample_app/public/422.html +30 -0
  51. data/spec/support/sample_app/public/500.html +30 -0
  52. data/spec/support/sample_app/public/favicon.ico +0 -0
  53. data/spec/support/sample_app/public/images/rails.png +0 -0
  54. data/spec/support/sample_app/public/index.html +275 -0
  55. data/spec/support/sample_app/public/javascripts/application.js +2 -0
  56. data/spec/support/sample_app/public/javascripts/controls.js +963 -0
  57. data/spec/support/sample_app/public/javascripts/dragdrop.js +973 -0
  58. data/spec/support/sample_app/public/javascripts/effects.js +1128 -0
  59. data/spec/support/sample_app/public/javascripts/prototype.js +4320 -0
  60. data/spec/support/sample_app/public/robots.txt +5 -0
  61. data/spec/support/sample_app/public/stylesheets/scaffold.css +54 -0
  62. data/spec/support/sample_app/script/about +4 -0
  63. data/spec/support/sample_app/script/console +3 -0
  64. data/spec/support/sample_app/script/dbconsole +3 -0
  65. data/spec/support/sample_app/script/destroy +3 -0
  66. data/spec/support/sample_app/script/generate +3 -0
  67. data/spec/support/sample_app/script/performance/benchmarker +3 -0
  68. data/spec/support/sample_app/script/performance/profiler +3 -0
  69. data/spec/support/sample_app/script/plugin +3 -0
  70. data/spec/support/sample_app/script/runner +3 -0
  71. data/spec/support/sample_app/script/server +3 -0
  72. data/spec/support/sample_app_run.sh +11 -0
  73. data/tasks/rspec.rake +26 -0
  74. data/tasks/yard.rake +14 -0
  75. data/website/index.html +11 -0
  76. data/website/index.txt +81 -0
  77. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  78. data/website/stylesheets/screen.css +159 -0
  79. data/website/template.html.erb +50 -0
  80. metadata +248 -0
@@ -0,0 +1,60 @@
1
+ require 'drb'
2
+ require 'cucumba/rails/model'
3
+
4
+ module Cucumba
5
+ # Cucumba rails client
6
+ class Rails
7
+
8
+ class ServerNotFound < Exception
9
+ end
10
+
11
+ attr_reader :host, :port, :drb_port, :description, :environment
12
+
13
+ def initialize(config)
14
+ @host = config[:host]
15
+ @port = config[:port] || 80
16
+ @drb_port = @port+1000
17
+ @run = config[:run]
18
+ @description = config[:desc]
19
+ @environment = config[:env]
20
+ if config[:path]
21
+ @path = File.join(config[:path])
22
+ else
23
+ @path = File.join('.')
24
+ end
25
+ @path = File.expand_path(@path)
26
+ @pid_file = File.join(@path,'tmp/pids/server.pid')
27
+ @server = DRbObject.new(nil, drb_url)
28
+ end
29
+
30
+ # url where rails application lives
31
+ def url
32
+ 'http://'+@host+':'+@port.to_s
33
+ end
34
+
35
+ def drb_url
36
+ 'druby://'+@host+':'+@drb_port.to_s
37
+ end
38
+
39
+ def rails_root
40
+ @path
41
+ end
42
+
43
+ def run?
44
+ @run
45
+ end
46
+
47
+ def model(model_name)
48
+ Model.new(model_name,@server)
49
+ end
50
+ alias :m :model
51
+
52
+ def execute(code)
53
+ @server.execute(code)
54
+ end
55
+ alias :e :execute
56
+
57
+ end
58
+ end
59
+
60
+ DRb.start_service
@@ -0,0 +1,26 @@
1
+ module Cucumba
2
+ class Rails
3
+ class Model
4
+
5
+ class NotFoundError < Exception
6
+ end
7
+
8
+ def initialize(model_name,server)
9
+ @server = server
10
+ if @server.has_model?(model_name)
11
+ @model = model_name
12
+ else
13
+ raise NotFoundError
14
+ end
15
+ end
16
+
17
+ def method_missing(method,*args)
18
+ if @server.model_has_method?(@model,method)
19
+ @server.invoke_method_on_model(@model,method,args)
20
+ else
21
+ super
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,73 @@
1
+ require 'cucumba'
2
+ require 'net/http'
3
+
4
+ module Cucumba
5
+
6
+ class Rails
7
+
8
+ def rails_start!
9
+ if run?
10
+ puts "=> #{self.description} booting..."
11
+ boot!
12
+ wait_untill_alive!
13
+ end
14
+ end
15
+
16
+ def rails_stop!
17
+ pid = File.read(@pid_file).to_i
18
+ puts "=> Killing alive server #{self.description}(pid:#{pid})"
19
+ Process.kill('INT',pid)
20
+ rescue Errno::ESRCH, Errno::ENOENT
21
+ puts "=> Server #{self.description} is not running"
22
+ end
23
+
24
+ private
25
+
26
+ def boot!
27
+ cmd = "ruby #{File.join(@path,'script','server')}"
28
+ cmd+= " --port=#{@port}"
29
+ cmd+= " --daemon"
30
+ cmd+= " --environment=#{@environment}"
31
+ puts `#{cmd}`
32
+ end
33
+
34
+ def wait_untill_alive!
35
+ check_start_time = Time.now
36
+ loop do
37
+ raise TimeoutError, "server #{self.description} start timeout" if (200-(Time.now.to_i - check_start_time.to_i)) <= 0
38
+ if alive?
39
+ puts "=> #{self.description} alive!"
40
+ break
41
+ else
42
+ sleep 0.2
43
+ end
44
+ end
45
+ end
46
+
47
+ def alive?
48
+ Net::HTTP.start(@host, @port) { |http| http.get('/rails/info/properties') }
49
+ rescue Errno::ECONNREFUSED, Errno::EBADF
50
+ return false
51
+ end
52
+
53
+ end
54
+
55
+ class <<self
56
+
57
+ # run all cucumba servers that should be run(:run => true)
58
+ def servers_start!
59
+ config.each do |server_config|
60
+ Cucumba[server_config[:name]].rails_stop!
61
+ Cucumba[server_config[:name]].rails_start!
62
+ end
63
+ end
64
+ alias :start_servers! :servers_start!
65
+
66
+ def servers_stop!
67
+ config.each { |server_config| Cucumba[server_config[:name]].rails_stop! }
68
+ end
69
+ alias :stop_servers! :servers_stop!
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,14 @@
1
+ lib = File.expand_path(File.join(File.dirname(__FILE__),'..'))
2
+ $:.unshift(lib) unless $:.include?(lib)
3
+
4
+ require 'cucumba/rails/runner'
5
+
6
+ Cucumba.servers_start!
7
+ trap(:INT) do
8
+ puts
9
+ Cucumba.servers_stop!
10
+ exit 0
11
+ end
12
+
13
+ puts "=> press Ctrl-C to exit and kill servers"
14
+ sleep
@@ -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/cucumba.rb'}"
9
+ puts "Loading cucumba gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -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)
@@ -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,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ load File.dirname(__FILE__) + "/../Rakefile"
4
+ require 'rubyforge'
5
+ require 'redcloth'
6
+ require 'syntax/convertors/html'
7
+ require 'erb'
8
+
9
+ download = "http://rubyforge.org/projects/#{$hoe.rubyforge_name}"
10
+ version = $hoe.version
11
+
12
+ def rubyforge_project_id
13
+ RubyForge.new.configure.autoconfig["group_ids"][$hoe.rubyforge_name]
14
+ end
15
+
16
+ class Fixnum
17
+ def ordinal
18
+ # teens
19
+ return 'th' if (10..19).include?(self % 100)
20
+ # others
21
+ case self % 10
22
+ when 1: return 'st'
23
+ when 2: return 'nd'
24
+ when 3: return 'rd'
25
+ else return 'th'
26
+ end
27
+ end
28
+ end
29
+
30
+ class Time
31
+ def pretty
32
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
33
+ end
34
+ end
35
+
36
+ def convert_syntax(syntax, source)
37
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
38
+ end
39
+
40
+ if ARGV.length >= 1
41
+ src, template = ARGV
42
+ template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
43
+ else
44
+ puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
45
+ exit!
46
+ end
47
+
48
+ template = ERB.new(File.open(template).read)
49
+
50
+ title = nil
51
+ body = nil
52
+ File.open(src) do |fsrc|
53
+ title_text = fsrc.readline
54
+ body_text_template = fsrc.read
55
+ body_text = ERB.new(body_text_template).result(binding)
56
+ syntax_items = []
57
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
58
+ ident = syntax_items.length
59
+ element, syntax, source = $1, $2, $3
60
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
61
+ "syntax-temp-#{ident}"
62
+ }
63
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
64
+ body = RedCloth.new(body_text).to_html
65
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
66
+ end
67
+ stat = File.stat(src)
68
+ created = stat.ctime
69
+ modified = stat.mtime
70
+
71
+ $stdout << template.result(binding)
@@ -0,0 +1,97 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Cucumba configuration" do
4
+ def load_fake_rails_module
5
+ Object.const_set "Rails", Module.new
6
+ end
7
+
8
+ def remove_fake_rails_module
9
+ Object.send :remove_const, :Rails
10
+ end
11
+
12
+ def force_cucumba_reload_config
13
+ Cucumba.send :class_variable_set, :@@config, nil
14
+ end
15
+
16
+ before :all do
17
+ load_fake_rails_module
18
+ end
19
+
20
+ before :each do
21
+ force_cucumba_reload_config
22
+ @good_config = [{
23
+ :name => 'name',
24
+ :host => 'some.host',
25
+ :port => 4321,
26
+ :desc => 'description',
27
+ :env => 'test',
28
+ :run => true
29
+ #TODO :ssl => false
30
+ }]
31
+ end
32
+
33
+ context "good configuration" do
34
+ it "one server" do
35
+ YAML.should_receive(:load_file).once.and_return(@good_config)
36
+ Rails.should_receive(:root).and_return('/path/to/rails/app')
37
+
38
+ [:name, "name"].each do |server|
39
+ client = Cucumba[server]
40
+
41
+ client.should be_instance_of(Cucumba::Rails)
42
+ client.host.should == 'some.host'
43
+ client.port.should == 4321
44
+ client.rails_root == '/path/to/rails/app'
45
+ client.drb_port.should == 5321
46
+ client.url.should == 'http://some.host:4321'
47
+ client.drb_url.should == 'druby://some.host:5321'
48
+ client.description.should == 'description'
49
+ client.environment.should == 'test'
50
+ client.run?.should be_true
51
+ end
52
+ end
53
+
54
+ it "should not be runned if run false" do
55
+ @good_config.first[:run]=false
56
+ YAML.should_receive(:load_file).once.and_return(@good_config)
57
+ Rails.should_receive(:root)
58
+ Cucumba[:name].run?.should be_false
59
+ end
60
+
61
+ it "should be runned if undefined rails" do
62
+ remove_fake_rails_module
63
+ YAML.should_receive(:load_file).once.and_return(@good_config)
64
+ Cucumba[:name].run?.should be_true
65
+ end
66
+ end
67
+
68
+ context "bad configuration" do
69
+
70
+ it "should raise exception if config not found" do
71
+ Rails.should_receive(:root)
72
+ YAML.should_receive(:load_file).once.and_raise(Errno::ENOENT)
73
+ lambda { Cucumba[:some] }.should raise_exception(Cucumba::ConfigNotFound)
74
+ end
75
+
76
+ it "should raise exception if server not found in config" do
77
+ Rails.should_receive(:root)
78
+ YAML.should_receive(:load_file).once.and_return(@good_config)
79
+ lambda { Cucumba[:wrong] }.should raise_exception(Cucumba::Rails::ServerNotFound)
80
+ end
81
+
82
+ end
83
+
84
+ after :all do
85
+ begin
86
+ remove_fake_rails_module
87
+ rescue NameError
88
+ end
89
+ end
90
+
91
+ end
92
+
93
+ describe 'Group without Rails' do
94
+ it "should not have Rails" do
95
+ defined?(Rails).should be_false
96
+ end
97
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ ENV["RAILS_ENV"] ||= 'test'
4
+ require File.expand_path(File.dirname(__FILE__) + '/support/sample_app/config/environment')
5
+
6
+ describe "Cucumba[:server]" do
7
+
8
+ it "should return instance of Cucumba::Rails" do
9
+ Cucumba[:test].should be_instance_of(Cucumba::Rails)
10
+ end
11
+
12
+ context "#model" do
13
+
14
+ it "should return instace of Cucumba::Rails::Model" do
15
+ [ Cucumba[:test].model("User"), Cucumba[:test].m("User"), Cucumba[:test].model(:User), Cucumba[:test].m(:User) ].each do |model|
16
+ model.should be_instance_of(Cucumba::Rails::Model)
17
+ end
18
+ end
19
+
20
+ it "should invoke existing methods" do
21
+ users_count_was = User.all.count
22
+ Cucumba[:test].m("User").create!(:name => 'test user', :password => 'secret')
23
+ (User.all.count - users_count_was).should == 1
24
+ User.last.name.should == 'test user'
25
+ User.last.password.should == 'secret'
26
+ end
27
+
28
+ it "should invoke method without arguments" do
29
+ Cucumba[:test].m(:User).columns
30
+ end
31
+
32
+ it "should eval code in server side" do
33
+ Cucumba[:test].execute("User.create!(:name => 'some name', :password => 'zecred')")
34
+ User.last.name.should == 'some name'
35
+ User.last.password == 'zecred'
36
+ end
37
+
38
+ it "should eval code and raise exception if exception appears on server side" do
39
+ lambda { Cucumba[:test].e("UnknownModel") }.should raise_exception(RuntimeError)
40
+ end
41
+
42
+ it "should invoke this method" do
43
+ Cucumba[:test].m(:User).method_with_args(:name, :first => 'bla', :last => 'alb')
44
+ end
45
+
46
+ it "should raise exception if model does not exists" do
47
+ lambda { Cucumba[:test].m("Unknown") }.should raise_exception(Cucumba::Rails::Model::NotFoundError)
48
+ end
49
+
50
+ it "should raise exception if model's method does not exists" do
51
+ lambda { Cucumba[:test].m(:User).blabla }.should raise_exception(NoMethodError)
52
+ end
53
+
54
+ it "should raise exception if exception appears on server" do
55
+ lambda { Cucumba[:test].m(:User).create!(:password => 'secret') }.should raise_exception(RuntimeError,"ActiveRecord::RecordInvalid Validation failed: Name can't be blank")
56
+ end
57
+
58
+ end
59
+ end