muding 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,20 @@
1
+ *** 0.2.0 / 2006-08-02
2
+
3
+ + 1 major enhancement
4
+ +Unit Testing
5
+
6
+ + 2 minor enhancements
7
+ + redirect_to
8
+ + abbreviations
9
+ + generators now work
10
+
11
+ + 1 change
12
+ + .rhtml is now .eruby, the standard ERB file suffix
13
+
14
+ + 2 bug fixes
15
+ +fixed some issues with Controller::Base
16
+ +removed redirect_to method due to it's non-functioning
17
+
1
18
  *** 0.1.1 / 2006-07-25
2
19
 
3
20
  + 2 bug fixes
data/MANIFEST CHANGED
@@ -11,6 +11,7 @@ bin/console
11
11
  bin/destroy
12
12
  configs/
13
13
  configs/boot.rb
14
+ configs/environment.rb
14
15
  configs/databases/
15
16
  configs/databases/mysql.yml
16
17
  configs/databases/oracle.yml
@@ -24,13 +25,21 @@ helpers/mud.rb
24
25
  helpers/mud_helper.rb
25
26
  helpers/test_helper.rb
26
27
  lib/
28
+ lib/initializer.rb
29
+ lib/code_statistics.rb
30
+ lib/version.rb
31
+ lib/test_help.rb
27
32
  lib/controller.rb
28
33
  lib/handle.rb
29
34
  lib/model.rb
30
35
  lib/muding.rb
31
36
  lib/muding_generator.rb
32
37
  lib/ruby_version_check.rb
33
- lib/tasks/migrate.rake
38
+ lib/tasks/muding.rb
39
+ lib/tasks/databases.rake
40
+ lib/tasks/documentation.rake
41
+ lib/tasks/statistics.rake
42
+ lib/tasks/testing.rake
34
43
  lib/acts/expireable.rb
35
44
  lib/acts/container.rb
36
45
  lib/commands/
data/README CHANGED
@@ -10,12 +10,3 @@ common to all multi-user environments into a separate framework that can
10
10
  be developed through open-source. Developers using the framework can then
11
11
  build their multi-user environment on top of the framework, and update the
12
12
  framework code independantly of their own code.
