synvert 0.0.17 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/CHANGELOG.md +4 -0
  4. data/README.md +7 -26
  5. data/bin/synvert +0 -1
  6. data/lib/synvert/cli.rb +26 -14
  7. data/lib/synvert/snippet.rb +17 -0
  8. data/lib/synvert/version.rb +1 -1
  9. data/lib/synvert.rb +3 -11
  10. data/synvert.gemspec +2 -3
  11. metadata +6 -85
  12. data/lib/synvert/configuration.rb +0 -25
  13. data/lib/synvert/exceptions.rb +0 -13
  14. data/lib/synvert/node_ext.rb +0 -319
  15. data/lib/synvert/rewriter/action.rb +0 -224
  16. data/lib/synvert/rewriter/condition.rb +0 -56
  17. data/lib/synvert/rewriter/gem_spec.rb +0 -42
  18. data/lib/synvert/rewriter/instance.rb +0 -185
  19. data/lib/synvert/rewriter/scope.rb +0 -46
  20. data/lib/synvert/rewriter.rb +0 -200
  21. data/lib/synvert/snippets/check_syntax.rb +0 -5
  22. data/lib/synvert/snippets/factory_girl/syntax_methods.rb +0 -98
  23. data/lib/synvert/snippets/rails/convert_dynamic_finders.rb +0 -93
  24. data/lib/synvert/snippets/rails/strong_parameters.rb +0 -93
  25. data/lib/synvert/snippets/rails/upgrade_3_0_to_3_1.rb +0 -135
  26. data/lib/synvert/snippets/rails/upgrade_3_1_to_3_2.rb +0 -42
  27. data/lib/synvert/snippets/rails/upgrade_3_2_to_4_0.rb +0 -230
  28. data/lib/synvert/snippets/rspec/be_close_to_be_within.rb +0 -18
  29. data/lib/synvert/snippets/rspec/block_to_expect.rb +0 -22
  30. data/lib/synvert/snippets/rspec/boolean_matcher.rb +0 -20
  31. data/lib/synvert/snippets/rspec/collection_matcher.rb +0 -34
  32. data/lib/synvert/snippets/rspec/its_to_it.rb +0 -89
  33. data/lib/synvert/snippets/rspec/message_expectation.rb +0 -41
  34. data/lib/synvert/snippets/rspec/method_stub.rb +0 -84
  35. data/lib/synvert/snippets/rspec/negative_error_expectation.rb +0 -21
  36. data/lib/synvert/snippets/rspec/new_syntax.rb +0 -18
  37. data/lib/synvert/snippets/rspec/one_liner_expectation.rb +0 -71
  38. data/lib/synvert/snippets/rspec/should_to_expect.rb +0 -50
  39. data/lib/synvert/snippets/rspec/stub_and_mock_to_double.rb +0 -22
  40. data/lib/synvert/snippets/ruby/new_hash_syntax.rb +0 -21
  41. data/lib/synvert/snippets/ruby/new_lambda_syntax.rb +0 -20
  42. data/spec/spec_helper.rb +0 -26
  43. data/spec/support/parser_helper.rb +0 -5
  44. data/spec/synvert/node_ext_spec.rb +0 -201
  45. data/spec/synvert/rewriter/action_spec.rb +0 -225
  46. data/spec/synvert/rewriter/condition_spec.rb +0 -106
  47. data/spec/synvert/rewriter/gem_spec_spec.rb +0 -52
  48. data/spec/synvert/rewriter/instance_spec.rb +0 -163
  49. data/spec/synvert/rewriter/scope_spec.rb +0 -42
  50. data/spec/synvert/rewriter_spec.rb +0 -153
  51. data/spec/synvert/snippets/factory_girl/syntax_methods_spec.rb +0 -154
  52. data/spec/synvert/snippets/rails/convert_dynamic_finders_spec.rb +0 -83
  53. data/spec/synvert/snippets/rails/strong_parameters_spec.rb +0 -132
  54. data/spec/synvert/snippets/rails/upgrade_3_0_to_3_1_spec.rb +0 -88
  55. data/spec/synvert/snippets/rails/upgrade_3_1_to_3_2_spec.rb +0 -41
  56. data/spec/synvert/snippets/rails/upgrade_3_2_to_4_0_spec.rb +0 -299
  57. data/spec/synvert/snippets/rspec/new_syntax_spec.rb +0 -183
  58. data/spec/synvert/snippets/ruby/new_hash_syntax_spec.rb +0 -27
  59. data/spec/synvert/snippets/ruby/new_lambda_syntax_spec.rb +0 -27
