conventional_models 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -48,11 +48,53 @@ Output:
48
48
  belongs_to_matcher {|column| column.name.end_with? "_id"}
49
49
  belongs_to_name {|column| column.name.gsub(/_id$/, "")}
50
50
  primary_key_name "id"
51
- table_name {|name| name.pluralize}
52
51
  class_name {|table_name| table_name.singularize.camelize}
53
52
  ignore_tables "schema_migrations", "sqlite_sequence", "sysdiagrams"
54
53
  end
55
54
 
55
+ == cmconsole command
56
+
57
+ Starts an IRB session and configures activerecord for you based on what is in config/database.yml.
58
+
59
+ === Usage
60
+ cmconsole [options]
61
+
62
+ For help use: cmconsole -h
63
+
64
+ === Options
65
+ -h, --help Displays help message
66
+ -v, --version Display the version, then exit
67
+ -e, --environment Specify the database env to use, default to development
68
+ -c, --config Where database.yml lives
69
+ -s, --skip-configure Don't configure ConventionalModels automatically
70
+ -V, --verbose Verbose
71
+
72
+ == Rake
73
+
74
+ You can use this from rake as follows:
75
+
76
+ # Confiigure active_record as you would normally
77
+
78
+ task :console do
79
+ require 'irb'
80
+ require 'conventional_models'
81
+ ConventionalModels.configure do
82
+ primary_key_name "Id"
83
+ end
84
+ puts ConventionalModels.model_code
85
+ IRB.start
86
+ end
87
+
88
+
89
+ == Why?
90
+
91
+ I use this for data migrations or quick scripting tasks on databases that don't follow rails
92
+ conventions.
93
+
94
+ == TODO
95
+
96
+
97
+
56
98
  == Note on Patches/Pull Requests
57
99
 
58
100
  * Fork the project.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # == Synopsis
4
+ # cmconsole starts an IRB session and configures activerecord for you
5
+ # based on what is in config/database.yml.
6
+ #
7
+ # == Examples
8
+ # Default options when you run cmconsosole are:
9
+ # cmconsole --config config/database.yml -e development
10
+ #
11
+ # Other examples:
12
+ # cmconsole --skip-configure
13
+ #
14
+ # == Usage
15
+ # cmconsole [options]
16
+ #
17
+ # For help use: cmconsole -h
18
+ #
19
+ # == Options
20
+ # -h, --help Displays help message
21
+ # -v, --version Display the version, then exit
22
+ # -e, --environment Specify the database env to use
23
+ # -c, --config Where database.yml lives
24
+ # -s, --skip-configure Don't configure ConventionalModels automatically
25
+ # -V, --verbose Verbose
26
+ #
27
+ # == Author
28
+ # Steve Hodgkiss
29
+ #
30
+ # == Copyright
31
+ # Copyright (c) 2007 Steve Hodgkiss. Licensed under the MIT License:
32
+ # http://www.opensource.org/licenses/mit-license.php
33
+
34
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
35
+ begin
36
+ require 'conventional_models'
37
+ rescue LoadError
38
+ if File.symlink? __FILE__
39
+ require File.dirname(File.readlink(__FILE__)) + '/../lib/conventional_models'
40
+ else
41
+ require File.dirname(__FILE__) + '/../lib/conventional_models'
42
+ end
43
+ end
44
+ cli = ConventionalModels::CLI.new(ARGV)
45
+ cli.run
@@ -5,13 +5,15 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{conventional_models}
8
- s.version = "0.1.2"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Steve Hodgkiss"]
12
- s.date = %q{2010-04-10}
12
+ s.date = %q{2010-04-11}
13
+ s.default_executable = %q{cmconsole}
13
14
  s.description = %q{Generate ActiveRecord models automatically with basic relationships based on conventions.}
14
15
  s.email = %q{steve@hodgkiss.me.uk}