13
-
14
- ** SETUP:
15
- muding mudname
16
- - creates a new directory at your current path for the mud you are
17
- developing
18
-
19
- ** INSTALL:
20
-
21
- sudo gem install muding
@@ -1,4 +1,46 @@
1
- require 'rubygems'
2
- require_gem 'muding'
3
- MUDING_ROOT = File.dirname(__FILE__) + "/../"
1
+ # Don't change this file. Configuration is done in config/environment.rb and config/environments/*.rb
2
+
3
+ unless defined?(MUDING_ROOT)
4
+ root_path = File.join(File.dirname(__FILE__), '..')
5
+
6
+ unless RUBY_PLATFORM =~ /mswin32/
7
+ require 'pathname'
8
+ root_path = Pathname.new(root_path).cleanpath(true).to_s
9
+ end
10
+
11
+ MUDING_ROOT = root_path
12
+ end
13
+
14
+ unless defined?(Muding::Initializer)
15
+ if File.directory?("#{MUDING_ROOT}/vendor/rails")
16
+ require "#{MUDING_ROOT}/vendor/muding/railties/lib/initializer"
17
+ else
18
+ require 'rubygems'
19
+
20
+ environment_without_comments = IO.readlines(File.dirname(__FILE__) + '/environment.rb').reject { |l| l =~ /^#/ }.join
21
+ environment_without_comments =~ /[^#]MUDING_GEM_VERSION = '([\d.]+)'/
22
+ muding_gem_version = $1
23
+
24
+ if version = defined?(MUDING_GEM_VERSION) ? MUDING_GEM_VERSION : muding_gem_version
25
+ muding_gem = Gem.cache.search('muding', "=#{version}").first
26
+
27
+ if muding_gem
28
+ require_gem "muding", "=#{version}"
29
+ require muding_gem.full_gem_path + '/lib/initializer'
30
+ else
31
+ STDERR.puts %(Cannot find gem for muding =#{version}:
32
+ Install the missing gem with 'gem install -v=#{version} muding', or
33
+ change environment.rb to define MUDING_GEM_VERSION with your desired version.
34
+ )
35
+ exit 1
36
+ end
37
+ else
38
+ require_gem "muding"
39
+ require 'initializer'
40
+ end
41
+ end
42
+
43
+ Muding::Initializer.run(:set_load_path)
44
+ end
45
+
4
46
 
@@ -0,0 +1,49 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Use this if you want to move your muding server into production mode.
4
+ # ENV['MUDING_ENV'] ||= 'production'
5
+
6
+ # Specifies gem version of Rails to use when vendor/rails is not present
7
+ <%= '# ' if freeze %>MUDING_GEM_VERSION = '<%= Muding::VERSION::STRING %>'
8
+
9
+ # Bootstrap the Rails environment, frameworks, and default configuration
10
+ require File.join(File.dirname(__FILE__), 'boot')
11
+
12
+ Muding::Initializer.run do |config|
13
+ # Settings in config/environments/* take precedence those specified here
14
+
15
+ # Add additional load paths for your own custom dirs
16
+ # config.load_paths += %W( #{MUDING_ROOT}/extras )
17
+
18
+ # Force all environments to use the same logger level
19
+ # (by default production uses :info, the others :debug)
20
+ # config.log_level = :debug
21
+
22
+ # Use the database for sessions instead of the file system
23
+ # (create the session table with 'rake db:sessions:create')
24
+ # config.action_controller.session_store = :active_record_store
25
+
26
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
27
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
28
+ # like if you have constraints or database-specific column types
29
+ # config.active_record.schema_format = :sql
30
+
31
+ # Activate observers that should always be running
32
+ # config.active_record.observers = :cacher, :garbage_collector
33
+
34
+ # Make Active Record use UTC-base instead of local time
35
+ # config.active_record.default_timezone = :utc
36
+
37
+ # See Muding::Configuration for more options
38
+ end
39
+
40
+ # Add new inflection rules using the following format
41
+ # (all these examples are active by default):
42
+ # Inflector.inflections do |inflect|
43
+ # inflect.plural /^(ox)$/i, '\1en'
44
+ # inflect.singular /^(ox)en/i, '\1'
45
+ # inflect.irregular 'person', 'people'
46
+ # inflect.uncountable %w( fish sheep )
47
+ # end
48
+
49
+ # Include your application configuration below
@@ -1,4 +1,7 @@
1
+ require(File.join(File.dirname(__FILE__), 'config', 'boot'))
2
+
1
3
  require 'rake'
4
+ require 'rake/testtask'
5
+ require 'rake/rdoctask'
2
6
 
3
- #We get our tasks from lib/tasks
4
- Dir["./lib/tasks/**/*.rake"].sort.each { |ext| load ext }
7
+ require 'tasks/muding'
@@ -1,5 +1,5 @@
1
- ENV["RAILS_ENV"] = "test"
2
- require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
1
+ ENV["MUDING_ENV"] = "test"
2
+ #require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
3
3
  require 'test_help'
4
4
 
5
5
  class Test::Unit::TestCase
@@ -44,9 +44,10 @@ module Acts #:nodoc:
44
44
  end
45
45
 
46
46
  def <<(content)
47
+ content.container = nil
47
48
  self.containables.each do |containable|
48
- begin
49
- self.send(containable).<< content
49
+ begin
50
+ self.send(containable).<< content
50
51
  return # if it successfully adds we are done with this method.
51
52
 
52
53
  # there is probably a better way to do this. right now if it can't be added to the container
@@ -0,0 +1,107 @@
1
+ class CodeStatistics #:nodoc:
2
+
3
+ TEST_TYPES = %w(Units Functionals Unit\ tests Functional\ tests Integration\ tests)
4
+
5
+ def initialize(*pairs)
6
+ @pairs = pairs
7
+ @statistics = calculate_statistics
8
+ @total = calculate_total if pairs.length > 1
9
+ end
10
+
11
+ def to_s
12
+ print_header
13
+ @pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) }
14
+ print_splitter
15
+
16
+ if @total
17
+ print_line("Total", @total)
18
+ print_splitter
19
+ end
20
+
21
+ print_code_test_stats
22
+ end
23
+
24
+ private
25
+ def calculate_statistics
26
+ @pairs.inject({}) { |stats, pair| stats[pair.first] = calculate_directory_statistics(pair.last); stats }
27
+ end
28
+
29
+ def calculate_directory_statistics(directory, pattern = /.*\.rb$/)
30
+ stats = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 }
31
+
32
+ Dir.foreach(directory) do |file_name|
33
+ if File.stat(directory + "/" + file_name).directory? and (/^\./ !~ file_name)
34
+ newstats = calculate_directory_statistics(directory + "/" + file_name, pattern)
35
+ stats.each { |k, v| stats[k] += newstats[k] }
36
+ end
37
+
38
+ next unless file_name =~ pattern
39
+
40
+ f = File.open(directory + "/" + file_name)
41
+
42
+ while line = f.gets
43
+ stats["lines"] += 1
44
+ stats["classes"] += 1 if line =~ /class [A-Z]/
45
+ stats["methods"] += 1 if line =~ /def [a-z]/
46
+ stats["codelines"] += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/
47
+ end
48
+ end
49
+
50
+ stats
51
+ end
52
+
53
+ def calculate_total
54
+ total = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 }
55
+ @statistics.each_value { |pair| pair.each { |k, v| total[k] += v } }
56
+ total
57
+ end
58
+
59
+ def calculate_code
60
+ code_loc = 0
61
+ @statistics.each { |k, v| code_loc += v['codelines'] unless TEST_TYPES.include? k }
62
+ code_loc
63
+ end
64
+
65
+ def calculate_tests
66
+ test_loc = 0
67
+ @statistics.each { |k, v| test_loc += v['codelines'] if TEST_TYPES.include? k }
68
+ test_loc
69
+ end
70
+
71
+ def print_header
72
+ print_splitter
73
+ puts "| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |"
74
+ print_splitter
75
+ end
76
+
77
+ def print_splitter
78
+ puts "+----------------------+-------+-------+---------+---------+-----+-------+"
79
+ end
80
+
81
+ def print_line(name, statistics)
82
+ m_over_c = (statistics["methods"] / statistics["classes"]) rescue m_over_c = 0
83
+ loc_over_m = (statistics["codelines"] / statistics["methods"]) - 2 rescue loc_over_m = 0
84
+
85
+ start = if TEST_TYPES.include? name
86
+ "| #{name.ljust(18)} "
87
+ else
88
+ "| #{name.ljust(20)} "
89
+ end
90
+
91
+ puts start +
92
+ "| #{statistics["lines"].to_s.rjust(5)} " +
93
+ "| #{statistics["codelines"].to_s.rjust(5)} " +
94
+ "| #{statistics["classes"].to_s.rjust(7)} " +
95
+ "| #{statistics["methods"].to_s.rjust(7)} " +
96
+ "| #{m_over_c.to_s.rjust(3)} " +
97
+ "| #{loc_over_m.to_s.rjust(5)} |"
98
+ end
99
+
100
+ def print_code_test_stats
101
+ code = calculate_code
102
+ tests = calculate_tests
103
+
104
+ puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f/code)}"
105
+ puts ""
106
+ end
107
+ end
@@ -1,7 +1,9 @@
1
- require "#{MUDING_ROOT}/config/environment"
1
+ #require "#{MUDING_ROOT}/config/environment"
2
2
  require 'muding_generator'
