watirmark 5.14.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/app_generators/create_project/create_project_generator.rb +115 -0
  2. data/app_generators/create_project/templates/features/env.rb.erb +8 -0
  3. data/app_generators/create_project/templates/features/model_steps.rb.erb +9 -0
  4. data/app_generators/create_project/templates/features/post_error_steps.rb.erb +15 -0
  5. data/app_generators/create_project/templates/features/sample.feature.erb +5 -0
  6. data/app_generators/create_project/templates/features/site_steps.rb.erb +7 -0
  7. data/app_generators/create_project/templates/generators/controller.rb.erb +9 -0
  8. data/app_generators/create_project/templates/generators/generate.rb.erb +9 -0
  9. data/app_generators/create_project/templates/generators/model.rb.erb +7 -0
  10. data/app_generators/create_project/templates/generators/mvc_generator.rb.erb +100 -0
  11. data/app_generators/create_project/templates/generators/rbeautify.rb.erb +212 -0
  12. data/app_generators/create_project/templates/generators/view.rb.erb +16 -0
  13. data/app_generators/create_project/templates/generators/workflow_loader.rb.erb +1 -0
  14. data/app_generators/create_project/templates/library/base_controller.rb.erb +9 -0
  15. data/app_generators/create_project/templates/library/base_view.rb.erb +6 -0
  16. data/app_generators/create_project/templates/library/configuration.rb.erb +6 -0
  17. data/app_generators/create_project/templates/library/core_libraries.rb.erb +9 -0
  18. data/app_generators/create_project/templates/library/loader.rb.erb +23 -0
  19. data/app_generators/create_project/templates/library/page_load_checker.rb.erb +11 -0
  20. data/app_generators/create_project/templates/library/post_errors_checker.rb.erb +23 -0
  21. data/app_generators/create_project/templates/library/project_require_file.rb.erb +8 -0
  22. data/app_generators/create_project/templates/library/search_controller.rb.erb +12 -0
  23. data/app_generators/create_project/templates/library/workflows.rb.erb +0 -0
  24. data/app_generators/create_project/templates/project/config.yml.erb +3 -0
  25. data/app_generators/create_project/templates/project/gemfile.rb.erb +11 -0
  26. data/app_generators/create_project/templates/project/rakefile.rb.erb +21 -0
  27. data/bin/etapestry/Gemfile +11 -0
  28. data/bin/etapestry/config.yml +3 -0
  29. data/bin/etapestry/features/etapestry_home.feature +5 -0
  30. data/bin/etapestry/features/step_definitions/model_steps.rb +9 -0
  31. data/bin/etapestry/features/step_definitions/post_error_steps.rb +15 -0
  32. data/bin/etapestry/features/step_definitions/site_steps.rb +7 -0
  33. data/bin/etapestry/features/support/env.rb +8 -0
  34. data/bin/etapestry/generators/mvc/mvc_generator.rb +100 -0
  35. data/bin/etapestry/generators/mvc/rbeautify.rb +212 -0
  36. data/bin/etapestry/generators/mvc/templates/controller.rb.erb +9 -0
  37. data/bin/etapestry/generators/mvc/templates/model.rb.erb +7 -0
  38. data/bin/etapestry/generators/mvc/templates/view.rb.erb +16 -0
  39. data/bin/etapestry/generators/mvc/templates/workflow_loader.rb.erb +1 -0
  40. data/bin/etapestry/lib/etapestry.rb +8 -0
  41. data/bin/etapestry/lib/etapestry/checkers/page_load_checker.rb +11 -0
  42. data/bin/etapestry/lib/etapestry/checkers/post_errors_checker.rb +23 -0
  43. data/bin/etapestry/lib/etapestry/configuration.rb +6 -0
  44. data/bin/etapestry/lib/etapestry/core_libraries.rb +9 -0
  45. data/bin/etapestry/lib/etapestry/loader.rb +23 -0
  46. data/bin/etapestry/lib/etapestry/site/base_controller.rb +9 -0
  47. data/bin/etapestry/lib/etapestry/site/base_view.rb +6 -0
  48. data/bin/etapestry/lib/etapestry/site/search_controller.rb +12 -0
  49. data/bin/etapestry/lib/etapestry/workflows.rb +0 -0
  50. data/bin/etapestry/rakefile.rb +21 -0
  51. data/bin/etapestry/script/generate.rb +9 -0
  52. data/bin/twitter/features/hashtag_search.feature +93 -0
  53. data/bin/twitter/features/step_definitions/hashtag_steps.rb +9 -0
  54. data/bin/twitter/lib/twitter/workflows/search/result_controller.rb +13 -0
  55. data/bin/twitter/lib/twitter/workflows/search/result_model.rb +5 -0
  56. data/bin/twitter/lib/twitter/workflows/search/result_view.rb +19 -0
  57. data/bin/watirmark +10 -0
  58. data/lib/watirmark.rb +26 -0
  59. data/lib/watirmark/at_exit.rb +13 -0
  60. data/lib/watirmark/configuration.rb +201 -0
  61. data/lib/watirmark/controller/actions.rb +172 -0
  62. data/lib/watirmark/controller/assertions.rb +116 -0
  63. data/lib/watirmark/controller/controller.rb +191 -0
  64. data/lib/watirmark/controller/dialogs.rb +33 -0
  65. data/lib/watirmark/controller/matcher.rb +19 -0
  66. data/lib/watirmark/cucumber/cuke_helper.rb +150 -0
  67. data/lib/watirmark/cucumber/email_helper.rb +103 -0
  68. data/lib/watirmark/cucumber/env.rb +9 -0
  69. data/lib/watirmark/cucumber/hooks.rb +16 -0
  70. data/lib/watirmark/cucumber/model_helper.rb +34 -0
  71. data/lib/watirmark/cucumber/transforms.rb +55 -0
  72. data/lib/watirmark/exceptions.rb +15 -0
  73. data/lib/watirmark/extensions/ruby_extensions.rb +129 -0
  74. data/lib/watirmark/extensions/webdriver_extensions.rb +150 -0
  75. data/lib/watirmark/formatters/snapshot_formatter.rb +23 -0
  76. data/lib/watirmark/loader.rb +87 -0
  77. data/lib/watirmark/model.rb +3 -0
  78. data/lib/watirmark/models/cucumber_helper.rb +49 -0
  79. data/lib/watirmark/models/debug_methods.rb +21 -0
  80. data/lib/watirmark/models/default_values.rb +21 -0
  81. data/lib/watirmark/models/factory.rb +168 -0
  82. data/lib/watirmark/models/factory_method_generators.rb +84 -0
  83. data/lib/watirmark/models/factory_methods.rb +72 -0
  84. data/lib/watirmark/models/trait.rb +35 -0
  85. data/lib/watirmark/models/upload_csv.rb +24 -0
  86. data/lib/watirmark/page/keyed_element.rb +63 -0
  87. data/lib/watirmark/page/page.rb +50 -0
  88. data/lib/watirmark/page/page_definition.rb +187 -0
  89. data/lib/watirmark/page/process_page.rb +112 -0
  90. data/lib/watirmark/page/radio_maps.rb +53 -0
  91. data/lib/watirmark/profile.rb +22 -0
  92. data/lib/watirmark/rake/smoketest.rb +17 -0
  93. data/lib/watirmark/screenshot.rb +127 -0
  94. data/lib/watirmark/session.rb +115 -0
  95. data/lib/watirmark/version.rb +5 -0
  96. data/spec/assertions_spec.rb +95 -0
  97. data/spec/config_spec.rb +82 -0
  98. data/spec/controller_actions_spec.rb +91 -0
  99. data/spec/controller_spec.rb +426 -0
  100. data/spec/controllers_and_models_spec.rb +52 -0
  101. data/spec/model_factory_spec.rb +568 -0
  102. data/spec/model_traits_spec.rb +141 -0
  103. data/spec/page_spec.rb +127 -0
  104. data/spec/process_page_spec.rb +163 -0
  105. data/spec/spec_helper.rb +17 -0
  106. metadata +238 -0
