conventional_models 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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