3
3
  require 'muding_generator/scripts/destroy'
4
4
 
5
+
5
6
  ARGV.shift if ['--help', '-h'].include?(ARGV[0])
7
+
6
8
  Muding::Generator::Scripts::Destroy.new.run(ARGV)
7
9
 
@@ -1,4 +1,4 @@
1
- require "#{MUDING_ROOT}/config/environment"
1
+ #require "#{MUDING_ROOT}/config/environment"
2
2
  require 'muding_generator'
3
3
  require 'muding_generator/scripts/generate'
4
4
 
@@ -1,9 +1,31 @@
1
1
  %w[socket handle].each { |lib| require lib }
2
+ require "optparse"
3
+
4
+ # Specified for sake of cleanliness, as it is repeated.
5
+ DEFAULT_PORT = 4000
6
+
7
+ options = {
8
+ :port => DEFAULT_PORT
9
+ }
10
+
11
+ optparse = OptionParser.new do |opt|
12
+ opt.banner = "Usage: #{$0} [OPTIONS]"
13
+ opt.separator ""
14
+ opt.on "-p", "--port [PORT]", "Select the server port, defaults to #{DEFAULT_PORT}" do |port|
15
+ options[:port] = port
16
+ end
17
+ opt.on_tail "-h", "--help", "Display this help message" do
18
+ puts optparse
19
+ exit
20
+ end
21
+ end
22
+
23
+ optparse.parse! ARGV
2
24
 
