annotator 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2012 YOURNAME
1
+ Copyright 2012 Tech-Angels
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -62,15 +62,14 @@ Of course similar thing happens when you remove column or change it's type.
62
62
  * for some fields like title above you can just skip description including dash sometimes name is just obvious enough
63
63
  * multiline comments are ok
64
64
  * generating initial descriptions it understands things like
65
- ** belongs_to association columns
66
- ** devise columns
67
- ** paperclip colums
65
+ * belongs_to association columns
66
+ * devise columns
67
+ * paperclip colums
68
68
 
69
69
  Contributions are very much welcome.
70
70
 
71
71
  == Todos
72
72
 
73
- * it could be written a bit cleaner
74
73
  * since name does not have "model" in it, we could possibly use "rake routes" to annotate controller actions, not sure if it's worth it
75
74
 
76
75
  == Authors
data/lib/annotator.rb CHANGED
@@ -1,189 +1,15 @@
1
1
  require 'annotator/railtie'
2
+ require 'annotator/model'
3
+ require 'annotator/attributes'
4
+ require 'annotator/initial_description'
2
5
 
3
6
  module Annotator
4
- def self.run
5
- models = Dir.glob("#{Rails.root}/app/models/*.rb").map do |filename|
6
- klass = filename.split('/').last.split(/\.rb$/).first.camelize.constantize
7
- [filename, klass]
8
- end.sort_by {|x| x.last.to_s}
9
-
10
-
11
- models.each do |filename, model|
12
- next unless model.ancestors.include? ActiveRecord::Base
13
- begin
14
- file = File.read(filename)
15
- lines = file.split("\n")
16
- out = ''
17
- ia = false # inside attributes block
18
- after_block = false # we are already after comments block
19
- changed = false
20
- skip_file = false
21
- attrs_arr = []
22
- lines.each do |line|
23
- break if skip_file
24
- out << "#{line}\n" && next if after_block
25
-
26
- if ia && !line.match(/^# \*/) && !line.match(/^# \S/)
27
- out << stringify_attrs_arr(update_attrs_arr(attrs_arr, model))
28
- ia = false
29
- changed = true
30
- end
31
-
32
- # check if we are still in the comments part of the file
33
- unless line.strip.empty? || line.match(/^\s*#/)
34
- after_block = true
35
- unless changed
36
- out << "# Attributes:\n"
37
- out << stringify_attrs_arr(update_attrs_arr(attrs_arr, model))
38
- end
39
- end
40
-
41
- if ia
42
- if line.match(/^# \*/)
43
- m = line.match(/^# \* (\w+) \[(.*?)\]( \- )?(.*)/)
44
- if m
45
- attrs_arr << [m[1], m[2], m[4]].map(&:strip)
46
- else
47
- puts "!! Unrecognized line format on attributes list in #{model}:"
48
- puts line
49
- end
50
- else
51
- attrs_arr[-1][2] << " #{line[4..-1]}"
52
- end
53
- else
54
- out << "#{line}\n"
55
- end
56
-
57
- ia = true if line.match(/^# Attributes:/i)
58
- skip_file = true if line.match(/^# Attributes\(nodoc\):/i)
59
- end
60
-
61
- File.open(filename,'w') { |f| f.write(out) } if out.strip != file.strip && !skip_file
62
-
63
- rescue Exception => e
64
- puts "FAILURE while trying to update model #{model}:\n #{e}"
65
- end
66
- end
67
-
68
-
69
- end
70
-
71
- protected
72
-
73
- def self.update_attrs_arr(arr, model)
74
- arr = arr.dup
75
- model.columns.each do |column|
76
- attrs_str = column_attrs(column)
77
- if row = arr.find {|x| x[0] == column.name}
78
- if row[1] != attrs_str
79
- puts " M #{model}##{column.name} [#{row[1]} -> #{attrs_str}]"
80
- row[1] = attrs_str
81
- end
82
- else
83
- puts " A #{model}##{column.name} [#{attrs_str}]"
84
- desc = initial_description model, column
85
- arr << [column.name, attrs_str, desc]
86
- end
87
- end
88
-
89
- # find columns that no more exist in db
90
- orphans = arr.map(&:first) - model.columns.map(&:name)
91
- unless orphans.empty?
92
- orphans.each do |orphan|
93
- puts " D #{model}#{orphan}"
94
- arr = arr.select {|x| x[0] != orphan}
95
- end
96
- end
97
- arr
98
- end
99
7
 
100
- def self.initial_description(model, column)
101
- case column.name
102
- when 'id' then return 'primary key'
103
- when 'created_at' then return 'creation time'
104
- when 'updated_at' then return 'last update time'
105
- end
106
-
107
- # TODO stop writing like it's functional lang and make class for Description ;)
108
-
109
- # Belongs to association
110
- model.reflect_on_all_associations.each do |reflect|
111
- if reflect.foreign_key == column.name && reflect.macro == :belongs_to
112
- return "belongs to #{reflect.klass}"
113
- end
114
- end
115
-
116
- # Devise column names
117
- if model.respond_to? :devise_modules
118
- devise_columns = {
119
- :reset_password_token => "Devise Recoverable module",
120
- :reset_password_sent_at => "Devise Recoverable module",
121
- :remember_created_at => "Devise Rememberable module",
122
- :sign_in_count => "Devise Trackable module",
123
- :current_sign_in_at => "Devise Trackable module",
124
- :last_sign_in_at => "Devise Trackable module",
125
- :current_sign_in_ip => "Devise Trackable module",
126
- :last_sign_in_ip => "Devise Trackable module",
127
- :password_salt => "Devise Encriptable module",
128
- :confirmation_token => "Devise Confirmable module",
129
- :confirmed_at => "Devise Confirmable module",
130
- :confiramtion_sent_at => "Devise Confirmable module",
131
- :unconfirmed_email => "Devise Confirmable module",
132
- :failed_attempts => "Devise Lockable module",
133
- :unlock_token => "Devise Locakble module",
134
- :locked_at => "Devise Lockable module",
135
- :authentication_token => "Devise Token authenticable module"
136
- }
137
- guess = devise_columns[column.name.to_sym]
138
- return guess if guess
139
- end
140
-
141
- # Paperclip column names
142
- if model.respond_to? :attachments_definitions
143
- model.attachments_definitions.keys.each do |att|
144
- cols = ["#{att}_file_name", "#{att}_content_type", "#{att}_file_size", "#{att}_updated_at"]
145
- return "Paperclip for #{att}" if cols.include? column.name
146
- end
147
- end
148
-
149
- # let's not add "document me" note for these obvious ones:
150
- return '' if %w{email name title body}.include? column.name
151
-
152
- return 'TODO: document me'
153
- end
154
-
155
- def self.column_attrs(c)
156
- ret = c.type.to_s
157
- ret << ", primary" if c.primary
158
- ret << ", default=#{c.default}" if c.default
159
- ret << ", not null" unless c.null
160
- ret << ", limit=#{c.limit}" if c.limit && (c.limit != 255 && c.type != :string)
161
- ret
162
- end
163
-
164
- def self.stringify_attrs_arr(arr)
165
- ret = ''
166
- arr.sort_by{|x| x[0] == 'id' ? '_' : x[0]}.each do |name, attrs, desc|
167
- # split into lines that don't exceed 80 chars
168
- desc = " - #{desc}" unless desc.empty?
169
- line = "# * #{name} [#{attrs}]#{desc}"
170
- lt = wrap_text(line, opts[:max_chars_per_line]-3).split("\n")
171
- line = ([lt[0]] + lt[1..-1].map{|x| "# #{x}"}).join("\n")
172
- ret << "#{line}\n"
8
+ def self.run
9
+ Dir.glob("#{Rails.root}/app/models/**/*.rb").sort.map do |filename|
10
+ Model.new(filename).update!
173
11
  end
174
- ret
175
12
  end
176
13
 
177
- def self.wrap_text(txt, col)
178
- txt.gsub(/(.{1,#{col}})( +|$)\n?|(.{#{col}})/,"\\1\\3\n")
179
- end
180
-
181
- def self.opts
182
- {
183
- :max_chars_per_line => 120
184
- }
185
- end
186
-
187
-
188
14
  end
189
15
 
@@ -0,0 +1,92 @@
1
+ module Annotator
2
+
3
+ # Attributes within given model file
4
+ class Attributes
5
+ R_ATTRIBUTE = /^# \* (\w+) \[(.*?)\]( \- )?(.*)$/
6
+ R_ATTRIBUTE_NEXT_LINE = /^# (.*?)$/
7
+ R_ATTRIBUTE_LINE = /(#{R_ATTRIBUTE})|(#{R_ATTRIBUTE_NEXT_LINE})/
8
+ HEADER = "# Attributes:"
9
+ MAX_CHARS_PER_LINE = 120
10
+
11
+ def initialize(model, lines)
12
+ @model = model
13
+ @lines = lines
14
+ @attrs = []
15
+ @changes = []
16
+ parse
17
+ end
18
+
19
+ # Convert attributes array back to attributes lines representation to be put into file
20
+ def lines
21
+ ret = [Attributes::HEADER]
22
+ # Sort by name, but id goes first
23
+ @attrs.sort_by{|x| x[:name] == 'id' ? '_' : x[:name]}.each do |row|
24
+ line = "# * #{row[:name]} [#{row[:type]}]#{row[:desc].to_s.empty? ? "" : " - #{row[:desc]}"}"
25
+ # split into lines that don't exceed 80 chars
26
+ lt = wrap_text(line, MAX_CHARS_PER_LINE-3).split("\n")
27
+ line = ([lt[0]] + lt[1..-1].map{|x| "# #{x}"}).join("\n")
28
+ ret << line
29
+ end
30
+ ret
31
+ end
32
+
33
+ # Update attribudes array to the current database state
34
+ def update!
35
+ @model.columns.each do |column|
36
+ if row = @attrs.find {|x| x[:name] == column.name}
37
+ if row[:type] != type_str(column)
38
+ puts " M #{@model}##{column.name} [#{row[:type]} -> #{type_str(column)}]"
39
+ row[:type] = type_str(column)
40
+ end
41
+ else
42
+ puts " A #{@model}##{column.name} [#{type_str(column)}]"
43
+ @attrs << {
44
+ :name => column.name,
45
+ :type => type_str(column),
46
+ :desc => InitialDescription.for(@model, column.name)
47
+ }
48
+ end
49
+ end
50
+
51
+ # find columns that no more exist in db
52
+ orphans = @attrs.map{|x| x[:name]} - @model.columns.map(&:name)
53
+ unless orphans.empty?
54
+ orphans.each do |orphan|
55
+ puts " D #{@model}#{orphan}"
56
+ @attrs = @attrs.select {|x| x[0] != orphan}
57
+ end
58
+ end
59
+
60
+ @attrs
61
+ end
62
+
63
+ protected
64
+
65
+ # Convert attributes lines into meaniningful array
66
+ def parse
67
+ @lines.each do |line|
68
+ if m = line.match(R_ATTRIBUTE)
69
+ @attrs << {:name => m[1].strip, :type => m[2].strip, :desc => m[4].strip}
70
+ elsif m = line.match(R_ATTRIBUTE_NEXT_LINE)
71
+ @attrs[-1][:desc] += " #{m[1].strip}"
72
+ end
73
+ end
74
+ end
75
+
76
+ # Human readable description of given column type
77
+ def type_str(c)
78
+ ret = c.type.to_s
79
+ ret << ", primary" if c.primary
80
+ ret << ", default=#{c.default}" if c.default
81
+ ret << ", not null" unless c.null
82
+ ret << ", limit=#{c.limit}" if c.limit && (c.limit != 255 && c.type != :string)
83
+ ret
84
+ end
85
+
86
+ # Wraps text nicely, not breaking in the middle of the word
87
+ def wrap_text(txt, col)
88
+ txt.gsub(/(.{1,#{col}})( +|$)\n?|(.{#{col}})/,"\\1\\3\n")
89
+ end
90
+
91
+ end
92
+ end
@@ -0,0 +1,23 @@
1
+ require 'annotator/initial_description/base'
2
+ Dir[File.dirname(__FILE__) + '/initial_description/*.rb'].each {|file| require file }
3
+
4
+ module Annotator
5
+ module InitialDescription
6
+
7
+ NO_DESCRIPTION_COLUMNS = %w{email name title body}
8
+
9
+ # Get initial description for given model & column
10
+ def self.for(model, column)
11
+ # Check if any module provides such description
12
+ Base.providers.each do |klass|
13
+ provider = klass.new model, column
14
+ return provider.text if provider.check
15
+ end
16
+ # Some columns are just too obvious
17
+ return "" if NO_DESCRIPTION_COLUMNS.include? column
18
+ # Let user do the work
19
+ return "TODO: document me"
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module Annotator
2
+ module InitialDescription
3
+
4
+ # Base class from which all other description providers inherit
5
+ class Base
6
+ def initialize(model, column)
7
+ @model = model
8
+ @column = column
9
+ end
10
+
11
+ def self.inherited(klass)
12
+ @providers ||= []
13
+ @providers << klass
14
+ end
15
+
16
+ def self.providers
17
+ @providers
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ module Annotator
2
+ module InitialDescription
3
+
4
+ # Initial descriptions for columns associated with belongs_to
5
+ class BelongsTo < Base
6
+
7
+ def check
8
+ # check if there is belongs to association where this column is a foreign key
9
+ @model.reflect_on_all_associations.each do |reflection|
10
+ if reflection.foreign_key == @column && reflection.macro == :belongs_to
11
+ @reflection = reflection
12
+ return true
13
+ end
14
+ end
15
+
16
+ # Polymorphic association type column
17
+ if @column.ends_with? '_type'
18
+ return true if @reflection = @model.reflect_on_association(@column.match(/(.*?)_type$/)[1].to_sym)
19
+ end
20
+
21
+ return false
22
+ end
23
+
24
+ def text
25
+ "belongs to :#{@reflection.name}#{@reflection.options[:polymorphic] ? ' (polymorphic)' : ''}"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,39 @@
1
+ module Annotator
2
+ module InitialDescription
3
+
4
+ # Initila descriptions for devise specific columns
5
+ class Devise < Base
6
+
7
+ def check
8
+ @model.respond_to?(:devise_modules) && columns.keys.include?(@column.to_sym)
9
+ end
10
+
11
+ def columns
12
+ {
13
+ :reset_password_token => "Devise Recoverable module",
14
+ :reset_password_sent_at => "Devise Recoverable module",
15
+ :remember_created_at => "Devise Rememberable module",
16
+ :sign_in_count => "Devise Trackable module",
17
+ :current_sign_in_at => "Devise Trackable module",
18
+ :last_sign_in_at => "Devise Trackable module",
19
+ :current_sign_in_ip => "Devise Trackable module",
20
+ :last_sign_in_ip => "Devise Trackable module",
21
+ :password_salt => "Devise Encriptable module",
22
+ :confirmation_token => "Devise Confirmable module",
23
+ :confirmed_at => "Devise Confirmable module",
24
+ :confiramtion_sent_at => "Devise Confirmable module",
25
+ :unconfirmed_email => "Devise Confirmable module",
26
+ :failed_attempts => "Devise Lockable module",
27
+ :unlock_token => "Devise Locakble module",
28
+ :locked_at => "Devise Lockable module",
29
+ :authentication_token => "Devise Token authenticable module"
30
+ }
31
+ end
32
+
33
+ def text
34
+ columns[@column.to_sym]
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,26 @@
1
+ module Annotator
2
+ module InitialDescription
3
+
4
+ # Initial descriptinos for paperclip attachments columns
5
+ class Paperclip < Base
6
+
7
+ def check
8
+ if @model.respond_to? :attachments_definitions
9
+ @model.attachments_definitions.keys.each do |att|
10
+ cols = ["#{att}_file_name", "#{att}_content_type", "#{att}_file_size", "#{att}_updated_at"]
11
+ if cols.include? @column
12
+ @attachment = att
13
+ return true
14
+ end
15
+ end
16
+ end
17
+ return false
18
+ end
19
+
20
+ def text
21
+ "Paperclip for #{@attachment}"
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module Annotator
2
+ module InitialDescription
3
+
4
+ # Initial descriptions for rails specific columns
5
+ class Rails < Base
6
+ def check
7
+ columns.keys.include? @column.to_sym
8
+ end
9
+
10
+ def columns
11
+ {
12
+ :id => "primary key", # TODO check if it actually is a primary key, find primary keys with other names
13
+ :created_at => "creation time",
14
+ :updated_at => "last update time"
15
+ }
16
+ end
17
+
18
+ def text
19
+ columns[@column.to_sym]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,57 @@
1
+ module Annotator
2
+
3
+ # Represents a single model file and associated class
4
+ class Model
5
+
6
+ def initialize(filename)
7
+ @filename = filename
8
+ @blocks = Hash.new {[]}
9
+ end
10
+
11
+ # Model class
12
+ def klass
13
+ @filename.split('app/models/').last.split(/\.rb$/).first.camelize.constantize rescue nil
14
+ end
15
+
16
+ # Split file into 3 blocks: before attributes, attributes block, and after
17
+ # If there's no attributes block, content will be in :after part (for easier insertion)
18
+ def parse
19
+ @file = File.read(@filename).strip
20
+ current_block = :before
21
+ return @nodoc = true if @file.match(/^# Attributes\(nodoc\):$/i)
22
+ @file.split("\n").each do |line|
23
+ if line.match(/^#{Regexp.escape Attributes::HEADER} *$/)
24
+ current_block = :attributes
25
+ next
26
+ end
27
+ current_block = :after if current_block == :attributes && !line.match(Attributes::R_ATTRIBUTE_LINE)
28
+ @blocks[current_block] += [line]
29
+ end
30
+
31
+ @blocks[:after], @blocks[:before] = @blocks[:before], [] if @blocks[:after].empty?
32
+ end
33
+
34
+ # If this file does not have associated AR class it should be skipped
35
+ def skipped?
36
+ !klass || !klass.ancestors.include?(ActiveRecord::Base) || @nodoc
37
+ end
38
+
39
+ # Save changes to file if there were any
40
+ def update_file
41
+ output = (@blocks[:before] + @blocks[:attributes] + @blocks[:after]).join("\n").strip + "\n"
42
+ File.open(@filename,'w') { |f| f.write(output) } if output != @file
43
+ end
44
+
45
+ # Update file with new database information
46
+ def update!
47
+ parse
48
+ return true if skipped?
49
+ attributes = Attributes.new klass, @blocks[:attributes]
50
+ attributes.update!
51
+ @blocks[:attributes] = attributes.lines
52
+ update_file
53
+ end
54
+ end
55
+ end
56
+
57
+
@@ -1,3 +1,3 @@
1
1
  module Annotator
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -3,7 +3,7 @@ require 'tempfile'
3
3
 
4
4
  class AnnotatorTest < ActiveSupport::TestCase
5
5
  def setup
6
- @output = execute("cd #{$test_app} && rake annotate")
6
+ @output = execute("rake annotate")
7
7
  end
8
8
 
9
9
  test "annotating foo" do
@@ -12,13 +12,13 @@ class AnnotatorTest < ActiveSupport::TestCase
12
12
 
13
13
  test "leaving existing comments" do
14
14
  FileUtils.cp asset_file('foo_annotated_with_comments.rb'), app_file('foo.rb')
15
- assert system("cd #{$test_app} && rake annotate")
15
+ execute "rake annotate"
16
16
  assert_equal File.read(asset_file 'foo_annotated_with_comments.rb' ), File.read(app_file 'foo.rb' )
17
17
  end
18
18
 
19
19
  test "updating column type" do
20
20
  FileUtils.cp asset_file('foo_annotated_bad_column.rb'), app_file('foo.rb')
21
- output = execute("cd #{$test_app} && rake annotate")
21
+ output = execute "rake annotate"
22
22
  assert_equal File.read(asset_file 'foo_annotated_column_fixed.rb' ), File.read(app_file 'foo.rb' )
23
23
  assert output.include?('M Foo#title [octopus -> string]')
24
24
  assert output.include?('M Foo#created_at [foobar -> datetime, not null]')
@@ -26,34 +26,44 @@ class AnnotatorTest < ActiveSupport::TestCase
26
26
 
27
27
  test "skipping when nodoc is preesnt" do
28
28
  FileUtils.cp asset_file('foo_annotated_bad_column_nodoc.rb'), app_file('foo.rb')
29
- execute("cd #{$test_app} && rake annotate")
29
+ execute "rake annotate"
30
30
  assert_equal File.read(asset_file 'foo_annotated_bad_column_nodoc.rb' ), File.read(app_file 'foo.rb' )
31
31
  end
32
32
 
33
33
  test "annotating devise columns" do
34
34
  assert_equal File.read(asset_file 'user_annotated.rb' ), File.read(app_file 'user.rb' )
35
- end
35
+ end
36
36
 
37
37
  test "annotating paperclip columns" do
38
38
  assert_equal File.read(asset_file 'paper_annotated.rb' ), File.read(app_file 'paper.rb' )
39
39
  end
40
40
 
41
- test "annotating belongs_to associations" do
41
+ test "annotating belongs_to and polymorphic associations" do
42
42
  assert_equal File.read(asset_file 'boo_annotated.rb' ), File.read(app_file 'boo.rb' )
43
43
  end
44
44
 
45
+ test "handling some code before annotitions block" do
46
+ FileUtils.cp asset_file('foo_require_first.rb'), app_file('foo.rb')
47
+ execute "rake annotate"
48
+ assert_equal File.read(asset_file 'foo_require_first.rb' ), File.read(app_file 'foo.rb' )
49
+ end
50
+
51
+ test "annotating namespaced models" do
52
+ assert_equal File.read(asset_file 'moo_hoo_annotated.rb' ), File.read(app_file 'moo/hoo.rb' )
53
+ end
54
+
45
55
  def asset_file(name)
46
56
  File.join(File.expand_path("../assets/", __FILE__), name)
47
57
  end
48
58
 
49
59
  def app_file(name)
50
- File.join($test_app,'app','models',name)
60
+ File.join(TestApp.path,'app','models',name)
51
61
  end
52
62
 
53
63
  # Check exit code while grabbing output
54
64
  def execute(command)
55
65
  tmp = Tempfile.new "output"
56
- assert system("#{command} > #{tmp.path}")
66
+ assert system("cd #{TestApp.path} && #{command} > #{tmp.path}")
57
67
  output = tmp.read
58
68
  tmp.unlink
59
69
  output
@@ -1,8 +1,11 @@
1
1
  # Attributes:
2
2
  # * id [integer, primary, not null] - primary key
3
3
  # * created_at [datetime, not null] - creation time
4
- # * foo_id [integer] - belongs to Foo
4
+ # * foo_id [integer] - belongs to :foo
5
+ # * poly_id [integer] - belongs to :poly (polymorphic)
6
+ # * poly_type [string] - belongs to :poly (polymorphic)
5
7
  # * updated_at [datetime, not null] - last update time
6
8
  class Boo < ActiveRecord::Base
7
9
  belongs_to :foo
10
+ belongs_to :poly, :polymorphic => true
8
11
  end
@@ -0,0 +1,11 @@
1
+ require 'pp'
2
+
3
+ # Attributes:
4
+ # * id [integer, primary, not null] - primary key
5
+ # * body [text]
6
+ # * created_at [datetime, not null] - creation time
7
+ # * random_number [integer] - TODO: document me
8
+ # * title [string]
9
+ # * updated_at [datetime, not null] - last update time
10
+ class Foo < ActiveRecord::Base
11
+ end
@@ -0,0 +1,13 @@
1
+ # Attributes:
2
+ # * id [integer, primary, not null] - primary key
3
+ # * body [text]
4
+ # * created_at [datetime, not null] - creation time
5
+ # * random_number [integer] - TODO: document me
6
+ # * title [string]
7
+ # * updated_at [datetime, not null] - last update time
8
+ # Some existing stupid comment
9
+ module Moo
10
+ class Hoo < ActiveRecord::Base
11
+ self.table_name = 'foos'
12
+ end
13
+ end
@@ -1,3 +1,4 @@
1
1
  class Boo < ActiveRecord::Base
2
2
  belongs_to :foo
3
+ belongs_to :poly, :polymorphic => true
3
4
  end
@@ -0,0 +1,6 @@
1
+ # Some existing stupid comment
2
+ module Moo
3
+ class Hoo < ActiveRecord::Base
4
+ self.table_name = 'foos'
5
+ end
6
+ end
Binary file
@@ -2,6 +2,8 @@ class CreateBoos < ActiveRecord::Migration
2
2
  def change
3
3
  create_table :boos do |t|
4
4
  t.references :foo
5
+ t.integer :poly_id
6
+ t.string :poly_type
5
7
  t.timestamps
6
8
  end
7
9
  end
@@ -11,7 +11,15 @@
11
11
  #
12
12
  # It's strongly recommended to check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(:version => 20120527020350) do
14
+ ActiveRecord::Schema.define(:version => 20120527025142) do
15
+
16
+ create_table "boos", :force => true do |t|
17
+ t.integer "foo_id"
18
+ t.integer "poly_id"
19
+ t.string "poly_type"
20
+ t.datetime "created_at", :null => false
21
+ t.datetime "updated_at", :null => false
22
+ end
15
23
 
16
24
  create_table "foos", :force => true do |t|
17
25
  t.text "body"
@@ -21,6 +29,15 @@ ActiveRecord::Schema.define(:version => 20120527020350) do
21
29
  t.datetime "updated_at", :null => false
22
30
  end
23
31
 
32
+ create_table "papers", :force => true do |t|
33
+ t.datetime "created_at", :null => false
34
+ t.datetime "updated_at", :null => false
35
+ t.string "avatar_file_name"
36
+ t.string "avatar_content_type"
37
+ t.integer "avatar_file_size"
38
+ t.datetime "avatar_updated_at"
39
+ end
40
+
24
41
  create_table "users", :force => true do |t|
25
42
  t.string "email", :default => "", :null => false
26
43
  t.string "encrypted_password", :default => "", :null => false
@@ -71,3 +71,100 @@ Migrating to DeviseCreateUsers (20120527020350)
71
71
   (0.0ms) PRAGMA index_info('index_users_on_confirmation_token')
72
72
   (0.0ms) PRAGMA index_info('index_users_on_reset_password_token')
73
73
   (0.0ms) PRAGMA index_info('index_users_on_email')
74
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" 
75
+ Migrating to CreateFoos (20120219112425)
76
+ Migrating to DeviseCreateUsers (20120527020350)
77
+ Migrating to CreatePapers (20120527023350)
78
+  (0.0ms) select sqlite_version(*)
79
+  (0.0ms) begin transaction
80
+  (0.2ms) CREATE TABLE "papers" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
81
+  (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20120527023350')
82
+  (5.4ms) commit transaction
83
+ Migrating to AddAttachmentAvatarToPapers (20120527023417)
84
+  (0.0ms) begin transaction
85
+  (0.3ms) ALTER TABLE "papers" ADD "avatar_file_name" varchar(255)
86
+  (0.2ms) ALTER TABLE "papers" ADD "avatar_content_type" varchar(255)
87
+  (0.2ms) ALTER TABLE "papers" ADD "avatar_file_size" integer
88
+  (0.2ms) ALTER TABLE "papers" ADD "avatar_updated_at" datetime
89
+  (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20120527023417')
90
+  (3.8ms) commit transaction
91
+ Migrating to CreateBoos (20120527025142)
92
+  (0.0ms) begin transaction
93
+  (0.4ms) CREATE TABLE "boos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "foo_id" integer, "poly_id" integer, "poly_type" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) 
94
+  (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20120527025142')
95
+  (4.0ms) commit transaction
96
+  (0.4ms) select sqlite_version(*)
97
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" 
98
+  (0.0ms) PRAGMA index_list("boos")
99
+  (0.0ms) PRAGMA index_list("foos")
100
+  (0.0ms) PRAGMA index_list("papers")
101
+  (0.1ms) PRAGMA index_list("users")
102
+  (0.1ms) PRAGMA index_info('index_users_on_authentication_token')
103
+  (0.1ms) PRAGMA index_info('index_users_on_unlock_token')
104
+  (0.0ms) PRAGMA index_info('index_users_on_confirmation_token')
105
+  (0.1ms) PRAGMA index_info('index_users_on_reset_password_token')
106
+  (0.0ms) PRAGMA index_info('index_users_on_email')
107
+  (0.1ms) select sqlite_version(*)
108
+  (14.9ms) CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
109
+  (0.0ms) PRAGMA index_list("schema_migrations")
110
+  (4.1ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
111
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations" 
112
+ Migrating to CreateFoos (20120219112425)
113
+  (0.0ms) begin transaction
114
+  (0.4ms) CREATE TABLE "foos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "body" text, "title" varchar(255), "random_number" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) 
115
+  (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20120219112425')
116
+  (7.1ms) commit transaction
117
+ Migrating to DeviseCreateUsers (20120527020350)
118
+  (0.0ms) begin transaction
119
+  (0.4ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255) DEFAULT '' NOT NULL, "encrypted_password" varchar(255) DEFAULT '' NOT NULL, "reset_password_token" varchar(255), "reset_password_sent_at" datetime, "remember_created_at" datetime, "sign_in_count" integer DEFAULT 0, "current_sign_in_at" datetime, "last_sign_in_at" datetime, "current_sign_in_ip" varchar(255), "last_sign_in_ip" varchar(255), "password_salt" varchar(255), "confirmation_token" varchar(255), "confirmed_at" datetime, "confirmation_sent_at" datetime, "unconfirmed_email" varchar(255), "failed_attempts" integer DEFAULT 0, "unlock_token" varchar(255), "locked_at" datetime, "authentication_token" varchar(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) 
120
+  (0.0ms) PRAGMA index_list("users")
121
+  (0.3ms) CREATE UNIQUE INDEX "index_users_on_email" ON "users" ("email")
122
+  (0.1ms) PRAGMA index_list("users")
123
+  (0.0ms) PRAGMA index_info('index_users_on_email')
124
+  (0.2ms) CREATE UNIQUE INDEX "index_users_on_reset_password_token" ON "users" ("reset_password_token")
125
+  (0.1ms) PRAGMA index_list("users")
126
+  (0.1ms) PRAGMA index_info('index_users_on_reset_password_token')
127
+  (0.0ms) PRAGMA index_info('index_users_on_email')
128
+  (0.2ms) CREATE UNIQUE INDEX "index_users_on_confirmation_token" ON "users" ("confirmation_token")
129
+  (0.1ms) PRAGMA index_list("users")
130
+  (0.1ms) PRAGMA index_info('index_users_on_confirmation_token')
131
+  (0.0ms) PRAGMA index_info('index_users_on_reset_password_token')
132
+  (0.0ms) PRAGMA index_info('index_users_on_email')
133
+  (0.2ms) CREATE UNIQUE INDEX "index_users_on_unlock_token" ON "users" ("unlock_token")
134
+  (0.1ms) PRAGMA index_list("users")
135
+  (0.1ms) PRAGMA index_info('index_users_on_unlock_token')
136
+  (0.0ms) PRAGMA index_info('index_users_on_confirmation_token')
137
+  (0.0ms) PRAGMA index_info('index_users_on_reset_password_token')
138
+  (0.0ms) PRAGMA index_info('index_users_on_email')
139
+  (0.2ms) CREATE UNIQUE INDEX "index_users_on_authentication_token" ON "users" ("authentication_token")
140
+  (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20120527020350')
141
+  (3.8ms) commit transaction
142
+ Migrating to CreatePapers (20120527023350)
143
+  (0.0ms) begin transaction
144
+  (0.2ms) CREATE TABLE "papers" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) 
145
+  (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20120527023350')
146
+  (3.8ms) commit transaction
147
+ Migrating to AddAttachmentAvatarToPapers (20120527023417)
148
+  (0.0ms) begin transaction
149
+  (0.3ms) ALTER TABLE "papers" ADD "avatar_file_name" varchar(255)
150
+  (0.1ms) ALTER TABLE "papers" ADD "avatar_content_type" varchar(255)
151
+  (0.2ms) ALTER TABLE "papers" ADD "avatar_file_size" integer
152
+  (0.2ms) ALTER TABLE "papers" ADD "avatar_updated_at" datetime
153
+  (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20120527023417')
154
+  (3.2ms) commit transaction
155
+ Migrating to CreateBoos (20120527025142)
156
+  (0.0ms) begin transaction
157
+  (0.3ms) CREATE TABLE "boos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "foo_id" integer, "poly_id" integer, "poly_type" varchar(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
158
+  (0.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20120527025142')
159
+  (3.7ms) commit transaction
160
+  (0.4ms) select sqlite_version(*)
161
+  (0.1ms) SELECT "schema_migrations"."version" FROM "schema_migrations"
162
+  (0.0ms) PRAGMA index_list("boos")
163
+  (0.0ms) PRAGMA index_list("foos")
164
+  (0.0ms) PRAGMA index_list("papers")
165
+  (0.0ms) PRAGMA index_list("users")
166
+  (0.0ms) PRAGMA index_info('index_users_on_authentication_token')
167
+  (0.0ms) PRAGMA index_info('index_users_on_unlock_token')
168
+  (0.0ms) PRAGMA index_info('index_users_on_confirmation_token')
169
+  (0.0ms) PRAGMA index_info('index_users_on_reset_password_token')
170
+  (0.0ms) PRAGMA index_info('index_users_on_email')
@@ -0,0 +1,19 @@
1
+ module TestApp
2
+
3
+ # No mattr_accessor before initialization ;(
4
+ def self.path=(new_path)
5
+ @path = new_path
6
+ end
7
+
8
+ def self.path
9
+ @path
10
+ end
11
+
12
+ def self.prepare!
13
+ self.path = File.expand_path("../../../tmp/dummy", __FILE__)
14
+ FileUtils.rm_rf path
15
+ FileUtils.mkdir_p path
16
+ FileUtils.cp_r File.expand_path("../../dummy//", __FILE__), File.expand_path(path+"/../")
17
+ system("cd #{path} && bundle exec rake db:migrate > /dev/null")
18
+ end
19
+ end
data/test/test_helper.rb CHANGED
@@ -3,17 +3,13 @@ require 'fileutils'
3
3
  # Configure Rails Environment
4
4
  ENV["RAILS_ENV"] = "test"
5
5
 
6
- $test_app = test_app_dir = File.expand_path("../../tmp/dummy", __FILE__)
7
- FileUtils.rm_rf test_app_dir
8
- FileUtils.mkdir_p test_app_dir
9
- FileUtils.cp_r File.expand_path("../dummy//", __FILE__), File.expand_path(test_app_dir+"/../")
10
- system("cd #{$test_app} && bundle exec rake db:migrate > /dev/null")
11
-
6
+ # Load support files
7
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
8
+
9
+ TestApp.prepare!
12
10
 
13
- require File.expand_path("#{test_app_dir}/config/environment.rb", __FILE__)
11
+ require File.expand_path("#{TestApp.path}/config/environment.rb", __FILE__)
14
12
  require "rails/test_help"
15
13
 
16
14
  Rails.backtrace_cleaner.remove_silencers!
17
15
 
18
- # Load support files
19
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: annotator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-05-27 00:00:00.000000000 Z
13
+ date: 2012-06-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -53,11 +53,20 @@ extra_rdoc_files: []
53
53
  files:
54
54
  - lib/tasks/annotator_tasks.rake
55
55
  - lib/annotator.rb
56
+ - lib/annotator/initial_description/belongs_to.rb
57
+ - lib/annotator/initial_description/devise.rb
58
+ - lib/annotator/initial_description/paperclip.rb
59
+ - lib/annotator/initial_description/base.rb
60
+ - lib/annotator/initial_description/rails.rb
61
+ - lib/annotator/model.rb
56
62
  - lib/annotator/version.rb
63
+ - lib/annotator/attributes.rb
64
+ - lib/annotator/initial_description.rb
57
65
  - lib/annotator/railtie.rb
58
66
  - MIT-LICENSE
59
67
  - Rakefile
60
68
  - README.rdoc
69
+ - test/support/test_app.rb
61
70
  - test/test_helper.rb
62
71
  - test/assets/paper_annotated.rb
63
72
  - test/assets/foo_annotated_bad_column.rb
@@ -67,6 +76,8 @@ files:
67
76
  - test/assets/boo_annotated.rb
68
77
  - test/assets/foo_annotated.rb
69
78
  - test/assets/foo_annotated_column_fixed.rb
79
+ - test/assets/foo_require_first.rb
80
+ - test/assets/moo_hoo_annotated.rb
70
81
  - test/annotator_test.rb
71
82
  - test/dummy/public/500.html
72
83
  - test/dummy/public/favicon.ico
@@ -93,6 +104,7 @@ files:
93
104
  - test/dummy/app/helpers/application_helper.rb
94
105
  - test/dummy/app/models/boo.rb
95
106
  - test/dummy/app/models/paper.rb
107
+ - test/dummy/app/models/moo/hoo.rb
96
108
  - test/dummy/app/models/user.rb
97
109
  - test/dummy/app/models/foo.rb
98
110
  - test/dummy/app/models/nomodel.rb
@@ -138,11 +150,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
150
  version: '0'
139
151
  requirements: []
140
152
  rubyforge_project:
141
- rubygems_version: 1.8.24
153
+ rubygems_version: 1.8.23
142
154
  signing_key:
143
155
  specification_version: 3
144
156
  summary: Annotate your models and keep your comments about fields.
145
157
  test_files:
158
+ - test/support/test_app.rb
146
159
  - test/test_helper.rb
147
160
  - test/assets/paper_annotated.rb
148
161
  - test/assets/foo_annotated_bad_column.rb
@@ -152,6 +165,8 @@ test_files:
152
165
  - test/assets/boo_annotated.rb
153
166
  - test/assets/foo_annotated.rb
154
167
  - test/assets/foo_annotated_column_fixed.rb
168
+ - test/assets/foo_require_first.rb
169
+ - test/assets/moo_hoo_annotated.rb
155
170
  - test/annotator_test.rb
156
171
  - test/dummy/public/500.html
157
172
  - test/dummy/public/favicon.ico
@@ -178,6 +193,7 @@ test_files:
178
193
  - test/dummy/app/helpers/application_helper.rb
179
194
  - test/dummy/app/models/boo.rb
180
195
  - test/dummy/app/models/paper.rb
196
+ - test/dummy/app/models/moo/hoo.rb
181
197
  - test/dummy/app/models/user.rb
182
198
  - test/dummy/app/models/foo.rb
183
199
  - test/dummy/app/models/nomodel.rb