@@ -0,0 +1,115 @@
1
+ require 'rubigen'
2
+ class CreateProjectGenerator < RubiGen::Base
3
+ default_options :author => nil
4
+ attr_reader :name
5
+
6
+ def initialize(runtime_args, runtime_options = {})
7
+ super
8
+ usage if args.empty?
9
+ @name = File.basename(args.shift)
10
+ @destination_root = File.expand_path(@name)
11
+ extract_options
12
+ end
13
+
14
+ def manifest
15
+ record do |m|
16
+ create_directories(m)
17
+ create_project_files(m)
18
+ create_library_checker_files(m)
19
+ create_library_site_files(m)
20
+ create_library_toplevel_files(m)
21
+ create_mvc_generators(m)
22
+ create_test_files(m)
23
+ end
24
+ end
25
+
26
+ def create_project_files(manifest)
27
+ manifest.template "project/gemfile.rb.erb", "Gemfile"
28
+ manifest.template "project/config.yml.erb", "config.yml"
29
+ manifest.template "project/rakefile.rb.erb", "rakefile.rb"
30
+ end
31
+
32
+ def create_library_checker_files(manifest)
33
+ manifest.template "library/page_load_checker.rb.erb", File.join("lib", name, "checkers", "page_load_checker.rb")
34
+ manifest.template "library/post_errors_checker.rb.erb", File.join("lib", name, "checkers", "post_errors_checker.rb")
35
+ end
36
+
37
+ def create_library_site_files(manifest)
38
+ manifest.template "library/base_controller.rb.erb", File.join("lib", name, "site", "base_controller.rb")
39
+ manifest.template "library/search_controller.rb.erb", File.join("lib", name, "site", "search_controller.rb")
40
+ manifest.template "library/base_view.rb.erb", File.join("lib", name, "site", "base_view.rb")
41
+ end
42
+
43
+ def create_library_toplevel_files(manifest)
44
+ manifest.template "library/configuration.rb.erb", File.join("lib", name, "configuration.rb")
45
+ manifest.template "library/workflows.rb.erb", File.join("lib", name, "workflows.rb")
46
+ manifest.template "library/core_libraries.rb.erb", File.join("lib", name, "core_libraries.rb")
47
+ manifest.template "library/loader.rb.erb", File.join("lib", name, "loader.rb")
48
+ manifest.template "library/project_require_file.rb.erb", File.join("lib","#{name}.rb")
49
+ end
50
+
51
+ def create_mvc_generators(manifest)
52
+ manifest.template "generators/generate.rb.erb", File.join("script","generate.rb")
53
+ manifest.template "generators/mvc_generator.rb.erb", File.join("generators","mvc","mvc_generator.rb")
54
+ manifest.template "generators/rbeautify.rb.erb", File.join("generators", "mvc", "rbeautify.rb")
55
+ manifest.template "generators/controller.rb.erb", File.join("generators","mvc","templates","controller.rb.erb")
56
+ manifest.template "generators/model.rb.erb", File.join("generators","mvc","templates","model.rb.erb")
57
+ manifest.template "generators/view.rb.erb", File.join("generators","mvc","templates","view.rb.erb")
58
+ manifest.template "generators/workflow_loader.rb.erb", File.join("generators","mvc","templates","workflow_loader.rb.erb")
59
+ end
60
+
61
+ def create_test_files(manifest)
62
+ manifest.template "features/model_steps.rb.erb", File.join("features","step_definitions","model_steps.rb")
63
+ manifest.template "features/post_error_steps.rb.erb", File.join("features","step_definitions","post_error_steps.rb")
64
+ manifest.template "features/site_steps.rb.erb", File.join("features","step_definitions","site_steps.rb")
65
+ manifest.template "features/env.rb.erb", File.join("features","support","env.rb")
66
+ manifest.template "features/sample.feature.erb", File.join("features","#{@name}_home.feature")
67
+ end
68
+
69
+ def create_directories(m)
70
+ BASEDIRS.each { |path| m.directory path }
71
+ create_subdirectories m, File.join('features'), %w(step_definitions support)
72
+ create_subdirectories m, File.join('lib', @name), %w(checkers site workflows)
73
+ create_subdirectories m, File.join('generators', 'mvc'), %w(templates)
74
+ end
75
+
76
+ def create_subdirectories (m, root, directories)
77
+ m.directory root
78
+ directories.each {|dir| m.directory File.join(root, dir)}
79
+ end
80
+
81
+
82
+ protected
83
+ def banner
84
+ <<-EOS
85
+ USAGE: #{spec.name} path/for/your/test/create_project project_name [options]
86
+ EOS
87
+ end
88
+
89
+ def add_options!(opts)
90
+ opts.separator ''
91
+ opts.separator 'Options:'
92
+ # For each option below, place the default
93
+ # at the top of the file next to "default_options"
94
+ # opts.on("-a", "--author=\"Your Name\"", String,
95
+ # "Some comment about this option",
96
+ # "Default: none") { |options[:author]| }
97
+ opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
98
+ end
99
+
100
+ def extract_options
101
+ # for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
102
+ # Templates can access these value via the attr_reader-generated methods, but not the
103
+ # raw instance variable value.
104
+ # @author = options[:author]
105
+ end
106
+
107
+ # Installation skeleton. Intermediate directories are automatically
108
+ # created so don't sweat their absence here.
109
+ BASEDIRS = %w(
110
+ features
111
+ generators
112
+ lib
113
+ script
114
+ )
115
+ end
@@ -0,0 +1,8 @@
1
+ dir = File.join(File.dirname(__FILE__))
2
+ $: << File.expand_path("#{dir}/../../lib")
3
+ $: << File.expand_path(dir)
4
+
5
+ require '<%= name.downcase %>'
6
+ require 'watirmark/cucumber/env'
7
+
8
+ include <%= name.camelize %>
@@ -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,5 @@
1
+ Feature: This is a sample feature file to make sure you have everything set up properly
2
+
3
+ Scenario: Navigate to the site by hostname
4
+ Given I go to the home page
5
+ Then the url should contain "<%= name %>.com"
@@ -0,0 +1,7 @@
1
+ Given /I go to the home page/ do
2
+ Page.browser.goto "www.<%= name %>.com"
3
+ end
4
+
5
+ Then /the url should contain "(.*?)"/ do |url|
6
+ Page.browser.url.should match(url)
7
+ end
@@ -0,0 +1,9 @@
1
+ module <%= name.camelize %>
2
+ <%%= create_modules %>
3
+ class <%%= name.camelize %> < BaseController
4
+ @model = <%%= name.camelize %>Model
5
+ @view = <%%= name.camelize %>View
6
+ end
7
+ <%%= create_module_end %>
8
+ end
9
+
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ require 'rubigen'
5
+ require 'rubigen/scripts/generate'
6
+
7
+ ARGV.shift if %w(--help -h).include?(ARGV[0])
8
+ RubiGen::Base.use_component_sources! [:rubygems]
9
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,7 @@
1
+ module <%= name.camelize %>
2
+ <%%= create_modules %>
3
+ <%%= name.camelize %>Model = Watirmark::Model.factory do
4
+ keywords <%%= name.camelize %>View.keywords
5
+ end
6
+ <%%= create_module_end %>
7
+ end
@@ -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/<%= name.downcase %>/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/<%= name.downcase %>/workflows.rb" do |f|
48
+ f.puts "<%= name.camelize %>::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