3
25
  log = Log4r::Logger.new 'main'
4
26
  log.outputters = Log4r::Outputter.stdout
5
27
  begin
6
- server = TCPServer.new('localhost', 4000)
28
+ server = TCPServer.new('localhost', options[:port])
7
29
  threads = []
8
30
 
9
31
  #The procedures for shuting down the server
@@ -25,7 +47,7 @@ begin
25
47
  Signal.trap sig, handle_signalled_shutdown
26
48
  end
27
49
 
28
- log.info "Accepting Connections..."
50
+ log.info "Accepting Connections on port #{options[:port]}..."
29
51
  while session = server.accept
30
52
  threads << Thread.new(session) do |s|
31
53
  begin
@@ -1,4 +1,4 @@
1
- require "#{MUDING_ROOT}/config/environment"
1
+ #require "#{MUDING_ROOT}/config/environment"
2
2
  require 'muding_generator'
3
3
  require 'muding_generator/scripts/update'
4
4
  Muding::Generator::Scripts::Update.new.run(ARGV)
@@ -1,15 +1,17 @@
1
+ require 'abbrev'
2
+
1
3
  module Controller
2
4
  Log = Log4r::Logger.new 'controller'
3
5
  Log.outputters = Log4r::Outputter.stdout
4
6
 
5
7
  class NoCommandException < Exception;end
6
-
7
-
8
+ class NoViewException < Exception;end
8
9
 
9
10
  class Base
11
+
10
12
  alias :route :class
11
13
  attr_accessor :input, :body, :rendered
12
- attr_accessor :new_route, :default_command, :prompt
14
+ attr_accessor :new_route, :default_command, :prompt, :redirect, :args
13
15
 
14
16
  @@before_view = {}
15
17
 
@@ -41,10 +43,15 @@ module Controller
41
43
 
42
44
  #TODO: Implement this.
43
45
  #Should jump to next controller method right after this one finishes
44
- #def redirect_to(options={})
45
- # config = {:route => self.class, :command => nil, :prompt => "", :view => :default}
46
- # config.update options if options.is_a?(Hash)
47
- #end
46
+ def redirect_to(options={})
47
+ config = {:route => self.class, :command => nil, :prompt => "", :view => :default, :args => ""}
48
+ config.update options if options.is_a?(Hash)
49
+ raise Exception.new("Could not redirect to nil. Please supply a command to redirect to.") if config[:command] == nil
50
+
51
+ self.redirect = true
52
+ self.args = config[:args]
53
+ route_to(config)
54
+ end
48
55
 
49
56
  #render sets the text that will be sent back as a response to this command
50
57
  #you can only render once per controller. This is in place to avoid magical
@@ -52,50 +59,80 @@ module Controller
52
59
  #
53
60
  #render called with no options yields the view file rendered if one exists.
54
61
  #