16
+ s.executables = ["cmconsole"]
15
17
  s.extra_rdoc_files = [
16
18
  "LICENSE",
17
19
  "README.rdoc"
@@ -25,21 +27,30 @@ Gem::Specification.new do |s|
25
27
  "README.rdoc",
26
28
  "Rakefile",
27
29
  "VERSION",
30
+ "bin/cmconsole",
28
31
  "conventional_models.gemspec",
32
+ "features/cmconsole.feature",
29
33
  "features/conventional_models.feature",
30
34
  "features/output_model_code.feature",
35
+ "features/step_definitions/cmconsole_steps.rb",
31
36
  "features/step_definitions/conventional_models_steps.rb",
32
37
  "features/step_definitions/output_model_code_steps.rb",
33
38
  "features/support/env.rb",
34
39
  "lib/conventional_models.rb",
35
40
  "lib/conventional_models/active_record_base_model_for.rb",
41
+ "lib/conventional_models/cli.rb",
36
42
  "lib/conventional_models/column.rb",
37
43
  "lib/conventional_models/conventions.rb",
38
44
  "lib/conventional_models/database.rb",
45
+ "lib/conventional_models/option_parser.rb",
46
+ "lib/conventional_models/options.rb",
39
47
  "lib/conventional_models/table.rb",
40
48
  "lib/conventional_models/version.rb",
49
+ "spec/conventional_models/cli_spec.rb",
41
50
  "spec/conventional_models/conventions_spec.rb",
42
51
  "spec/conventional_models/database_spec.rb",
52
+ "spec/conventional_models/option_parser_spec.rb",
53
+ "spec/conventional_models/options_spec.rb",
43
54
  "spec/conventional_models/table_spec.rb",
44
55
  "spec/conventional_models_spec.rb",
45
56
  "spec/spec.opts",
@@ -51,8 +62,11 @@ Gem::Specification.new do |s|
51
62
  s.rubygems_version = %q{1.3.6}
52
63
  s.summary = %q{Generate ActiveRecord models. For lazy people.}
53
64
  s.test_files = [
54
- "spec/conventional_models/conventions_spec.rb",
65
+ "spec/conventional_models/cli_spec.rb",
66
+ "spec/conventional_models/conventions_spec.rb",
55
67
  "spec/conventional_models/database_spec.rb",
68
+ "spec/conventional_models/option_parser_spec.rb",
69
+ "spec/conventional_models/options_spec.rb",
56
70
  "spec/conventional_models/table_spec.rb",
57
71
  "spec/conventional_models_spec.rb",
58
72
  "spec/spec_helper.rb"
@@ -0,0 +1,34 @@
1
+ @wip
2
+ Feature: Cmconsole
3
+ In order to play with models generated against other projects with ease
4
+ As a user
5
+ I want a cmconsole command to find my database config, configure activerecord and start an IRB session for me
6
+
7
+ Scenario: Typing cmconsole when a valid config/database.yml exists
8
+ Given a file named "config/database.yml" with:
9
+ """
10
+ development:
11
+ adapter: sqlite3
12
+ database: test.sqlite
13
+ pool: 5
14
+ timeout: 5000
15
+
16
+ test:
17
+ adapter: sqlite3
18
+ database: test.sqlite
19
+ pool: 5
20
+ timeout: 5000
21
+
22
+ production:
23
+ adapter: sqlite3
24
+ database: production.sqlite
25
+ pool: 5
26
+ timeout: 5000
27
+ """
28
+ And a table "pages"
29
+ When I run "../../bin/cmconsole"
30
+ Then I should see ">> "
31
+
32
+
33
+
34
+
@@ -10,7 +10,7 @@ Feature: ConventionalModels
10
10
  $:.unshift("../../lib")
11
11
  require 'rubygems'
12
12
  require 'active_record'
13
- ActiveRecord::Base.establish_connection(:database => '../test.sqlite', :adapter => 'sqlite3')
13
+ ActiveRecord::Base.establish_connection(:database => 'test.sqlite', :adapter => 'sqlite3')
14
14
  require 'conventional_models'
15
15
  ConventionalModels.configure
16
16
  puts "Number of records: #{<model_name>.count}"
@@ -30,7 +30,7 @@ Feature: ConventionalModels
30
30
  $:.unshift("../../lib")
31
31
  require 'rubygems'
32
32
  require 'active_record'
33
- ActiveRecord::Base.establish_connection(:database => '../test.sqlite', :adapter => 'sqlite3')
33
+ ActiveRecord::Base.establish_connection(:database => 'test.sqlite', :adapter => 'sqlite3')
34
34
  require 'conventional_models'
35
35
  ConventionalModels.configure
36
36
  puts "Number of records: #{<model_name>.count}"
@@ -58,7 +58,7 @@ Feature: ConventionalModels
58
58
  $:.unshift("../../lib")
59
59
  require 'rubygems'
60
60
  require 'active_record'
61
- ActiveRecord::Base.establish_connection(:database => '../test.sqlite', :adapter => 'sqlite3')
61
+ ActiveRecord::Base.establish_connection(:database => 'test.sqlite', :adapter => 'sqlite3')
62
62
  require 'conventional_models'
63
63
  ConventionalModels.configure do
64
64
  primary_key_name "Id"
@@ -18,7 +18,7 @@ Feature: Output model code
18
18
  $:.unshift("../../lib")
19
19
  require 'rubygems'
20
20
  require 'active_record'
21
- ActiveRecord::Base.establish_connection(:database => '../test.sqlite', :adapter => 'sqlite3')
21
+ ActiveRecord::Base.establish_connection(:database => 'test.sqlite', :adapter => 'sqlite3')
22
22
  require 'conventional_models'
23
23
  ConventionalModels.configure do
24
24
  primary_key_name "Id"
@@ -8,15 +8,16 @@ require 'active_record'
8
8
 
9
9
  Before do
10
10
  config = {
11
- :development => {
12
- :database => 'tmp/test.sqlite',
13
- :adapter => 'sqlite3'
11
+ "development" => {
12
+ "database" => 'tmp/aruba/test.sqlite',
13
+ "adapter" => 'sqlite3'
14
14
  }
15
15
  }
16
16
 
17
17
  ActiveRecord::Base.configurations = config
18
18
 
19
19
  system "mkdir -p tmp"
20
- system 'rm -f tmp/test.sqlite'
21
- ActiveRecord::Base.establish_connection(config[:development])
20
+ system "mkdir -p tmp/aruba"
21
+ system 'rm -f tmp/aruba/test.sqlite'
22
+ ActiveRecord::Base.establish_connection(config["development"])
22
23
  end
@@ -7,12 +7,21 @@ require 'conventional_models/database'
7
7
  require 'conventional_models/table'
8
8
  require 'conventional_models/column'
9
9
  require 'conventional_models/active_record_base_model_for'
10
+ require 'conventional_models/options'
11
+ require 'conventional_models/option_parser'
12
+ require 'conventional_models/cli'
13
+ require 'irb';
14
+ require 'irb/completion'
10
15
 
11
16
  module ConventionalModels
17
+ @@database = nil
18
+
12
19
  def self.configure(&block)
13
20
  @@conventions = Conventions.new(&block)
14
- @@database = Database.new(::ActiveRecord::Base.connection)
15
- @@database.apply_conventions(@@conventions)
21
+ unless @@database.nil?
22
+ remove(@@database)
23
+ end
24
+ @@database = Database.new(@@conventions)
16
25
  run_code @@database.code
17
26
  end
18
27
 
@@ -27,4 +36,22 @@ module ConventionalModels
27
36
  def self.model_code_for(table)
28
37
  @@database.code_for(table)
29
38
  end
39
+
40
+ def self.run_console!
41
+ configure_active_record
42
+ configure
43
+ IRB.start
44
+ end
45
+
46
+ def self.configure_active_record(config='config/database.yml', environment='development')
47
+ config = YAML::load(IO.read(config))
48
+ ActiveRecord::Base.configurations = config
49
+ ActiveRecord::Base.establish_connection(config[environment])
50
+ end
51
+
52
+ def self.remove(database)
53
+ database.tables.map{|t| t.class_name.to_sym}.each do |class_sym|
54
+ Object.send(:remove_const, class_sym)
55
+ end
56
+ end
30
57
  end
@@ -0,0 +1,61 @@
1
+ require 'optparse'
2
+ require 'rdoc/usage'
3
+ require 'ostruct'
4
+ require 'date'
5
+
6
+ module ConventionalModels
7
+ class CLI
8
+ attr_reader :options
9
+
10
+ def initialize(arguments)
11
+ @arguments = arguments
12
+ @option_parser = OptionParser.new(arguments)
13
+ @options = @option_parser.options
14
+ end
15
+
16
+ def run
17
+ if @option_parser.parsed_options?
18
+ return output_help if @options.output_help
19
+ return output_version if @options.output_version
20
+ output_options if @options.verbose
21
+ run_console
22
+ else
23
+ output_usage
24
+ end
25
+ end
26
+
27
+ protected
28
+
29
+ def run_console
30
+ unless File.exists?(@options.config)
31
+ puts "Config #{@options.config} doesn't exist!"
32
+ return
33
+ end
34
+ ConventionalModels.configure_active_record(@options.config, @options.environment)
35
+ ConventionalModels.configure unless @options.skip_configure
36
+ puts ConventionalModels.model_code
37
+ IRB.start
38
+ end
39
+
40
+ def output_options
41
+ puts "Options:\n"
42
+
43
+ @options.marshal_dump.each do |name, val|
44
+ puts " #{name} = #{val}"
45
+ end
46
+ end
47
+
48
+ def output_help
49
+ output_version
50
+ RDoc::usage()
51
+ end
52
+
53
+ def output_usage
54
+ RDoc::usage('usage')
55
+ end
56
+
57
+ def output_version
58
+ puts "ConventionalModels version #{ConventionalModels::VERSION::STRING}"
59
+ end
60
+ end
61
+ end
@@ -4,27 +4,11 @@ module ConventionalModels
4
4
  class Database
5
5
  attr_accessor :tables
6
6
 
7
- def initialize(connection)
8
- @connection = connection
7
+ def initialize(conventions)
8
+ @connection = ::ActiveRecord::Base.connection
9
+ @conventions = conventions
9
10
  @tables = []
10
- end
11
-
12
- def apply_conventions(conventions)
13
- @connection.tables.select{|table| !conventions.ignored_tables.include? table}.each do |table|
14
- @tables << Table.new(table, @connection.columns(table))
15
- end
16
-
17
- @tables.each{|table| table.apply_conventions(conventions)}
18
-
19
- @tables.each do |table|
20
- table.belongs_to_names.each do |belongs_to|
21
- name = conventions.belongs_to_name.call(belongs_to)
22
- has_many_table = @tables.select{|t| t.class_name == conventions.class_name.call(name)}.first
23
- if has_many_table
24
- has_many_table.lines << "has_many :#{table.name.tableize}, :class_name => '#{table.class_name}', :primary_key => '#{conventions.primary_key_name}', :foreign_key => '#{belongs_to.name}'"
25
- end
26
- end
27
- end
11
+ apply_conventions
28
12
  end
29
13
 
30
14
  def code
@@ -39,5 +23,33 @@ module ConventionalModels
39
23
  "#{table_name} not found"
40
24
  end
41
25
  end
26
+
27
+ protected
28
+ def apply_conventions
29
+ @connection.tables.select{|table| !@conventions.ignored_tables.include? table}.each do |table|
30
+ @tables << Table.new(table, @connection.columns(table), @conventions)
31
+ end
32
+
33
+ @tables.each do |table|
34
+ table.belongs_to_names.each do |belongs_to|
35
+ name = @conventions.belongs_to_name.call(belongs_to)
36
+ has_many_table = @tables.select{|t| t.class_name == @conventions.class_name.call(name)}.first
37
+ if has_many_table
38
+ unconventions = []
39
+ unless table.conventional_name?
40
+ unconventions << ":class_name => '#{table.class_name}'"
41
+ unconventions << ":foreign_key => '#{belongs_to.name}'"
42
+ end
43
+ unless @conventions.primary_key_name == "id"
44
+ unconventions << ":primary_key => '#{@conventions.primary_key_name}'"
45
+ end
46
+
47
+ has_many_table.lines << ["has_many :#{table.name.tableize}", "#{unconventions.join(", ")}"].select do |convention|
48
+ !convention.empty?
49
+ end.join(", ")
50
+ end
51
+ end
52
+ end
53
+ end
42
54
  end
43
55
  end
@@ -0,0 +1,50 @@
1
+ require 'optparse'
2
+ require 'rdoc/usage'
3
+ require 'ostruct'
4
+ require 'date'
5
+
6
+ module ConventionalModels
7
+ class OptionParser
8
+
9
+ attr_reader :options
10
+
11
+ def initialize(arguments)
12
+ @arguments = arguments
13
+
14
+ @options = Options.new
15
+
16
+ @parsed_options = true
17
+ parse
18
+ end
19
+
20
+ def parsed_options?
21
+ @parsed_options
22
+ end
23
+
24
+ def parse
25
+ opts = ::OptionParser.new
26
+ opts.on('-v', '--version') { @options.output_version = true }
27
+ opts.on('-h', '--help') { @options.output_help = true }
28
+ opts.on('-s', '--skip-configure') { @options.skip_configure = true }
29
+ opts.on('-c', '--config FILE') { |file| @options.config = file }
30
+ opts.on('-e', '--environment ENV') { |env| @options.environment = env }
31
+ opts.on('-V', '--verbose') { |env| @options.verbose = true }
32
+
33
+ opts.parse!(@arguments) rescue @parsed_options = false
34
+ end
35
+
36
+ protected
37
+ def output_help
38
+ output_version
39
+ RDoc::usage()
40
+ end
41
+
42
+ def output_usage
43
+ RDoc::usage('usage')
44
+ end
45
+
46
+ def output_version
47
+ puts "ConventionalModels version #{ConventionalModels::VERSION}"
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,16 @@
1
+ module ConventionalModels
2
+ class Options
3
+ attr_accessor :skip_configure, :config, :environment, :verbose, :output_version, :output_help
4
+
5
+ def initialize
6
+ @skip_configure = false
7
+ @config = "config/database.yml"
8
+ @environment = "development"
9
+ @verbose = false
10
+ @output_version = false
11
+ @output_help = false
12
+ end
13
+
14
+
15
+ end
16
+ end
@@ -2,35 +2,44 @@ module ConventionalModels
2
2
  class Table
3
3
  attr_accessor :name, :columns, :lines, :belongs_to_names, :class_name
4
4
 
5
- def initialize(name, columns)
5
+ def initialize(name, columns, conventions)
6
6
  @name = name
7
7
  @columns = columns
8
8
  @lines = []
9
9
  @belongs_to_names = []
10
+ @conventions = conventions
11
+
12
+ apply_conventions
10
13
  end
11
14
 
12
15
  def ==(other)
13
16
  @name == other.name
14
17
  end
15
18
 
16
- def apply_conventions(conventions)
17
- @class_name = conventions.class_name.call(@name)
19
+ def code
20
+ "class ::#{@name.singularize.camelize} < ::ActiveRecord::Base\n#{@lines.map{|l| " #{l}"}.join("\n")}\nend"
21
+ end
22
+
23
+ def conventional_name?
24
+ @name.tableize == @name
25
+ end
26
+
27
+ protected
28
+
29
+ def apply_conventions
30
+ @class_name = @conventions.class_name.call(@name)
18
31
 
19
- @lines << "set_primary_key \"#{conventions.primary_key_name}\""
32
+ @lines << "set_primary_key \"#{@conventions.primary_key_name}\"" unless @conventions.primary_key_name == "id"
20
33
 
21
- @lines << "set_table_name \"#{@name}\""
34
+ @lines << "set_table_name \"#{@name}\"" unless @name.tableize == @name
22
35
 
23
- @columns.each do |column|
24
- if conventions.belongs_to_matcher.call(column)
25
- name = conventions.belongs_to_name.call(column)
26
- @belongs_to_names << column
27
- @lines << "belongs_to :#{name.underscore}, :class_name => '#{conventions.class_name.call(name)}'"
36
+ @columns.each do |column|
37
+ if @conventions.belongs_to_matcher.call(column)
38
+ name = @conventions.belongs_to_name.call(column)
39
+ @belongs_to_names << column
40
+ @lines << "belongs_to :#{name.underscore}, :class_name => '#{@conventions.class_name.call(name)}'"
41
+ end
28
42
  end
29
43
  end
30
- end
31
-
32
- def code
33
- "class ::#{@name.singularize.camelize} < ::ActiveRecord::Base\n#{@lines.map{|l| " #{l}"}.join("\n")}\nend"
34
- end
35
44
  end
36
45
  end
@@ -1,8 +1,8 @@
1
1
  module ConventionalModels #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 0
5
- BUILD = 1
4
+ MINOR = 2
5
+ BUILD = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, BUILD].join('.')
8
8
  end
@@ -0,0 +1,114 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ module ConventionalModels
4
+ describe CLI do
5
+ before(:each) do
6
+ @args = []
7
+ @options = Options.new
8
+ @option_parser = mock(OptionParser, :options => @options)
9
+ OptionParser.stub(:new).and_return(@option_parser)
10
+ File.stub(:exists?).with(@options.config).and_return(true)
11
+ end
12
+
13
+ it "should create a new option parser with args" do
14
+ OptionParser.should_receive(:new).with(@args)
15
+ CLI.new(@args)
16
+ end
17
+
18
+ describe "run" do
19
+ before(:each) do
20
+ @stdout_orig = $stdout
21
+ $stdout = StringIO.new
22
+ end
23
+ after(:each) do
24
+ $stdout = @stdout_orig
25
+ end
26
+
27
+ def run
28
+ @cli = CLI.new(@args)
29
+ @cli.run
30
+ end
31
+
32
+ describe "with parsed options" do
33
+ before(:each) do
34
+ @option_parser.stub(:parsed_options?).and_return(true)
35
+ ConventionalModels.stub(:configure)
36
+ ConventionalModels.stub(:model_code)
37
+ ConventionalModels.stub(:configure_active_record)
38
+ IRB.stub(:start)
39
+ end
40
+
41
+ it "configures activerecord with config and environment options" do
42
+ ConventionalModels.should_receive(:configure_active_record).with(@options.config, @options.environment)
43
+ run
44
+ end
45
+
46
+ describe "when config doesnt exist" do
47
+ before(:each) do
48
+ File.stub(:exists?).with(@options.config).and_return(false)
49
+ end
50
+
51
+ it "complains" do
52
+ run
53
+ $stdout.string.should include("doesn't exist")
54
+ end
55
+
56
+ it "does not call configure_active_record" do
57
+ run
58
+ ConventionalModels.should_not_receive(:configure_active_record)
59
+ end
60
+ end
61
+
62
+ it "calls configure" do
63
+ ConventionalModels.should_receive(:configure)
64
+ run
65
+ end
66
+
67
+ it "puts the model code" do
68
+ ConventionalModels.should_receive(:model_code).and_return("TEST")
69
+ run
70
+ $stdout.string.should == "TEST\n"
71
+ end
72
+
73
+ it "start IRB" do
74
+ IRB.should_receive(:start)
75
+ run
76
+ end
77
+
78
+ describe "with skip-configure option" do
79
+ it "does not call configure" do
80
+ @options.skip_configure = true
81
+ ConventionalModels.should_not_receive(:configure)
82
+ run
83
+ end
84
+ end
85
+
86
+ describe "with help option" do
87
+ it "outputs help" do
88
+ RDoc.should_receive(:usage)
89
+ @options.output_help = true
90
+ ConventionalModels.should_not_receive(:configure_active_record)
91
+ run
92
+ end
93
+ end
94
+
95
+ describe "with output version option" do
96
+ it "outputs the version" do
97
+ @options.output_version = true
98
+ ConventionalModels.should_not_receive(:configure_active_record)
99
+ run
100
+ $stdout.string.should =~ /#{VERSION::STRING}/
101
+ end
102
+ end
103
+ end
104
+
105
+ describe "with invalid options" do
106
+ it "prints usage" do
107
+ RDoc.should_receive(:usage).with('usage')
108
+ @option_parser.stub(:parsed_options?).and_return(false)
109
+ run
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -9,6 +9,8 @@ module ConventionalModels
9
9
  @connection = mock(::ActiveRecord::ConnectionAdapters::AbstractAdapter)
10
10
  @columns = [mock(Column)]
11
11
 
12
+ ::ActiveRecord::Base.stub(:connection).and_return(@connection)
13
+
12
14
  @connection.stub(:tables).and_return(["Test"])
13
15
  @connection.stub(:columns).with("Test").and_return(@columns)
14
16
 
@@ -19,39 +21,57 @@ module ConventionalModels
19
21
  Table.stub(:new => @table)
20
22
  end
21
23
 
22
- describe "#apply_conventions" do
23
- before(:each) do
24
- @database = Database.new(@connection)
25
- end
26
-
27
- it "creates a table with the table name and the column definitions" do
28
- Table.should_receive(:new).with("Test", @columns).and_return(@table)
29
- @database.apply_conventions(@conventions)
24
+ describe ".new" do
25
+ it "creates a table with the table name, column definitions and conventions" do
26
+ Table.should_receive(:new).with("Test", @columns, @conventions).and_return(@table)
27
+ @database = Database.new(@conventions)
30
28
  @database.tables.first.should == @table
31
29
  end
32
30
 
33
- it "applies conventions to each table" do
34
- @table.should_receive(:apply_conventions).with(@conventions)
35
- @database.apply_conventions(@conventions)
36
- end
37
-
38
31
  describe "has many relationships" do
39
- before(:each) do
40
- @connection.stub(:tables).and_return(["sites", "pages"])
32
+
33
+ describe "conventional" do
34
+ before(:each) do
35
+ @connection.stub(:tables).and_return(["sites", "pages"])
36
+
37
+ Table.unstub!(:new)
38
+ @site_columns = [Column.new("name", nil, "string")]
39
+ @pages_columns = [Column.new("site_id", nil, "integer")]
40
+ @connection.stub(:columns).with("sites").and_return(@site_columns)
41
+ @connection.stub(:columns).with("pages").and_return(@pages_columns)
42
+ @database = Database.new(Conventions.new)
43
+ end
44
+
45
+ it "sets the table name" do
46
+ @database.tables.first.name.should == "sites"
47
+ end
41
48
 
42
- Table.unstub!(:new)
43
- @site_columns = [Column.new("name", nil, "string")]
44
- @pages_columns = [Column.new("site_id", nil, "integer")]
49
+ it "sets site to have many pages" do
50
+ @database.tables.first.lines.last.should == "has_many :pages"
51
+ # , :class_name => 'Page', :primary_key => 'id', :foreign_key => 'site_id'
52
+ end
53
+ end
54
+
55
+ describe "unconventional" do
56
+ before(:each) do
57
+ @connection.stub(:tables).and_return(["Site", "Page"])
58
+ Table.unstub!(:new)
59
+ @site_columns = [Column.new("Name", nil, "string")]
60
+ @pages_columns = [Column.new("Site_id", nil, "integer")]
61
+ @connection.stub(:columns).with("Site").and_return(@site_columns)
62
+ @connection.stub(:columns).with("Page").and_return(@pages_columns)
63
+ @database = Database.new(Conventions.new{ primary_key_name "ID" })
64
+ end
65
+
66
+ it "sets the table name" do
67
+ @database.tables.first.name.should == "Site"
68
+ end
45
69
 
46
- @connection.stub(:columns).with("sites").and_return(@site_columns)
47
- @connection.stub(:columns).with("pages").and_return(@pages_columns)
70
+ it "sets site to have many pages" do
71
+ @database.tables.first.lines.last.should == "has_many :pages, :class_name => 'Page', :foreign_key => 'Site_id', :primary_key => 'ID'"
72
+ end
48
73
  end
49
74
 
50
- it "sets site to have many pages" do
51
- @database.apply_conventions(Conventions.new)
52
- @database.tables.first.name.should == "sites"
53
- @database.tables.first.lines.last.should == "has_many :pages, :class_name => 'Page', :primary_key => 'id', :foreign_key => 'site_id'"
54
- end
55
75
  end
56
76
 
57
77
  it "ignores tables" do
@@ -59,19 +79,18 @@ module ConventionalModels
59
79
  ignore_tables "Test"
60
80
  end
61
81
  @table.should_not_receive(:apply_conventions)
62
- @database.apply_conventions(@conventions)
82
+ @database = Database.new(@conventions)
63
83
  end
64
84
  end
65
85
 
66
86
  describe "code outputting" do
67
87
  before(:each) do
68
88
  @table.stub(:name).and_return("Test")
69
- @database = Database.new(@connection)
70
- @database.apply_conventions(@conventions)
71
89
  end
72
90
  describe "#code" do
73
91
  it "should return the code for each table" do
74
92
  @table.should_receive(:code).and_return("test")
93
+ @database = Database.new(@conventions)
75
94
  @database.code.should == "test"
76
95
  end
77
96
  end
@@ -79,9 +98,11 @@ module ConventionalModels
79
98
  describe "#code_for" do
80
99
  it "should return the model code for a specific table" do
81
100
  @table.should_receive(:code).and_return("test")
101
+ @database = Database.new(@conventions)
82
102
  @database.code_for("Test").should == "test"
83
103
  end
84
104
  it "should return not found for unknown tables" do
105
+ @database = Database.new(@conventions)
85
106
  @database.code_for("SomeTable").should == "SomeTable not found"
86
107
  end
87
108
  end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ module ConventionalModels
4
+ describe OptionParser do
5
+ def options_for(args)
6
+ @option_parser = OptionParser.new(args)
7
+ @option_parser.options
8
+ end
9
+
10
+ describe "parsing" do
11
+ it "accepts a database config file" do
12
+ options_for(["-c", "config/db.yml"]).config.should == "config/db.yml"
13
+ options_for(["--config", "config/db.yml"]).config.should == "config/db.yml"
14
+ end
15
+
16
+ it "accepts an environment flag" do
17
+ options_for(["-e", "production"]).environment.should == "production"
18
+ options_for(["--environment", "production"]).environment.should == "production"
19
+ end
20
+
21
+ it "accepts a skip configure flag" do
22
+ options_for(["-s"]).skip_configure.should == true
23
+ options_for(["--skip-configure"]).skip_configure.should == true
24
+ end
25
+
26
+ it "accepts an output version flag" do
27
+ options_for(["-v"]).output_version.should == true
28
+ options_for(["--version"]).output_version.should == true
29
+ end
30
+
31
+ it "accepts an output help flag" do
32
+ options_for(["-h"]).output_help.should == true
33
+ options_for(["--help"]).output_help.should == true
34
+ end
35
+ end
36
+
37
+ describe "invalid arguments" do
38
+ it "should set parsed_options? to false" do
39
+ options_for(["--boobs"])
40
+ @option_parser.parsed_options?.should == false
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ module ConventionalModels
4
+ describe Options do
5
+ before(:each) do
6
+ @options = Options.new
7
+ end
8
+
9
+ describe "default options" do
10
+ it "should use rails location for default database.yml" do
11
+ @options.config.should == "config/database.yml"
12
+ end
13
+
14
+ it "should configure" do
15
+ @options.skip_configure.should be_false
16
+ end
17
+
18
+ it "should default to development environment" do
19
+ @options.environment.should == "development"
20
+ end
21
+
22
+ it "should not be verbose" do
23
+ @options.verbose.should be_false
24
+ end
25
+
26
+ it "should not output version" do
27
+ @options.output_version.should be_false
28
+ end
29
+
30
+ it "should not output help" do
31
+ @options.output_help.should be_false
32
+ end
33
+ end
34
+ end
35
+ end
@@ -4,36 +4,66 @@ module ConventionalModels
4
4
  describe Table do
5
5
  before(:each) do
6
6
  @columns = [mock(Column, :name => "test")]
7
+ @conventions = Conventions.new
8
+ end
9
+
10
+ def has_item?(array, expected)
11
+ @found = false
12
+ array.each do |line|
13
+ @found = true if line == expected
14
+ end
15
+ @found
7
16
  end
8
17
 
9
18
  describe ".new" do
10
19
  it "sets the name" do
11
- Table.new("test", @columns).name.should == "test"
20
+ Table.new("test", @columns, @conventions).name.should == "test"
12
21
  end
13
22
 
14
23
  it "sets the columns" do
15
- Table.new("test", @columns).columns.should == @columns
24
+ Table.new("test", @columns, @conventions).columns.should == @columns
16
25
  end
17
26
  end
18
27
 
19
28
  describe "#==" do
20
29
  it "is true for tables with the same name" do
21
- Table.new("Page", @columns).should == Table.new("Page", @columns)
30
+ Table.new("Page", @columns, @conventions).should == Table.new("Page", @columns, @conventions)
22
31
  end
23
32
 
24
33
  it "is false for tables with different names" do
25
- Table.new("Page", @columns).should_not == Table.new("Bar", @columns)
34
+ Table.new("Page", @columns, @conventions).should_not == Table.new("Bar", @columns, @conventions)
26
35
  end
27
36
  end
28
37
 
29
- describe "#apply_conventions" do
38
+ describe "#conventional_name?" do
39
+ it "is true for tables that have a name that matches rails conventions" do
40
+ Table.new("Page", @columns, @conventions).conventional_name?.should be_false
41
+ Table.new("pages", @columns, @conventions).conventional_name?.should be_true
42
+ end
43
+ end
44
+
45
+ describe ".new" do
30
46
  it "sets the primary key" do
31
47
  @conventions = Conventions.new do
32
48
  primary_key_name "ID"
33
49
  end
34
- @table = Table.new("Page", @columns)
35
- @table.apply_conventions(@conventions)
36
- @table.lines[0].should == "set_primary_key \"ID\""
50
+ @table = Table.new("Page", @columns, @conventions)
51
+ has_item?(@table.lines, "set_primary_key \"ID\"").should be_true
52
+ end
53
+
54
+ it "doesn't set the primary key when it is the rails default" do
55
+ @table = Table.new("Page", @columns, @conventions)
56
+ has_item?(@table.lines, "set_primary_key \"id\"").should_not == be_true
57
+ end
58
+
59
+ it "sets the table name" do
60
+ @table = Table.new("Page", @columns, @conventions)
61
+ has_item?(@table.lines, "set_table_name \"Page\"").should be_true
62
+ end
63
+
64
+ it "doesn't set the table name if it is the rails default" do
65
+ @table = Table.new("pages", @columns, @conventions)
66
+ has_item?(@table.lines, "set_table_name \"pages\"").should be_false
37
67
  end
38
68
 
39
69
  it "sets the class name" do
@@ -42,17 +72,15 @@ module ConventionalModels
42
72
  "BOO"
43
73
  end
44
74
  end
45
- @table = Table.new("Page", @columns)
46
- @table.apply_conventions(@conventions)
75
+ @table = Table.new("Page", @columns, @conventions)
47
76
  @table.class_name.should == "BOO"
48
77
  end
49
78
 
50
79
  it "sets belongs to columns" do
51
80
  @conventions = Conventions.new
52
81
  @columns = [Column.new("Site_id", nil, "integer")]
53
- @table = Table.new("Page", @columns)
54
- @table.apply_conventions(@conventions)
55
- @table.lines[2].should == "belongs_to :site, :class_name => 'Site'"
82
+ @table = Table.new("Page", @columns, @conventions)
83
+ has_item?(@table.lines, "belongs_to :site, :class_name => 'Site'").should be_true
56
84
  @table.belongs_to_names.first.name.should == "Site_id"
57
85
  end
58
86
 
@@ -60,18 +88,18 @@ module ConventionalModels
60
88
 
61
89
  describe "#code" do
62
90
  before(:each) do
63
- @table = Table.new("pages", @columns)
91
+ @table = Table.new("pages", @columns, @conventions)
64
92
  end
65
93
 
66
- it "returns an empty activerecord class with no columns" do
94
+ it "returns an activerecord class" do
67
95
  @model_code = @table.code
68
- @model_code.should == %Q{class ::Page < ::ActiveRecord::Base\n\nend}
96
+ @model_code.starts_with?(%Q{class ::Page < ::ActiveRecord::Base}).should be_true
69
97
  end
70
98
 
71
99
  it "returns lines in the model definition" do
72
100
  @table.lines << "test"
73
101
  @model_code = @table.code
74
- @model_code.split("\n")[1].should == " test"
102
+ has_item?(@model_code.split("\n"), " test").should be_true
75
103
  end
76
104
  end
77
105
  end
@@ -8,24 +8,18 @@ module ConventionalModels
8
8
 
9
9
  ConventionalModels.stub(:run_code)
10
10
 
11
- @connection = mock(Column)
12
- ::ActiveRecord::Base.stub(:connection).and_return(@connection)
13
-
14
11
  @generated_code = mock(String)
15
12
  @database = mock(Database, :code => @generated_code)
16
13
  @database.stub(:apply_conventions).with(@conventions)
17
14
  Database.stub(:new => @database)
15
+
16
+ ConventionalModels.stub(:remove)
18
17
  end
19
18
 
20
19
  describe ".configure" do
21
- describe "with no args" do
22
- it "creates a database object with the connection and conventions" do
23
- Database.should_receive(:new).with(@connection).and_return(@database)
24
- ConventionalModels.configure
25
- end
26
-
27
- it "called apply_conventions on the database object" do
28
- @database.should_receive(:apply_conventions).with(@conventions)
20
+ describe "with no args" do
21
+ it "creates a database object with the conventions" do
22
+ Database.should_receive(:new).with(@conventions).and_return(@database)
29
23
  ConventionalModels.configure
30
24
  end
31
25
 
@@ -34,6 +28,13 @@ module ConventionalModels
34
28
  ConventionalModels.configure
35
29
  end
36
30
  end
31
+ describe "second call" do
32
+ it "should call remove if a database has already been configured" do
33
+ ConventionalModels.should_receive(:remove).with(@database)
34
+ ConventionalModels.configure
35
+ ConventionalModels.configure
36
+ end
37
+ end
37
38
  end
38
39
 
39
40
  describe ".run_code" do
@@ -58,5 +59,27 @@ module ConventionalModels
58
59
  ConventionalModels.model_code_for("Test").should == "test"
59
60
  end
60
61
  end
62
+
63
+ describe ".run_console!" do
64
+ it "starts an IRB session" do
65
+ IRB.should_receive(:start)
66
+ ConventionalModels.should_receive(:configure_active_record)
67
+ ConventionalModels.should_receive(:configure)
68
+ ConventionalModels.run_console!
69
+ end
70
+ end
71
+
72
+ describe ".remove" do
73
+ before(:each) do
74
+ ConventionalModels.unstub(:remove)
75
+ table = mock(Table, :class_name => "TestTable")
76
+ @database.should_receive(:tables).and_return([table])
77
+ Object.should_receive(:send).with(:remove_const, :TestTable)
78
+ end
79
+
80
+ it "removes the table constants from the environment" do
81
+ ConventionalModels.remove(@database)
82
+ end
83
+ end
61
84
  end
62
85
  end
@@ -9,5 +9,4 @@ require 'spec'
9
9
  require 'spec/autorun'
10
10
 
11
11
  Spec::Runner.configure do |config|
12
-
13
12
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
7
  - 2
9
- version: 0.1.2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Steve Hodgkiss
@@ -14,8 +14,8 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-10 00:00:00 +01:00
18
- default_executable:
17
+ date: 2010-04-11 00:00:00 +01:00
18
+ default_executable: cmconsole
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rspec
@@ -75,8 +75,8 @@ dependencies:
75
75
  requirement: *id004
76
76
  description: Generate ActiveRecord models automatically with basic relationships based on conventions.
77
77
  email: steve@hodgkiss.me.uk
78
- executables: []
79
-
78
+ executables:
79
+ - cmconsole
80
80
  extensions: []
81
81
 
82
82
  extra_rdoc_files:
@@ -91,21 +91,30 @@ files:
91
91
  - README.rdoc
92
92
  - Rakefile
93
93
  - VERSION
94
+ - bin/cmconsole
94
95
  - conventional_models.gemspec
96
+ - features/cmconsole.feature
95
97
  - features/conventional_models.feature
96
98
  - features/output_model_code.feature
99
+ - features/step_definitions/cmconsole_steps.rb
97
100
  - features/step_definitions/conventional_models_steps.rb
98
101
  - features/step_definitions/output_model_code_steps.rb
99
102
  - features/support/env.rb
100
103
  - lib/conventional_models.rb
101
104
  - lib/conventional_models/active_record_base_model_for.rb
105
+ - lib/conventional_models/cli.rb
102
106
  - lib/conventional_models/column.rb
103
107
  - lib/conventional_models/conventions.rb
104
108
  - lib/conventional_models/database.rb
109
+ - lib/conventional_models/option_parser.rb
110
+ - lib/conventional_models/options.rb
105
111
  - lib/conventional_models/table.rb
106
112
  - lib/conventional_models/version.rb
113
+ - spec/conventional_models/cli_spec.rb
107
114
  - spec/conventional_models/conventions_spec.rb
108
115
  - spec/conventional_models/database_spec.rb
116
+ - spec/conventional_models/option_parser_spec.rb
117
+ - spec/conventional_models/options_spec.rb
109
118
  - spec/conventional_models/table_spec.rb
110
119
  - spec/conventional_models_spec.rb
111
120
  - spec/spec.opts
@@ -141,8 +150,11 @@ signing_key:
141
150
  specification_version: 3
142
151
  summary: Generate ActiveRecord models. For lazy people.
143
152
  test_files:
153
+ - spec/conventional_models/cli_spec.rb
144
154
  - spec/conventional_models/conventions_spec.rb
145
155
  - spec/conventional_models/database_spec.rb
156
+ - spec/conventional_models/option_parser_spec.rb
157
+ - spec/conventional_models/options_spec.rb
146
158
  - spec/conventional_models/table_spec.rb
147
159
  - spec/conventional_models_spec.rb
148
160
  - spec/spec_helper.rb