@@ -1,299 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe 'Upgrade rails from 3.2 to 4.0' do
6
- before do
7
- Synvert::Configuration.instance.set :path, '.'
8
- rewriter_path = File.join(File.dirname(__FILE__), '../../../../lib/synvert/snippets/rails/upgrade_3_2_to_4_0.rb')
9
- @rewriter = eval(File.read(rewriter_path))
10
- allow_any_instance_of(Synvert::Rewriter::GemSpec).to receive(:match?).and_return(true)
11
- strong_parameters_rewriter_path = File.join(File.dirname(__FILE__), '../../../../lib/synvert/snippets/rails/strong_parameters.rb')
12
- eval(File.read(strong_parameters_rewriter_path))
13
- convert_dynamic_finders_rewriter_path = File.join(File.dirname(__FILE__), '../../../../lib/synvert/snippets/rails/convert_dynamic_finders.rb')
14
- eval(File.read(convert_dynamic_finders_rewriter_path))
15
- expect(SecureRandom).to receive(:hex).with(64).and_return("bf4f3f46924ecd9adcb6515681c78144545bba454420973a274d7021ff946b8ef043a95ca1a15a9d1b75f9fbdf85d1a3afaf22f4e3c2f3f78e24a0a188b581df")
16
- end
17
-
18
- describe 'with fakefs', fakefs: true do
19
- let(:application_content) {'''
20
- if defined?(Bundler)
21
- Bundler.require(*Rails.groups(:assets => %w(development test)))
22
- end
23
- module Synvert
24
- class Application < Rails::Application
25
- config.active_record.whitelist_attributes = true
26
- config.active_record.mass_assignment_sanitizer = :strict
27
- config.assets.compress = :uglifier
28
- config.middleware.insert_before(Rack::Lock, ActionDispatch::BestStandardsSupport)
29
- end
30
- end
31
- '''}
32
- let(:application_rewritten_content) {'''
33
- Bundler.require(:default, Rails.env)
34
- module Synvert
35
- class Application < Rails::Application
36
- config.assets.js_compressor = :uglifier
37
- end
38
- end
39
- '''}
40
- let(:production_content) {'''
41
- Synvert::Application.configure do
42
- config.cache_classes = true
43
- config.active_record.identity_map = true
44
- config.action_dispatch.best_standards_support = :builtin
45
-
46
- ActionController::Base.page_cache_extension = "html"
47
- end
48
- '''}
49
- let(:production_rewritten_content) {'''
50
- Synvert::Application.configure do
51
- config.eager_load = true
52
- config.cache_classes = true
53
-
54
- ActionController::Base.default_static_extension = "html"
55
- end
56
- '''}
57
- let(:development_content) {'''
58
- Synvert::Application.configure do
59
- config.cache_classes = false
60
- end
61
- '''}
62
- let(:development_rewritten_content) {'''
63
- Synvert::Application.configure do
64
- config.eager_load = false
65
- config.cache_classes = false
66
- end
67
- '''}
68
- let(:test_content) {'''
69
- Synvert::Application.configure do
70
- config.cache_classes = false
71
- end
72
- '''}
73
- let(:test_rewritten_content) {'''
74
- Synvert::Application.configure do
75
- config.eager_load = false
76
- config.cache_classes = false
77
- end
78
- '''}
79
- let(:wrap_parameters_content) {'''
80
- ActiveSupport.on_load(:action_controller) do
81
- wrap_parameters format: [:json]
82
- end
83
- ActiveSupport.on_load(:active_record) do
84
- self.include_root_in_json = false
85
- end
86
- '''}
87
- let(:wrap_parameters_rewritten_content) {'''
88
- ActiveSupport.on_load(:action_controller) do
89
- wrap_parameters format: [:json]
90
- end
91
- '''}
92
- let(:secret_token_content) {'''
93
- Synvert::Application.config.secret_token = "0447aa931d42918bfb934750bb78257088fb671186b5d1b6f9fddf126fc8a14d34f1d045cefab3900751c3da121a8dd929aec9bafe975f1cabb48232b4002e4e"
94
- '''}
95
- let(:secret_token_rewritten_content) {'''
96
- Synvert::Application.config.secret_token = "0447aa931d42918bfb934750bb78257088fb671186b5d1b6f9fddf126fc8a14d34f1d045cefab3900751c3da121a8dd929aec9bafe975f1cabb48232b4002e4e"
97
- Synvert::Application.config.secret_key_base = "bf4f3f46924ecd9adcb6515681c78144545bba454420973a274d7021ff946b8ef043a95ca1a15a9d1b75f9fbdf85d1a3afaf22f4e3c2f3f78e24a0a188b581df"
98
- '''}
99
- let(:routes_content) {"""
100
- Synvert::Application.routes.draw do
101
- get Rack::Utils.escape('こんにちは'), controller: 'welcome', action: 'index'
102
- match '/' => 'root#index'
103
- match 'new', to: 'episodes#new'
104
- end
105
- """}
106
- let(:routes_rewritten_content) {"""
107
- Synvert::Application.routes.draw do
108
- get 'こんにちは', controller: 'welcome', action: 'index'
109
- get '/' => 'root#index'
110
- get 'new', to: 'episodes#new'
111
- end
112
- """}
113
- let(:migration_content) {"""
114
- class RenamePeopleToUsers < ActiveRecord::Migration
115
- def change
116
- change_table :posts do |t|
117
- t.rename :user_id, :account_id
118
- t.rename_index :user_id, :account_id
119
- end
120
- end
121
- end
122
- """}
123
- let(:migration_rewritten_content) {"""
124
- class RenamePeopleToUsers < ActiveRecord::Migration
125
- def change
126
- change_table :posts do |t|
127
- t.rename :user_id, :account_id
128
- end
129
- end
130
- end
131
- """}
132
- let(:post_model_content) {'''
133
- class Post < ActiveRecord::Base
134
- scope :active, where(active: true)
135
-
136
- attr_accessible :title, :description
137
-
138
- def serialized_attrs
139
- self.serialized_attributes
140
- end
141
-
142
- def active_users_by_email(email)
143
- User.find_all_by_email_and_active(email, true)
144
- end
145
-
146
- def first_active_user_by_email(email)
147
- User.find_by_email_and_active(email, true)
148
- end
149
-
150
- def last_active_user_by_email(email)
151
- User.find_last_by_email_and_active(email, true)
152
- end
153
-
154
- def scoped_active_user_by_email(email)
155
- User.scoped_by_email_and_active(email, true)
156
- end
157
- end
158
- '''}
159
- let(:post_model_rewritten_content) {'''
160
- class Post < ActiveRecord::Base
161
- scope :active, -> { where(active: true) }
162
-
163
- def serialized_attrs
164
- self.class.serialized_attributes
165
- end
166
-
167
- def active_users_by_email(email)
168
- User.where(email: email, active: true)
169
- end
170
-
171
- def first_active_user_by_email(email)
172
- User.where(email: email, active: true).first
173
- end
174
-
175
- def last_active_user_by_email(email)
176
- User.where(email: email, active: true).last
177
- end
178
-
179
- def scoped_active_user_by_email(email)
180
- User.where(email: email, active: true)
181
- end
182
- end
183
- '''}
184
- let(:users_controller_content) {'''
185
- class UsersController < ApplicationController
186
- def new
187
- @user = User.find_or_initialize_by_login_and_email(params[:user][:login], params[:user][:email])
188
- end
189
-
190
- def create
191
- @user = User.find_or_create_by_login_and_email(params[:user][:login], params[:user][:email])
192
- end
193
- end
194
- '''}
195
- let(:users_controller_rewritten_content) {'''
196
- class UsersController < ApplicationController
197
- def new
198
- @user = User.find_or_initialize_by(login: params[:user][:login], email: params[:user][:email])
199
- end
200
-
201
- def create
202
- @user = User.find_or_create_by(login: params[:user][:login], email: params[:user][:email])
203
- end
204
- end
205
- '''}
206
- let(:posts_controller_content) {'''
207
- class PostsController < ApplicationController
208
- def update
209
- @post = Post.find(params[:id])
210
- if @post.update_attributes params[:post]
211
- redirect_to post_path(@post)
212
- else
213
- render :action => :edit
214
- end
215
- end
216
- end
217
- '''}
218
- let(:posts_controller_rewritten_content) {'''
219
- class PostsController < ApplicationController
220
- def update
221
- @post = Post.find(params[:id])
222
- if @post.update_attributes post_params
223
- redirect_to post_path(@post)
224
- else
225
- render :action => :edit
226
- end
227
- end
228
-
229
- def post_params
230
- params.require(:post).permit(:title, :description)
231
- end
232
- end
233
- '''}
234
- let(:post_test_content) {'''
235
- require "test_helper"
236
-
237
- class PostTest < ActiveRecord::TestCase
238
- end
239
- '''}
240
- let(:post_test_rewritten_content) {'''
241
- require "test_helper"
242
-
243
- class PostTest < ActiveSupport::TestCase
244
- end
245
- '''}
246
- let(:test_helper_content) {'''
247
- class ActiveSupport::TestCase
248
- def constants
249
- [ActionController::Integration, ActionController::IntegrationTest, ActionController::PerformanceTest, ActionController::AbstractRequest,
250
- ActionController::Request, ActionController::AbstractResponse, ActionController::Response, ActionController::Routing]
251
- end
252
- end
253
- '''}
254
- let(:test_helper_rewritten_content) {'''
255
- class ActiveSupport::TestCase
256
- def constants
257
- [ActionDispatch::Integration, ActionDispatch::IntegrationTest, ActionDispatch::PerformanceTest, ActionDispatch::Request,
258
- ActionDispatch::Request, ActionDispatch::Response, ActionDispatch::Response, ActionDispatch::Routing]
259
- end
260
- end
261
- '''}
262
-
263
- it 'process' do
264
- FileUtils.mkdir_p 'config/environments'
265
- FileUtils.mkdir_p 'config/initializers'
266
- FileUtils.mkdir_p 'db/migrate'
267
- FileUtils.mkdir_p 'app/models'
268
- FileUtils.mkdir_p 'app/controllers'
269
- FileUtils.mkdir_p 'test/unit'
270
- File.write 'config/application.rb', application_content
271
- File.write 'config/environments/production.rb', production_content
272
- File.write 'config/environments/development.rb', development_content
273
- File.write 'config/environments/test.rb', test_content
274
- File.write 'config/initializers/wrap_parameters.rb', wrap_parameters_content
275
- File.write 'config/initializers/secret_token.rb', secret_token_content
276
- File.write 'config/routes.rb', routes_content
277
- File.write 'db/migrate/20140101000000_change_posts.rb', migration_content
278
- File.write 'app/models/post.rb', post_model_content
279
- File.write 'app/controllers/users_controller.rb', users_controller_content
280
- File.write 'app/controllers/posts_controller.rb', posts_controller_content
281
- File.write 'test/unit/post_test.rb', post_test_content
282
- File.write 'test/test_helper.rb', test_helper_content
283
- @rewriter.process
284
- expect(File.read 'config/application.rb').to eq application_rewritten_content
285
- expect(File.read 'config/environments/production.rb').to eq production_rewritten_content
286
- expect(File.read 'config/environments/development.rb').to eq development_rewritten_content
287
- expect(File.read 'config/environments/test.rb').to eq test_rewritten_content
288
- expect(File.read 'config/initializers/wrap_parameters.rb').to eq wrap_parameters_rewritten_content
289
- expect(File.read 'config/initializers/secret_token.rb').to eq secret_token_rewritten_content
290
- expect(File.read 'config/routes.rb').to eq routes_rewritten_content
291
- expect(File.read 'db/migrate/20140101000000_change_posts.rb').to eq migration_rewritten_content
292
- expect(File.read 'app/models/post.rb').to eq post_model_rewritten_content
293
- expect(File.read 'app/controllers/users_controller.rb').to eq users_controller_rewritten_content
294
- expect(File.read 'app/controllers/posts_controller.rb').to eq posts_controller_rewritten_content
295
- expect(File.read 'test/unit/post_test.rb').to eq post_test_rewritten_content
296
- expect(File.read 'test/test_helper.rb').to eq test_helper_rewritten_content
297
- end
298
- end
299
- end
@@ -1,183 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Use RSpec new syntax' do
4
- before do
5
- Synvert::Configuration.instance.set :path, '.'
6
- allow_any_instance_of(Synvert::Rewriter::GemSpec).to receive(:match?).and_return(true)
7
- Dir.glob File.join(File.dirname(__FILE__), '../../../../lib/synvert/snippets/rspec/*') do |file|
8
- if file =~ /new_syntax.rb$/
9
- @rewriter = eval(File.read(file))
10
- else
11
- eval(File.read(file))
12
- end
13
- end
14
- end
15
-
16
- describe 'with fakefs', fakefs: true do
17
- let(:post_spec_content) {"""
18
- it 'case' do
19
- obj.should matcher
20
- obj.should_not matcher
21
-
22
- 1.should == 1
23
- 1.should < 2
24
- Integer.should === 1
25
- 'string'.should =~ /^str/
26
- [1, 2, 3].should =~ [2, 1, 3]
27
-
28
- expect(obj).to be_true
29
- expect(obj).to be_false
30
-
31
- expect(1.0 / 3.0).to be_close(0.333, 0.001)
32
-
33
- expect(collection).to have(3).items
34
- expect(collection).to have_exactly(3).items
35
- expect(collection).to have_at_least(3).items
36
- expect(collection).to have_at_most(3).items
37
-
38
- expect(team).to have(3).players
39
-
40
- lambda { do_something }.should raise_error
41
- proc { do_something }.should raise_error
42
- -> { do_something }.should raise_error
43
-
44
- expect { do_something }.not_to raise_error(SomeErrorClass)
45
- expect { do_something }.not_to raise_error('message')
46
- expect { do_something }.not_to raise_error(SomeErrorClass, 'message')
47
-
48
- obj.should_receive(:message)
49
- Klass.any_instance.should_receive(:message)
50
-
51
- obj.stub(:message)
52
- obj.stub!(:message)
53
- obj.stub_chain(:foo, :bar, :baz)
54
- Klass.any_instance.stub(:message)
55
-
56
- obj.stub(:foo => 1, :bar => 2)
57
-
58
- obj.unstub!(:message)
59
-
60
- obj.stub(:message).any_number_of_times
61
- obj.stub(:message).at_least(0)
62
-
63
- expect(obj).to receive(:message).and_return { 1 }
64
- allow(obj).to receive(:message).and_return { 1 }
65
-
66
- expect(obj).to receive(:message).and_return
67
- allow(obj).to receive(:message).and_return
68
-
69
- stub('something')
70
- mock('something')
71
- end
72
-
73
- it { should matcher }
74
- it { should_not matcher }
75
-
76
- it { should have(3).items }
77
- it { should have_at_least(3).players }
78
-
79
- describe 'example' do
80
- subject { { foo: 1, bar: 2 } }
81
- its(:size) { should == 2 }
82
- its([:foo]) { should == 1 }
83
- its('keys.first') { should == :foo }
84
- end
85
- """}
86
- let(:post_spec_rewritten_content) {"""
87
- it 'case' do
88
- expect(obj).to matcher
89
- expect(obj).not_to matcher
90
-
91
- expect(1).to eq 1
92
- expect(1).to be < 2
93
- expect(Integer).to be === 1
94
- expect('string').to match /^str/
95
- expect([1, 2, 3]).to match_array [2, 1, 3]
96
-
97
- expect(obj).to be_truthy
98
- expect(obj).to be_falsey
99
-
100
- expect(1.0 / 3.0).to be_within(0.001).of(0.333)
101
-
102
- expect(collection.size).to eq 3
103
- expect(collection.size).to eq 3
104
- expect(collection.size).to be >= 3
105
- expect(collection.size).to be <= 3
106
-
107
- expect(team.players.size).to eq 3
108
-
109
- expect { do_something }.to raise_error
110
- expect { do_something }.to raise_error
111
- expect { do_something }.to raise_error
112
-
113
- expect { do_something }.not_to raise_error
114
- expect { do_something }.not_to raise_error
115
- expect { do_something }.not_to raise_error
116
-
117
- expect(obj).to receive(:message)
118
- expect_any_instance_of(Klass).to receive(:message)
119
-
120
- allow(obj).to receive(:message)
121
- allow(obj).to receive(:message)
122
- allow(obj).to receive_message_chain(:foo, :bar, :baz)
123
- allow_any_instance_of(Klass).to receive(:message)
124
-
125
- allow(obj).to receive_messages(:foo => 1, :bar => 2)
126
-
127
- obj.unstub(:message)
128
-
129
- allow(obj).to receive(:message)
130
- allow(obj).to receive(:message)
131
-
132
- expect(obj).to receive(:message) { 1 }
133
- allow(obj).to receive(:message) { 1 }
134
-
135
- expect(obj).to receive(:message)
136
- allow(obj).to receive(:message)
137
-
138
- double('something')
139
- double('something')
140
- end
141
-
142
- it { is_expected.to matcher }
143
- it { is_expected.not_to matcher }
144
-
145
- it 'has 3 items' do
146
- expect(subject.size).to eq(3)
147
- end
148
-
149
- it 'has at least 3 players' do
150
- expect(subject.players.size).to be >= 3
151
- end
152
-
153
- describe 'example' do
154
- subject { { foo: 1, bar: 2 } }
155
-
156
- describe '#size' do
157
- subject { super().size }
158
- it { should == 2 }
159
- end
160
-
161
- describe '[:foo]' do
162
- subject { super()[:foo] }
163
- it { should == 1 }
164
- end
165
-
166
- describe '#keys' do
167
- subject { super().keys }
168
- describe '#first' do
169
- subject { super().first }
170
- it { should == :foo }
171
- end
172
- end
173
- end
174
- """}
175
-
176
- it 'process' do
177
- FileUtils.mkdir_p 'spec/models'
178
- File.write 'spec/models/post_spec.rb', post_spec_content
179
- @rewriter.process
180
- expect(File.read 'spec/models/post_spec.rb').to eq post_spec_rewritten_content
181
- end
182
- end
183
- end
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Ruby uses new hash synax' do
4
- before do
5
- Synvert::Configuration.instance.set :path, '.'
6
- allow_any_instance_of(Synvert::Rewriter::GemSpec).to receive(:match?).and_return(true)
7
- rewriter_path = File.join(File.dirname(__FILE__), '../../../../lib/synvert/snippets/ruby/new_hash_syntax.rb')
8
- @rewriter = eval(File.read(rewriter_path))
9
- end
10
-
11
- describe 'with fakefs', fakefs: true do
12
- let(:test_content) {"""
13
- {:foo => 'bar', 'foo' => 'bar'}
14
- {:key1 => 'value1', :key2 => 'value2'}
15
- """}
16
- let(:test_rewritten_content) {"""
17
- {foo: 'bar', 'foo' => 'bar'}
18
- {key1: 'value1', key2: 'value2'}
19
- """}
20
-
21
- it 'process' do
22
- File.write 'test.rb', test_content
23
- @rewriter.process
24
- expect(File.read 'test.rb').to eq test_rewritten_content
25
- end
26
- end
27
- end
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Ruby uses new -> synax' do
4
- before do
5
- Synvert::Configuration.instance.set :path, '.'
6
- allow_any_instance_of(Synvert::Rewriter::GemSpec).to receive(:match?).and_return(true)
7
- rewriter_path = File.join(File.dirname(__FILE__), '../../../../lib/synvert/snippets/ruby/new_lambda_syntax.rb')
8
- @rewriter = eval(File.read(rewriter_path))
9
- end
10
-
11
- describe 'with fakefs', fakefs: true do
12
- let(:test_content) {"""
13
- lambda { test }
14
- lambda { |a, b, c| a + b + c }
15
- """}
16
- let(:test_rewritten_content) {"""
17
- -> { test }
18
- ->(a, b, c) { a + b + c }
19
- """}
20
-
21
- it 'process' do
22
- File.write 'test.rb', test_content
23
- @rewriter.process
24
- expect(File.read 'test.rb').to eq test_rewritten_content
25
- end
26
- end
27
- end