55
- # render #=> renders /mud/views/controller/view.rhtml
62
+ # render #=> renders /mud/views/controller/view.eruby
56
63
  #
57
64
  # render :text => "send this to them" #=> send this to them
58
65
  def render(options = {})
59
66
  raise "Double Render Error" if self.rendered
60
67
  self.rendered = true
61
- return if options[:nothing]
62
- if options[:text]
63
- @body = options[:text]
68
+ config = {:view => @method}
69
+ config.update options if options.is_a?(Hash)
70
+
71
+ return if config[:nothing]
72
+
73
+ if config[:text]
74
+ @body = config[:text]
64
75
  return
65
76
  end
66
- @body = render_template(view_file(@method))
77
+
78
+ @body = render_template(view_file(config[:view]))
67
79
  end
68
80
 
81
+ def rendered?
82
+ @rendered
83
+ end
84
+
69
85
  def initialize(command, s = {}) #:nodoc:
70
- @method = command.downcase
86
+ @method_string = command.downcase
71
87
  @session = s
88
+ self.redirect = false
89
+ end
90
+
91
+ #simple begins with abbreviation with alphabetical order
92
+ def find_method(method_string)
93
+ methods = self.command_methods.sort
94
+ methods.abbrev[method_string]
72
95
  end
96
+
97
+
73
98
 
74
99
  #service is the main method that controlls the flow through the controller.
75
100
  #first it runs the method,
76
101
  #then it renders the view if something hasn't already been rendered
77
102
  #then it tacks the prompt onto the end of the command.
78
103
  def service(*a)
79
- if respond_to? @method
80
- if self.method(@method).arity >= 1
81
- send(@method, *a)
82
- else
83
- send(@method)
104
+
105
+ @method = find_method(@method_string)
106
+ if @method == nil
107
+ render :view=>@method_string
108
+ else
109
+ if respond_to? @method
110
+ if self.method(@method).arity >= 1
111
+ send(@method, *a)
112
+ else
113
+ send(@method)
114
+ end
115
+ end
116
+ if !self.rendered
117
+ begin
118
+ render
119
+ rescue NoViewException
120
+ if self.redirect
121
+ return self
122
+ end
123
+ raise
124
+ end
84
125
  end
85
126
  end
86
- if !self.rendered
87
- render
88
- end
89
-
127
+
90
128
  @body += self.prompt if self.prompt
91
-
92
- session[:handle].puts(@body)
93
129
 
130
+ session[:handle].puts @body
94
131
  self
95
132
  end
96
133
 
97
134
  def view_file(method)
98
- command_file = method + ".rhtml"
135
+ command_file = method.to_s + ".eruby"
99
136
  load_and_read_file(command_file)
100
137
  end
101
138
 
@@ -109,7 +146,8 @@ module Controller
109
146
  file.read
110
147
  rescue Errno::ENOENT
111
148
  #if we haven't at least rendered something, we are going to through a nocommand exception here..
112
- raise Controller::NoCommandException
149
+ raise Controller::NoCommandException if !@method
150
+ raise Controller::NoViewException
113
151
  end
114
152
 
115
153
  def view_dir
@@ -131,6 +169,23 @@ module Controller
131
169
  def Base.before_view
132
170
  return @@before_view
133
171
  end
172
+
173
+ class << self
174
+ def hidden_commands
175
+ write_inheritable_attribute(:hidden_commands, Controller::Base.public_instance_methods) unless read_inheritable_attribute(:hidden_commands)
176
+ read_inheritable_attribute(:hidden_commands)
177
+ end
178
+ def hide_action(*names)
179
+ write_inheritable_attribute(:hidden_actions,
180
+ hidden_actions | names.collect { |n| n.to_s })
181
+ end
182
+ end
183
+ def command_methods
184
+ self.class.command_methods
185
+ end
186
+ def self.command_methods
187
+ @command_methods ||= Set.new(public_instance_methods - hidden_commands)
188
+ end
134
189
  end
135
190
 
136
191
  class NotFound < Base