watirmark 5.14.16
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/app_generators/create_project/create_project_generator.rb +115 -0
- data/app_generators/create_project/templates/features/env.rb.erb +8 -0
- data/app_generators/create_project/templates/features/model_steps.rb.erb +9 -0
- data/app_generators/create_project/templates/features/post_error_steps.rb.erb +15 -0
- data/app_generators/create_project/templates/features/sample.feature.erb +5 -0
- data/app_generators/create_project/templates/features/site_steps.rb.erb +7 -0
- data/app_generators/create_project/templates/generators/controller.rb.erb +9 -0
- data/app_generators/create_project/templates/generators/generate.rb.erb +9 -0
- data/app_generators/create_project/templates/generators/model.rb.erb +7 -0
- data/app_generators/create_project/templates/generators/mvc_generator.rb.erb +100 -0
- data/app_generators/create_project/templates/generators/rbeautify.rb.erb +212 -0
- data/app_generators/create_project/templates/generators/view.rb.erb +16 -0
- data/app_generators/create_project/templates/generators/workflow_loader.rb.erb +1 -0
- data/app_generators/create_project/templates/library/base_controller.rb.erb +9 -0
- data/app_generators/create_project/templates/library/base_view.rb.erb +6 -0
- data/app_generators/create_project/templates/library/configuration.rb.erb +6 -0
- data/app_generators/create_project/templates/library/core_libraries.rb.erb +9 -0
- data/app_generators/create_project/templates/library/loader.rb.erb +23 -0
- data/app_generators/create_project/templates/library/page_load_checker.rb.erb +11 -0
- data/app_generators/create_project/templates/library/post_errors_checker.rb.erb +23 -0
- data/app_generators/create_project/templates/library/project_require_file.rb.erb +8 -0
- data/app_generators/create_project/templates/library/search_controller.rb.erb +12 -0
- data/app_generators/create_project/templates/library/workflows.rb.erb +0 -0
- data/app_generators/create_project/templates/project/config.yml.erb +3 -0
- data/app_generators/create_project/templates/project/gemfile.rb.erb +11 -0
- data/app_generators/create_project/templates/project/rakefile.rb.erb +21 -0
- data/bin/etapestry/Gemfile +11 -0
- data/bin/etapestry/config.yml +3 -0
- data/bin/etapestry/features/etapestry_home.feature +5 -0
- data/bin/etapestry/features/step_definitions/model_steps.rb +9 -0
- data/bin/etapestry/features/step_definitions/post_error_steps.rb +15 -0
- data/bin/etapestry/features/step_definitions/site_steps.rb +7 -0
- data/bin/etapestry/features/support/env.rb +8 -0
- data/bin/etapestry/generators/mvc/mvc_generator.rb +100 -0
- data/bin/etapestry/generators/mvc/rbeautify.rb +212 -0
- data/bin/etapestry/generators/mvc/templates/controller.rb.erb +9 -0
- data/bin/etapestry/generators/mvc/templates/model.rb.erb +7 -0
- data/bin/etapestry/generators/mvc/templates/view.rb.erb +16 -0
- data/bin/etapestry/generators/mvc/templates/workflow_loader.rb.erb +1 -0
- data/bin/etapestry/lib/etapestry.rb +8 -0
- data/bin/etapestry/lib/etapestry/checkers/page_load_checker.rb +11 -0
- data/bin/etapestry/lib/etapestry/checkers/post_errors_checker.rb +23 -0
- data/bin/etapestry/lib/etapestry/configuration.rb +6 -0
- data/bin/etapestry/lib/etapestry/core_libraries.rb +9 -0
- data/bin/etapestry/lib/etapestry/loader.rb +23 -0
- data/bin/etapestry/lib/etapestry/site/base_controller.rb +9 -0
- data/bin/etapestry/lib/etapestry/site/base_view.rb +6 -0
- data/bin/etapestry/lib/etapestry/site/search_controller.rb +12 -0
- data/bin/etapestry/lib/etapestry/workflows.rb +0 -0
- data/bin/etapestry/rakefile.rb +21 -0
- data/bin/etapestry/script/generate.rb +9 -0
- data/bin/twitter/features/hashtag_search.feature +93 -0
- data/bin/twitter/features/step_definitions/hashtag_steps.rb +9 -0
- data/bin/twitter/lib/twitter/workflows/search/result_controller.rb +13 -0
- data/bin/twitter/lib/twitter/workflows/search/result_model.rb +5 -0
- data/bin/twitter/lib/twitter/workflows/search/result_view.rb +19 -0
- data/bin/watirmark +10 -0
- data/lib/watirmark.rb +26 -0
- data/lib/watirmark/at_exit.rb +13 -0
- data/lib/watirmark/configuration.rb +201 -0
- data/lib/watirmark/controller/actions.rb +172 -0
- data/lib/watirmark/controller/assertions.rb +116 -0
- data/lib/watirmark/controller/controller.rb +191 -0
- data/lib/watirmark/controller/dialogs.rb +33 -0
- data/lib/watirmark/controller/matcher.rb +19 -0
- data/lib/watirmark/cucumber/cuke_helper.rb +150 -0
- data/lib/watirmark/cucumber/email_helper.rb +103 -0
- data/lib/watirmark/cucumber/env.rb +9 -0
- data/lib/watirmark/cucumber/hooks.rb +16 -0
- data/lib/watirmark/cucumber/model_helper.rb +34 -0
- data/lib/watirmark/cucumber/transforms.rb +55 -0
- data/lib/watirmark/exceptions.rb +15 -0
- data/lib/watirmark/extensions/ruby_extensions.rb +129 -0
- data/lib/watirmark/extensions/webdriver_extensions.rb +150 -0
- data/lib/watirmark/formatters/snapshot_formatter.rb +23 -0
- data/lib/watirmark/loader.rb +87 -0
- data/lib/watirmark/model.rb +3 -0
- data/lib/watirmark/models/cucumber_helper.rb +49 -0
- data/lib/watirmark/models/debug_methods.rb +21 -0
- data/lib/watirmark/models/default_values.rb +21 -0
- data/lib/watirmark/models/factory.rb +168 -0
- data/lib/watirmark/models/factory_method_generators.rb +84 -0
- data/lib/watirmark/models/factory_methods.rb +72 -0
- data/lib/watirmark/models/trait.rb +35 -0
- data/lib/watirmark/models/upload_csv.rb +24 -0
- data/lib/watirmark/page/keyed_element.rb +63 -0
- data/lib/watirmark/page/page.rb +50 -0
- data/lib/watirmark/page/page_definition.rb +187 -0
- data/lib/watirmark/page/process_page.rb +112 -0
- data/lib/watirmark/page/radio_maps.rb +53 -0
- data/lib/watirmark/profile.rb +22 -0
- data/lib/watirmark/rake/smoketest.rb +17 -0
- data/lib/watirmark/screenshot.rb +127 -0
- data/lib/watirmark/session.rb +115 -0
- data/lib/watirmark/version.rb +5 -0
- data/spec/assertions_spec.rb +95 -0
- data/spec/config_spec.rb +82 -0
- data/spec/controller_actions_spec.rb +91 -0
- data/spec/controller_spec.rb +426 -0
- data/spec/controllers_and_models_spec.rb +52 -0
- data/spec/model_factory_spec.rb +568 -0
- data/spec/model_traits_spec.rb +141 -0
- data/spec/page_spec.rb +127 -0
- data/spec/process_page_spec.rb +163 -0
- data/spec/spec_helper.rb +17 -0
- metadata +238 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module <%= name.camelize %>
|
|
2
|
+
<%%= create_modules %>
|
|
3
|
+
class <%%= name.camelize %>View < BaseView
|
|
4
|
+
keyword(:keyword_name) { browser.text_field(:id, 'element_id') }
|
|
5
|
+
|
|
6
|
+
def home(model)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def create(model)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def edit(model)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
<%%= create_module_end %>
|
|
16
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= name.camelize %>::Loader.load_product '<%%= product.downcase %>'
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require '<%= name.downcase %>/site/base_view'
|
|
2
|
+
require '<%= name.downcase %>/site/base_controller'
|
|
3
|
+
require '<%= name.downcase %>/site/search_controller'
|
|
4
|
+
Watirmark.loader do
|
|
5
|
+
base_directory File.dirname(__FILE__)
|
|
6
|
+
product '<%= name.camelize %>'
|
|
7
|
+
load_files 'checkers/**/*.rb'
|
|
8
|
+
end
|
|
9
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'watirmark/loader'
|
|
2
|
+
module <%= name.camelize %>
|
|
3
|
+
class Loader
|
|
4
|
+
class << self
|
|
5
|
+
@@loaded = {}
|
|
6
|
+
|
|
7
|
+
def load_workflow(name)
|
|
8
|
+
load_files name, "*{_view}.rb"
|
|
9
|
+
load_files name, "*{_model}.rb"
|
|
10
|
+
load_files name, "*{_controller}.rb"
|
|
11
|
+
load_files name, "*.rb"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def load_files(name, files)
|
|
15
|
+
Watirmark.loader do
|
|
16
|
+
base_directory File.dirname(__FILE__)
|
|
17
|
+
product '<%= name.camelize %>'
|
|
18
|
+
load_files "workflows/#{name}#{files}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Watirmark
|
|
2
|
+
class Session
|
|
3
|
+
|
|
4
|
+
# put in here the appropriate waits
|
|
5
|
+
# to verify that the page has loaded completely, if your app has javascript-loaded content
|
|
6
|
+
def self.page_load
|
|
7
|
+
Watir::Wait.until { Page.browser.url != "about:blank" }
|
|
8
|
+
end
|
|
9
|
+
Watirmark::Session::POST_WAIT_CHECKERS << Proc.new { Watirmark::Session::page_load }
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'watirmark/session'
|
|
2
|
+
|
|
3
|
+
module Watirmark
|
|
4
|
+
class Session
|
|
5
|
+
|
|
6
|
+
# Post errors are basically any error messages that
|
|
7
|
+
# appear to the user when a form submission fails. This catches that
|
|
8
|
+
# error and allows the cucumber to catch the error (@@buffer_post_failure)
|
|
9
|
+
# or just throw an exception when an error is seen after a post
|
|
10
|
+
def self.post_errors
|
|
11
|
+
#if Page.browser.table(:class, 'error').present?
|
|
12
|
+
# message = Page.browser.table(:class, 'error').text
|
|
13
|
+
# if @@buffer_post_failure
|
|
14
|
+
# @@post_failure = message.strip
|
|
15
|
+
# else
|
|
16
|
+
# raise Watirmark::PostFailure, message.strip
|
|
17
|
+
# end
|
|
18
|
+
#end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Watirmark::Session::POST_WAIT_CHECKERS << Proc.new { Watirmark::Session::post_errors }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module <%= name.camelize %>
|
|
2
|
+
class SearchController < BaseController
|
|
3
|
+
|
|
4
|
+
def current_record_visible?
|
|
5
|
+
raise "Method needs to be defined in the subclass and return a true/false value"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def populate_data
|
|
9
|
+
super unless current_record_visible?
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
|
|
2
|
+
|
|
3
|
+
# Run a bundle install if running from Jenkins
|
|
4
|
+
begin
|
|
5
|
+
sh "bundle install" if File.dirname(__FILE__) =~ /\/(hudson|mnt)\/workspace\//
|
|
6
|
+
rescue Gem::RemoteFetcher::FetchError
|
|
7
|
+
puts "Unable to connect - retrying #{Time.now}"
|
|
8
|
+
retry
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
require 'bundler/setup'
|
|
12
|
+
require 'cucumber/rake/task'
|
|
13
|
+
|
|
14
|
+
module RakeHelper
|
|
15
|
+
def self.cucumber_task(task_name, files=nil)
|
|
16
|
+
Cucumber::Rake::Task.new(task_name) do |t|
|
|
17
|
+
t.cucumber_opts = "-r features #{FileList[files]} -b --format html -o reports/report.html --format pretty"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# There are cases where we want a bare model,
|
|
2
|
+
# For example in the API we can use the model to generate the defaults for the API call
|
|
3
|
+
When /I create a model (\[[^\]]+\])$/ do |model|
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
When /I (create|update) a model (\[[^\]]+\]) with values$/ do |action, model, table|
|
|
7
|
+
update_model(model, table)
|
|
8
|
+
end
|
|
9
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Exact matches
|
|
2
|
+
Then /^I should see the error: '?"?([^\/].*)"?'?$/ do |error|
|
|
3
|
+
# Replace carriage returns with a space to make it easier to declare the error
|
|
4
|
+
if Watirmark::Session.instance.post_failure
|
|
5
|
+
Watirmark::Session.instance.post_failure.gsub(/[\r\n]+/, ' ').strip.should == error.strip
|
|
6
|
+
else
|
|
7
|
+
'No POST failure seen!'.should == error
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Pattern matches
|
|
12
|
+
Then /^I should see the error: \/(.+)\/$/ do |error|
|
|
13
|
+
Watirmark::Session.instance.post_failure.gsub(/[\r\n]+/, ' ').should =~ /#{error.gsub!(/[\r\n]+/, ' ')}/
|
|
14
|
+
end
|
|
15
|
+
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'rubigen'
|
|
2
|
+
require 'active_support/inflector'
|
|
3
|
+
require_relative 'rbeautify'
|
|
4
|
+
|
|
5
|
+
class MvcGenerator < RubiGen::Base
|
|
6
|
+
attr_reader :product, :name
|
|
7
|
+
|
|
8
|
+
def initialize(runtime_args, runtime_options = {})
|
|
9
|
+
super
|
|
10
|
+
usage if args.empty?
|
|
11
|
+
@product = args.shift
|
|
12
|
+
@name = args.shift
|
|
13
|
+
usage unless @name && @product
|
|
14
|
+
@destination_root = File.expand_path(File.dirname(__FILE__) + '/../../')
|
|
15
|
+
extract_options
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def workflow_directory
|
|
19
|
+
"lib/etapestry/workflows/#{@product}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def manifest
|
|
23
|
+
record do |m|
|
|
24
|
+
create_directories(m)
|
|
25
|
+
add_mvc_stubs m
|
|
26
|
+
add_loader
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def add_mvc_stubs m
|
|
31
|
+
m.template "model.rb.erb", File.join(workflow_directory, "#{@name}_model.rb")
|
|
32
|
+
m.template "view.rb.erb", File.join(workflow_directory,"#{@name}_view.rb")
|
|
33
|
+
m.template "controller.rb.erb", File.join(workflow_directory,"#{@name}_controller.rb")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def workflow_exists?
|
|
37
|
+
File.directory? "../#{workflow_directory}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def add_rake_task
|
|
41
|
+
append_to_file "../rakefile.rb" do |f|
|
|
42
|
+
f.puts "RakeHelper.cucumber_task(:#{@product}, \"features/#{@product}/**/*.feature\")"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def add_loader
|
|
47
|
+
append_to_file "../lib/etapestry/workflows.rb" do |f|
|
|
48
|
+
f.puts "Etapestry::Loader.load_workflow '#{@product.downcase}/#{@name.downcase}'"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def append_to_file name, &block
|
|
53
|
+
File.open(name, 'a+') {|f| yield f}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def create_directories(m)
|
|
57
|
+
m.directory workflow_directory
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def create_modules
|
|
61
|
+
@product.split('/').map{|x| "module #{x.camelize}\n"}.join.strip
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def create_module_end
|
|
65
|
+
@product.split('/').map{|x| "end\n"}.join.strip
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
protected
|
|
69
|
+
def banner
|
|
70
|
+
<<-EOS
|
|
71
|
+
USAGE: #{spec.name} path/for/your/test/mvc workflow_directory name [options]
|
|
72
|
+
EOS
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def after_generate
|
|
76
|
+
mvc_file_path = "#{@destination_root}/#{workflow_directory}/#{@name}"
|
|
77
|
+
RBeautify.new({}).beautify_file("#{mvc_file_path}_model.rb")
|
|
78
|
+
RBeautify.new({}).beautify_file("#{mvc_file_path}_view.rb")
|
|
79
|
+
RBeautify.new({}).beautify_file("#{mvc_file_path}_controller.rb")
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def add_options!(opts)
|
|
83
|
+
opts.separator ''
|
|
84
|
+
opts.separator 'Options:'
|
|
85
|
+
# For each option below, place the default
|
|
86
|
+
# at the top of the file next to "default_options"
|
|
87
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
|
88
|
+
# "Some comment about this option",
|
|
89
|
+
# "Default: none") { |options[:author]| }
|
|
90
|
+
opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def extract_options
|
|
94
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
|
95
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
|
96
|
+
# raw instance variable value.
|
|
97
|
+
# @author = options[:author]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
=begin
|
|
5
|
+
/***************************************************************************
|
|
6
|
+
* Copyright (C) 2008, Paul Lutus *
|
|
7
|
+
* *
|
|
8
|
+
* This program is free software; you can redistribute it and/or modify *
|
|
9
|
+
* it under the terms of the GNU General Public License as published by *
|
|
10
|
+
* the Free Software Foundation; either version 2 of the License, or *
|
|
11
|
+
* (at your option) any later version. *
|
|
12
|
+
* *
|
|
13
|
+
* This program is distributed in the hope that it will be useful, *
|
|
14
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
15
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
16
|
+
* GNU General Public License for more details. *
|
|
17
|
+
* *
|
|
18
|
+
* You should have received a copy of the GNU General Public License *
|
|
19
|
+
* along with this program; if not, write to the *
|
|
20
|
+
* Free Software Foundation, Inc., *
|
|
21
|
+
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
22
|
+
***************************************************************************/
|
|
23
|
+
=end
|
|
24
|
+
|
|
25
|
+
PVERSION = "Version 2.9, 10/24/2008"
|
|
26
|
+
|
|
27
|
+
class RBeautify
|
|
28
|
+
|
|
29
|
+
# indent regexp tests
|
|
30
|
+
|
|
31
|
+
IndentExp = [
|
|
32
|
+
/^module\b/,
|
|
33
|
+
/^class\b/,
|
|
34
|
+
/^if\b/,
|
|
35
|
+
/(=\s*|^)until\b/,
|
|
36
|
+
/(=\s*|^)for\b/,
|
|
37
|
+
/^unless\b/,
|
|
38
|
+
/(=\s*|^)while\b/,
|
|
39
|
+
/(=\s*|^)begin\b/,
|
|
40
|
+
/(^| )case\b/,
|
|
41
|
+
/\bthen\b/,
|
|
42
|
+
/^rescue\b/,
|
|
43
|
+
/^def\b/,
|
|
44
|
+
/\bdo\b/,
|
|
45
|
+
/^else\b/,
|
|
46
|
+
/^elsif\b/,
|
|
47
|
+
/^ensure\b/,
|
|
48
|
+
/\bwhen\b/,
|
|
49
|
+
/\{[^\}]*$/,
|
|
50
|
+
/\[[^\]]*$/
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
# outdent regexp tests
|
|
54
|
+
|
|
55
|
+
OutdentExp = [
|
|
56
|
+
/^rescue\b/,
|
|
57
|
+
/^ensure\b/,
|
|
58
|
+
/^elsif\b/,
|
|
59
|
+
/^end\b/,
|
|
60
|
+
/^else\b/,
|
|
61
|
+
/\bwhen\b/,
|
|
62
|
+
/^[^\{]*\}/,
|
|
63
|
+
/^[^\[]*\]/
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
# user-customizable values
|
|
67
|
+
OPTIONS = {
|
|
68
|
+
tab_string: ' ',
|
|
69
|
+
tab_size: 2
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
def initialize(options)
|
|
73
|
+
options = OPTIONS.merge(options)
|
|
74
|
+
@tab_string, @tab_size = options[:tab_string], options[:tab_size]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def rb_make_tab(tab)
|
|
78
|
+
tab < 0 ? "" : (@tab_string * @tab_size * tab)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def rb_add_line(line,tab)
|
|
82
|
+
line.strip!
|
|
83
|
+
line = rb_make_tab(tab) + line if line.length > 0
|
|
84
|
+
line
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def beautify_string(source, path = "")
|
|
88
|
+
comment_block = false
|
|
89
|
+
in_here_doc = false
|
|
90
|
+
here_doc_term = ""
|
|
91
|
+
program_end = false
|
|
92
|
+
multiLine_array = []
|
|
93
|
+
multiLine_str = ""
|
|
94
|
+
tab = 0
|
|
95
|
+
output = []
|
|
96
|
+
source.each_line do |line|
|
|
97
|
+
line.chomp!
|
|
98
|
+
if !program_end
|
|
99
|
+
# detect program end mark
|
|
100
|
+
if line =~ /^__END__$/
|
|
101
|
+
program_end = true
|
|
102
|
+
else
|
|
103
|
+
# combine continuing lines
|
|
104
|
+
if !(line =~ /^\s*#/) && line =~ /[^\\]\\\s*$/
|
|
105
|
+
multiLine_array.push line
|
|
106
|
+
multiLine_str += line.sub(/^(.*)\\\s*$/,"\\1")
|
|
107
|
+
next
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# add final line
|
|
111
|
+
if multiLine_str.length > 0
|
|
112
|
+
multiLine_array.push line
|
|
113
|
+
multiLine_str += line.sub(/^(.*)\\\s*$/,"\\1")
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
tline = ((multiLine_str.length > 0) ? multiLine_str : line).strip
|
|
117
|
+
if tline =~ /^=begin/
|
|
118
|
+
comment_block = true
|
|
119
|
+
end
|
|
120
|
+
if in_here_doc
|
|
121
|
+
in_here_doc = false if tline =~ %r{\s*#{here_doc_term}\s*}
|
|
122
|
+
else # not in here_doc
|
|
123
|
+
if tline =~ %r{=\s*<<}
|
|
124
|
+
here_doc_term = tline.sub(%r{.*=\s*<<-?\s*([_|\w]+).*},"\\1")
|
|
125
|
+
in_here_doc = here_doc_term.size > 0
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
if comment_block || program_end || in_here_doc
|
|
131
|
+
# add the line unchanged
|
|
132
|
+
output << line
|
|
133
|
+
else
|
|
134
|
+
comment_line = (tline =~ /^#/)
|
|
135
|
+
if !comment_line
|
|
136
|
+
# throw out sequences that will
|
|
137
|
+
# only sow confusion
|
|
138
|
+
while tline.gsub!(/\{[^\{]*?\}/,"")
|
|
139
|
+
end
|
|
140
|
+
while tline.gsub!(/\[[^\[]*?\]/,"")
|
|
141
|
+
end
|
|
142
|
+
while tline.gsub!(/'.*?'/,"")
|
|
143
|
+
end
|
|
144
|
+
while tline.gsub!(/".*?"/,"")
|
|
145
|
+
end
|
|
146
|
+
while tline.gsub!(/\`.*?\`/,"")
|
|
147
|
+
end
|
|
148
|
+
while tline.gsub!(/\([^\(]*?\)/,"")
|
|
149
|
+
end
|
|
150
|
+
while tline.gsub!(/\/.*?\//,"")
|
|
151
|
+
end
|
|
152
|
+
while tline.gsub!(/%r(.).*?\1/,"")
|
|
153
|
+
end
|
|
154
|
+
# delete end-of-line comments
|
|
155
|
+
tline.sub!(/#[^\"]+$/,"")
|
|
156
|
+
# convert quotes
|
|
157
|
+
tline.gsub!(/\\\"/,"'")
|
|
158
|
+
OutdentExp.each do |re|
|
|
159
|
+
if tline =~ re
|
|
160
|
+
tab -= 1
|
|
161
|
+
break
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
if multiLine_array.length > 0
|
|
166
|
+
multiLine_array.each do |ml|
|
|
167
|
+
output << rb_add_line(ml,tab)
|
|
168
|
+
end
|
|
169
|
+
multiLine_array.clear
|
|
170
|
+
multiLine_str = ""
|
|
171
|
+
else
|
|
172
|
+
output << rb_add_line(line,tab)
|
|
173
|
+
end
|
|
174
|
+
if !comment_line
|
|
175
|
+
IndentExp.each do |re|
|
|
176
|
+
if tline =~ re && !(tline =~ /\s+end\s*$/)
|
|
177
|
+
tab += 1
|
|
178
|
+
break
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
if tline =~ /^=end/
|
|
184
|
+
comment_block = false
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
error = (tab != 0)
|
|
188
|
+
STDERR.puts "Error: indent/outdent mismatch: #{tab}." if error
|
|
189
|
+
return output.join("\n") + "\n",error
|
|
190
|
+
end # beautify_string
|
|
191
|
+
|
|
192
|
+
def beautify_file(path)
|
|
193
|
+
error = false
|
|
194
|
+
|
|
195
|
+
if path == '-' # stdin source
|
|
196
|
+
source = STDIN.read
|
|
197
|
+
dest,error = beautify_string(source,"stdin")
|
|
198
|
+
print dest
|
|
199
|
+
else # named file source
|
|
200
|
+
source = File.read(path)
|
|
201
|
+
dest,error = beautify_string(source,path)
|
|
202
|
+
|
|
203
|
+
if source != dest
|
|
204
|
+
# make a backup copy
|
|
205
|
+
File.open(path + "~","w") { |f| f.write(source) }
|
|
206
|
+
# overwrite the original
|
|
207
|
+
File.open(path,"w") { |f| f.write(dest) }
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
error
|
|
211
|
+
end # beautify_file
|
|
212
|
+
end # module RBeautify
|