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.
Files changed (49) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +4 -0
  4. data/.yardopts +1 -0
  5. data/CHANGELOG.md +25 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +22 -0
  8. data/README.md +85 -0
  9. data/Rakefile +25 -0
  10. data/annotated-rails.gemspec +28 -0
  11. data/bin/annotate-rails +30 -0
  12. data/lib/annotated/models.rb +187 -0
  13. data/lib/annotated/version.rb +3 -0
  14. data/lib/annotated-rails.rb +2 -0
  15. data/spec/annotated/models/annotator_spec.rb +46 -0
  16. data/spec/annotated/models_spec.rb +184 -0
  17. data/spec/dummy/.gitignore +3 -0
  18. data/spec/dummy/README.rdoc +1 -0
  19. data/spec/dummy/Rakefile +7 -0
  20. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  21. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  22. data/spec/dummy/app/models/.gitkeep +0 -0
  23. data/spec/dummy/app/models/post.rb +2 -0
  24. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  25. data/spec/dummy/config/application.rb +55 -0
  26. data/spec/dummy/config/boot.rb +10 -0
  27. data/spec/dummy/config/database.yml +25 -0
  28. data/spec/dummy/config/environment.rb +5 -0
  29. data/spec/dummy/config/environments/development.rb +37 -0
  30. data/spec/dummy/config/environments/production.rb +67 -0
  31. data/spec/dummy/config/environments/test.rb +37 -0
  32. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  33. data/spec/dummy/config/initializers/inflections.rb +15 -0
  34. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  35. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  36. data/spec/dummy/config/initializers/session_store.rb +8 -0
  37. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  38. data/spec/dummy/config/routes.rb +2 -0
  39. data/spec/dummy/config.ru +4 -0
  40. data/spec/dummy/db/schema.rb +34 -0
  41. data/spec/dummy/log/.gitkeep +0 -0
  42. data/spec/dummy/public/404.html +26 -0
  43. data/spec/dummy/public/422.html +26 -0
  44. data/spec/dummy/public/500.html +25 -0
  45. data/spec/dummy/public/favicon.ico +0 -0
  46. data/spec/dummy/script/rails +6 -0
  47. data/spec/spec_helper.rb +27 -0
  48. data/spec/support/stub_file.rb +25 -0
  49. metadata +207 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .rvmrc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
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
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in annotate-rails.gemspec
4
+ gemspec
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 [![Build Status](http://travis-ci.org/kucaahbe/annotated-rails.png)](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
@@ -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,3 @@
1
+ module Annotated
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,2 @@
1
+ # I have nothing to load here,
2
+ # it's for bundler, maybe...
@@ -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,3 @@
1
+ db/*.sqlite3
2
+ log
3
+ test
@@ -0,0 +1 @@
1
+ This is a dummy rails application for testing purposes