annotated-rails 0.0.1
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/.gitignore +18 -0
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +25 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +85 -0
- data/Rakefile +25 -0
- data/annotated-rails.gemspec +28 -0
- data/bin/annotate-rails +30 -0
- data/lib/annotated/models.rb +187 -0
- data/lib/annotated/version.rb +3 -0
- data/lib/annotated-rails.rb +2 -0
- data/spec/annotated/models/annotator_spec.rb +46 -0
- data/spec/annotated/models_spec.rb +184 -0
- data/spec/dummy/.gitignore +3 -0
- data/spec/dummy/README.rdoc +1 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/post.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +55 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/schema.rb +34 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/stub_file.rb +25 -0
- metadata +207 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--no-private --files CHANGELOG.md
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
TODO
|
2
|
+
----
|
3
|
+
|
4
|
+
* rake task(rake annotate)
|
5
|
+
* add exception handling for "bad" models:
|
6
|
+
|
7
|
+
Annotaiting GoodModel BadModel(failed)
|
8
|
+
BadModel exception:
|
9
|
+
bla/bla/bla
|
10
|
+
bla
|
11
|
+
|
12
|
+
current(master)
|
13
|
+
---------------
|
14
|
+
|
15
|
+
nothing here yet
|
16
|
+
|
17
|
+
0.0.1
|
18
|
+
-----
|
19
|
+
|
20
|
+
what in the box:
|
21
|
+
|
22
|
+
* annotation for table and indexes
|
23
|
+
* binary file with annotation/denotation ability
|
24
|
+
* abstract class ignoring
|
25
|
+
* NO trailing characters
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 kucaahbe
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# annotated-rails [](http://travis-ci.org/kucaahbe/annotated-rails)
|
2
|
+
|
3
|
+
Provides schema annotation for your models.
|
4
|
+
|
5
|
+
Like this:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
class Post < ActiveRecord::Base
|
9
|
+
...
|
10
|
+
end
|
11
|
+
#--
|
12
|
+
# generated by 'annotated-rails' gem, please do not remove this line and content below, instead use `bundle exec annotate-rails -d` command
|
13
|
+
#++
|
14
|
+
# Table name: posts
|
15
|
+
#
|
16
|
+
# * id :integer not null
|
17
|
+
# title :string(30)
|
18
|
+
# content :text
|
19
|
+
# slug :string(255) not null
|
20
|
+
# author_name :string(255)
|
21
|
+
# comments_count :integer default 0
|
22
|
+
# created_at :datetime not null
|
23
|
+
# updated_at :datetime not null
|
24
|
+
#
|
25
|
+
# Indexes:
|
26
|
+
# index_posts_on_slug slug
|
27
|
+
#--
|
28
|
+
# generated by 'annotated-rails' gem, please do not remove this line and content above, instead use `bundle exec annotate-rails -d` command
|
29
|
+
#++
|
30
|
+
```
|
31
|
+
|
32
|
+
Inspired by [ctran/annotate_models](http://github.com/ctran/annotate_models)
|
33
|
+
|
34
|
+
For using with <strong>3.x rails</strong>, do not tested against earlier versions.
|
35
|
+
|
36
|
+
## Installation
|
37
|
+
|
38
|
+
Add this line to your rails Gemfile:
|
39
|
+
|
40
|
+
group :development do
|
41
|
+
gem 'annotated-rails'
|
42
|
+
end
|
43
|
+
|
44
|
+
And then execute:
|
45
|
+
|
46
|
+
$ bundle
|
47
|
+
|
48
|
+
Or install it yourself as:
|
49
|
+
|
50
|
+
$ gem install annotated-rails
|
51
|
+
|
52
|
+
## Usage
|
53
|
+
|
54
|
+
To annotate:
|
55
|
+
|
56
|
+
bundle exec annotate-rails
|
57
|
+
|
58
|
+
To remove annotation:
|
59
|
+
|
60
|
+
bundle exec annotate-rails -d
|
61
|
+
|
62
|
+
To see CLI help:
|
63
|
+
|
64
|
+
bundle exec annotate-rails -h|--help
|
65
|
+
|
66
|
+
## Future plans
|
67
|
+
|
68
|
+
* look at the CHANGELOG for what is going to be done
|
69
|
+
* add guard/something similar support
|
70
|
+
* add annotations for other things
|
71
|
+
|
72
|
+
## Testing
|
73
|
+
|
74
|
+
* clone
|
75
|
+
* bundle
|
76
|
+
* rake
|
77
|
+
|
78
|
+
## Contributing
|
79
|
+
|
80
|
+
1. Fork it
|
81
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
82
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
83
|
+
4. Add tests for your changes
|
84
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
85
|
+
6. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
task :default => :spec
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
8
|
+
t.rspec_opts='--tag ~wip'
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace :spec do
|
12
|
+
RSpec::Core::RakeTask.new(:wip) do |t|
|
13
|
+
t.rspec_opts='--tag wip'
|
14
|
+
t.fail_on_error = false
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec::Core::RakeTask.new(:rcov) do |t|
|
18
|
+
t.rspec_opts=['-r simplecov']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Validate the gemspec"
|
23
|
+
task :gemspec do
|
24
|
+
eval(File.read(Dir["*.gemspec"].first)).validate && puts('gemspec valid')
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/annotated/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["kucaahbe"]
|
6
|
+
gem.email = ["kucaahbe@ukr.net"]
|
7
|
+
gem.description = %q{Y.a. Rails models annotation}
|
8
|
+
gem.summary = gem.description+%q{inspired by annotate_models gem}
|
9
|
+
gem.homepage = "http://github.com/kucaahbe/annotated-rails"
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
gem.name = "annotated-rails"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.bindir = 'bin'
|
17
|
+
gem.executables << 'annotate-rails'
|
18
|
+
gem.version = Annotated::VERSION
|
19
|
+
|
20
|
+
gem.add_runtime_dependency 'activerecord', '>= 3.0.0'
|
21
|
+
|
22
|
+
gem.add_development_dependency 'rspec', '~> 2.8.0'
|
23
|
+
gem.add_development_dependency 'rspec-rails', '~> 2.8.0'
|
24
|
+
gem.add_development_dependency 'rails', '~> 3.2.0'
|
25
|
+
gem.add_development_dependency 'sqlite3'
|
26
|
+
gem.add_development_dependency 'yard'
|
27
|
+
gem.add_development_dependency 'bluecloth'
|
28
|
+
end
|
data/bin/annotate-rails
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
options = {}
|
6
|
+
OptionParser.new do |opts|
|
7
|
+
opts.banner = "Usage: annotate-rails [options]"
|
8
|
+
|
9
|
+
opts.separator ""
|
10
|
+
|
11
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
12
|
+
options[:verbose] = v
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on("-d", "--delete", "Delete annotations") do |d|
|
16
|
+
options[:delete] = d
|
17
|
+
end
|
18
|
+
end.parse!
|
19
|
+
|
20
|
+
ENV['ANN_CLI']='true'
|
21
|
+
print 'Loading rails environment: '
|
22
|
+
require './config/environment'
|
23
|
+
puts 'done.'
|
24
|
+
require 'annotated/models'
|
25
|
+
|
26
|
+
if options.delete(:delete)
|
27
|
+
Annotated::Models.instance.denotate!
|
28
|
+
else
|
29
|
+
Annotated::Models.instance.annotate!(options)
|
30
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
# {include:file:README.md}
|
4
|
+
module Annotated
|
5
|
+
|
6
|
+
# @private
|
7
|
+
module Helpers
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def puts_message msg
|
12
|
+
puts msg if ENV['ANN_CLI']
|
13
|
+
end
|
14
|
+
|
15
|
+
def print_message msg
|
16
|
+
print msg if ENV['ANN_CLI']
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def debug?
|
22
|
+
@debug ||= ENV.has_key?('ANN_DEBUG')
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class Models
|
28
|
+
|
29
|
+
# @private
|
30
|
+
class Annotator
|
31
|
+
|
32
|
+
include Helpers
|
33
|
+
|
34
|
+
def initialize model_const, model_file_full_path
|
35
|
+
@model, @path = model_const, model_file_full_path
|
36
|
+
@annotatable = true
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :path, :model
|
40
|
+
|
41
|
+
def annotatable? # I'm not sure is this a right word...
|
42
|
+
make_annotation!
|
43
|
+
@annotatable
|
44
|
+
end
|
45
|
+
|
46
|
+
def annotation
|
47
|
+
make_annotation!
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_regexp
|
51
|
+
/\z/
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove_regexp
|
55
|
+
border = '# '+STRONG_ANNOTATION
|
56
|
+
border.gsub!(' ', '\s')
|
57
|
+
border.gsub!('#', '\#')
|
58
|
+
%r{\n(\#--\n)?#{border}.+#{border}.*\n?(\#++)?}m
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def make_annotation!
|
64
|
+
return @annotatable=false if @model.abstract_class?
|
65
|
+
return @annotation if defined?(@annotation)
|
66
|
+
|
67
|
+
# TODO add exception handling inside this method to notify about broken models
|
68
|
+
table_name = @model.table_name.to_s
|
69
|
+
annotation_header = <<annheader
|
70
|
+
#--
|
71
|
+
# #{ANNOTATION % 'below'}
|
72
|
+
#++
|
73
|
+
annheader
|
74
|
+
annotation_footer = <<annfooter
|
75
|
+
|
76
|
+
#--
|
77
|
+
# #{ANNOTATION % 'above'}
|
78
|
+
#++
|
79
|
+
annfooter
|
80
|
+
annotation_table = []
|
81
|
+
|
82
|
+
# append table name:
|
83
|
+
annotation_table << "# Table name: #{table_name}"
|
84
|
+
annotation_table << '#'
|
85
|
+
column_with_maximum_name_length = @model.columns.map(&:name).max_by { |c| c.length }.length
|
86
|
+
|
87
|
+
@model.columns.each do |column|
|
88
|
+
column_limit = if column.type==:decimal && column.precision
|
89
|
+
"(#{[column.precision, column.scale].join(',')})"
|
90
|
+
else
|
91
|
+
column.limit ? "(#{column.limit})" : ''
|
92
|
+
end
|
93
|
+
|
94
|
+
other_column_attrs = []
|
95
|
+
other_column_attrs << NOT_NULL unless column.null
|
96
|
+
other_column_attrs << DEFAULT % column.default if column.default
|
97
|
+
|
98
|
+
annotation_table << sprintf(
|
99
|
+
%Q|# %s %-#{column_with_maximum_name_length+1}s:%-16s%s|,
|
100
|
+
column.primary && PRIMARY_KEY_MARK || ' ',
|
101
|
+
column.name,
|
102
|
+
column.type.to_s+column_limit,
|
103
|
+
other_column_attrs.join(',')
|
104
|
+
).rstrip
|
105
|
+
end
|
106
|
+
|
107
|
+
# annotating indexes if present
|
108
|
+
annotation_index = []
|
109
|
+
if (indexes = ActiveRecord::Base.connection.indexes(table_name)) and not indexes.empty?
|
110
|
+
annotation_index << "\n#"
|
111
|
+
annotation_index << "# Indexes:"
|
112
|
+
maximum_index_name_length = indexes.map(&:name).max_by { |c| c.length }.length
|
113
|
+
indexes.each do |index|
|
114
|
+
# todo add other index fields
|
115
|
+
annotation_index << sprintf(
|
116
|
+
"# %-#{maximum_index_name_length}s %s %s",
|
117
|
+
index.name,
|
118
|
+
index.columns.join(','),
|
119
|
+
index.unique ? 'unique' : ''
|
120
|
+
).rstrip
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
@annotation = annotation_header + annotation_table.join("\n") + annotation_index.join("\n") + annotation_footer
|
125
|
+
end
|
126
|
+
|
127
|
+
end # Annotator
|
128
|
+
|
129
|
+
include Singleton
|
130
|
+
include Helpers
|
131
|
+
|
132
|
+
STRONG_ANNOTATION = %q|generated by 'annotated-rails' gem|
|
133
|
+
ANNOTATION = %Q|#{STRONG_ANNOTATION}, please do not remove this line and content %s, instead use `bundle exec annotate-rails -d` command|
|
134
|
+
NOT_NULL = 'not null'
|
135
|
+
PRIMARY_KEY_MARK = '*'
|
136
|
+
DEFAULT = 'default %s'
|
137
|
+
|
138
|
+
def annotate! options = {}
|
139
|
+
print_message "Annotating: "
|
140
|
+
|
141
|
+
annotators.each do |annotator|
|
142
|
+
next unless annotator.annotatable?
|
143
|
+
|
144
|
+
print_message annotator.model.to_s+' '
|
145
|
+
|
146
|
+
content = File.read(annotator.path).gsub(annotator.remove_regexp, "\n")
|
147
|
+
content.gsub!(annotator.add_regexp, annotator.annotation)
|
148
|
+
|
149
|
+
write_file annotator.path, content
|
150
|
+
end
|
151
|
+
|
152
|
+
puts_message "\n"
|
153
|
+
end
|
154
|
+
|
155
|
+
def denotate!
|
156
|
+
annotators.each do |annotator|
|
157
|
+
content = File.read(annotator.path).gsub(annotator.remove_regexp, "\n")
|
158
|
+
write_file annotator.path, content
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def annotators
|
165
|
+
return @annotators if defined?(@annotators)
|
166
|
+
@annotators = []
|
167
|
+
|
168
|
+
begin
|
169
|
+
Dir[::Rails.root.join('app/models/','**/*.rb').to_s].each do |module_path|
|
170
|
+
require module_path
|
171
|
+
@annotators << Annotator.new(ActiveRecord::Base.descendants.last,module_path) # "last".method here, todo a better way for constants and file path's handling
|
172
|
+
end
|
173
|
+
rescue Exception => e
|
174
|
+
#puts e.inspect if debug?
|
175
|
+
end
|
176
|
+
|
177
|
+
@annotators # make sure we return annotators
|
178
|
+
end
|
179
|
+
|
180
|
+
protected
|
181
|
+
|
182
|
+
def write_file destination, content
|
183
|
+
File.open(destination, 'wb') { |file| file.write(content) }
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'annotated/models'
|
3
|
+
|
4
|
+
describe Annotated::Models::Annotator do
|
5
|
+
|
6
|
+
context "#path" do
|
7
|
+
it "should return file path" do
|
8
|
+
described_class.new(Post,'/path/to/post').path.should eq('/path/to/post')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "#annotation" do
|
13
|
+
|
14
|
+
it "should return annotation for Post" do
|
15
|
+
described_class.new(Post,'/path/to/post').annotation.should eq(<<-ANNOTATION)
|
16
|
+
#--
|
17
|
+
# generated by 'annotated-rails' gem, please do not remove this line and content below, instead use `bundle exec annotate-rails -d` command
|
18
|
+
#++
|
19
|
+
# Table name: posts
|
20
|
+
#
|
21
|
+
# * id :integer not null
|
22
|
+
# title :string(255)
|
23
|
+
# content :text
|
24
|
+
# some_long_named_column_bla_bla_bla_bla_bla :text
|
25
|
+
# author_name :string(10) not null
|
26
|
+
# comments_count :integer not null,default 0
|
27
|
+
# null_true :string(255)
|
28
|
+
# null_true_with_default :string(255) default bla
|
29
|
+
# decimal_column :decimal
|
30
|
+
# decimal_column_with_precision :integer(23)
|
31
|
+
# decimal_column_with_precision_and_scale :decimal(23,5)
|
32
|
+
# decimal_column_with_scale :decimal
|
33
|
+
# created_at :datetime not null
|
34
|
+
# updated_at :datetime not null
|
35
|
+
#
|
36
|
+
# Indexes:
|
37
|
+
# index_posts_on_author_name author_name
|
38
|
+
#--
|
39
|
+
# generated by 'annotated-rails' gem, please do not remove this line and content above, instead use `bundle exec annotate-rails -d` command
|
40
|
+
#++
|
41
|
+
ANNOTATION
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'annotated/models'
|
3
|
+
|
4
|
+
describe Annotated::Models do
|
5
|
+
|
6
|
+
subject { Annotated::Models.instance }
|
7
|
+
|
8
|
+
let(:annotator) { Annotated::Models::Annotator }
|
9
|
+
|
10
|
+
before :all do
|
11
|
+
User = Class.new
|
12
|
+
Avatar = Class.new
|
13
|
+
end
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
StubFile.clear!
|
17
|
+
end
|
18
|
+
|
19
|
+
context "#annotate!" do
|
20
|
+
|
21
|
+
it "must annotate all models" do
|
22
|
+
annotator.any_instance.stub(:make_annotation!)
|
23
|
+
|
24
|
+
subject.should_receive(:annotators).
|
25
|
+
and_return(
|
26
|
+
annotators=[annotator.new(User,'path1'),annotator.new(Avatar,'path2')]
|
27
|
+
)
|
28
|
+
annotators.each { |a| a.should_receive(:annotation).and_return('String') }
|
29
|
+
|
30
|
+
File.should_receive(:read).with('path1').and_return((user_file=StubFile.new(<<-USER,'path1')).content)
|
31
|
+
class User < ActiveRecord::Base
|
32
|
+
end
|
33
|
+
USER
|
34
|
+
File.should_receive(:read).with('path2').and_return((avatar_file=StubFile.new(<<-AVATAR,'path2')).content)
|
35
|
+
class Avatar < ActiveRecord::Base
|
36
|
+
end
|
37
|
+
AVATAR
|
38
|
+
File.stub(:open) do |path,mode,block|
|
39
|
+
StubFile.open path, mode, &block
|
40
|
+
end
|
41
|
+
|
42
|
+
subject.annotate!
|
43
|
+
|
44
|
+
user_file.content.should eq((<<-TEXT).chomp)
|
45
|
+
class User < ActiveRecord::Base
|
46
|
+
end
|
47
|
+
String
|
48
|
+
TEXT
|
49
|
+
avatar_file.content.should eq((<<-TEXT).chomp)
|
50
|
+
class Avatar < ActiveRecord::Base
|
51
|
+
end
|
52
|
+
String
|
53
|
+
TEXT
|
54
|
+
end
|
55
|
+
|
56
|
+
it "must not annotate abstract AR classes" do
|
57
|
+
SomeBase = Class.new
|
58
|
+
|
59
|
+
SomeBase.should_receive(:abstract_class?) { true }
|
60
|
+
|
61
|
+
subject.should_receive(:annotators).and_return(annotators=[annotator.new(SomeBase,'some_base_model_path')])
|
62
|
+
|
63
|
+
File.should_not_receive(:read).with('some_base_model_path')
|
64
|
+
|
65
|
+
subject.annotate!
|
66
|
+
end
|
67
|
+
|
68
|
+
it "must annotate file using one write operation" do
|
69
|
+
LalaClass = Class.new
|
70
|
+
annotator.any_instance.stub(:make_annotation!)
|
71
|
+
|
72
|
+
subject.should_receive(:annotators).
|
73
|
+
and_return(
|
74
|
+
annotators=[annotator.new(LalaClass,'lala_path')]
|
75
|
+
)
|
76
|
+
annotators.each { |a| a.should_receive(:annotation).and_return('String') }
|
77
|
+
|
78
|
+
File.should_receive(:read).with('lala_path').once.and_return('file_content')
|
79
|
+
File.should_receive(:open).with('lala_path','wb').once
|
80
|
+
|
81
|
+
subject.annotate!
|
82
|
+
end
|
83
|
+
|
84
|
+
it "must be able to renotate" do
|
85
|
+
annotator.any_instance.stub(:make_annotation!)
|
86
|
+
|
87
|
+
subject.should_receive(:annotators).
|
88
|
+
and_return(
|
89
|
+
annotators=[annotator.new(User,'path1'),annotator.new(Avatar,'path2')]
|
90
|
+
)
|
91
|
+
annotators.each { |a| a.should_receive(:annotation).and_return('NewAnnotation') }
|
92
|
+
|
93
|
+
File.should_receive(:read).with('path1').and_return((user_file=StubFile.new(<<-USER,'path1')).content)
|
94
|
+
class User < ActiveRecord::Base
|
95
|
+
end
|
96
|
+
#--
|
97
|
+
# generated by 'annotated-rails' gem dfg dfg
|
98
|
+
#++
|
99
|
+
#old
|
100
|
+
# annotation
|
101
|
+
# text
|
102
|
+
#--
|
103
|
+
# generated by 'annotated-rails' gem dfg dfg
|
104
|
+
#++
|
105
|
+
USER
|
106
|
+
File.should_receive(:read).with('path2').and_return((avatar_file=StubFile.new(<<-AVATAR,'path2')).content)
|
107
|
+
class Avatar < ActiveRecord::Base
|
108
|
+
end
|
109
|
+
#--
|
110
|
+
# generated by 'annotated-rails' gem dfg dfg
|
111
|
+
#++
|
112
|
+
# another old
|
113
|
+
# annotation asd
|
114
|
+
# text lolo
|
115
|
+
#--
|
116
|
+
# generated by 'annotated-rails' gem dfg dfg
|
117
|
+
#++
|
118
|
+
AVATAR
|
119
|
+
File.stub(:open) do |path,mode,block|
|
120
|
+
StubFile.open path, mode, &block
|
121
|
+
end
|
122
|
+
|
123
|
+
subject.annotate!
|
124
|
+
|
125
|
+
user_file.content.should eq((<<-TEXT).chomp)
|
126
|
+
class User < ActiveRecord::Base
|
127
|
+
end
|
128
|
+
NewAnnotation
|
129
|
+
TEXT
|
130
|
+
avatar_file.content.should eq((<<-TEXT).chomp)
|
131
|
+
class Avatar < ActiveRecord::Base
|
132
|
+
end
|
133
|
+
NewAnnotation
|
134
|
+
TEXT
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
context "#denotate!" do
|
140
|
+
|
141
|
+
it "must denotate all models" do
|
142
|
+
subject.should_receive(:annotators).and_return(annotators=[annotator.new(User,'path1'),annotator.new(Avatar,'path2')])
|
143
|
+
|
144
|
+
File.should_receive(:read).with('path1').and_return((user_file=StubFile.new(<<-USER,'path1')).content)
|
145
|
+
class User < ActiveRecord::Base
|
146
|
+
end
|
147
|
+
# generated by 'annotated-rails' gem asdasd
|
148
|
+
# blabla
|
149
|
+
# generated
|
150
|
+
#text
|
151
|
+
# generated by 'annotated-rails' gem gdfgdfgdfg
|
152
|
+
USER
|
153
|
+
File.should_receive(:read).with('path2').and_return((avatar_file=StubFile.new(<<-AVATAR,'path2')).content)
|
154
|
+
class Avatar < ActiveRecord::Base
|
155
|
+
end
|
156
|
+
#--
|
157
|
+
# generated by 'annotated-rails' gem dfg dfg
|
158
|
+
#++
|
159
|
+
# blabla
|
160
|
+
# generated
|
161
|
+
#text
|
162
|
+
#--
|
163
|
+
# generated by 'annotated-rails' gem dfg dfg
|
164
|
+
#++
|
165
|
+
AVATAR
|
166
|
+
File.stub(:open) do |path,mode,block|
|
167
|
+
StubFile.open path, mode, &block
|
168
|
+
end
|
169
|
+
|
170
|
+
subject.denotate!
|
171
|
+
|
172
|
+
user_file.content.should eq((<<-TEXT))
|
173
|
+
class User < ActiveRecord::Base
|
174
|
+
end
|
175
|
+
TEXT
|
176
|
+
avatar_file.content.should eq(z=(<<-TEXT))
|
177
|
+
class Avatar < ActiveRecord::Base
|
178
|
+
end
|
179
|
+
TEXT
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
This is a dummy rails application for testing purposes
|