stdouttoggler 0.5.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +129 -0
- data/Rakefile +5 -0
- data/bin/toggle +37 -0
- data/examples/additional_types.yaml +16 -0
- data/examples/file_names.yaml +5 -0
- data/lib/stdouttoggler/application.rb +213 -0
- data/lib/stdouttoggler/file_writer.rb +15 -0
- data/lib/stdouttoggler/regex/stdout_regex.rb +43 -0
- data/lib/stdouttoggler/types.rb +15 -0
- data/lib/stdouttoggler/types_validator.rb +53 -0
- data/lib/stdouttoggler.rb +22 -0
- data/stdouttoggler.gemspec +13 -0
- data/test/test_file_writer.rb +244 -0
- data/test/test_std_out_regex.rb +280 -0
- data/test/test_types_validator.rb +149 -0
- metadata +61 -0
data/README.txt
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
= Standard Out Toggler
|
2
|
+
|
3
|
+
Standard Out Toggler is a simple executable gem that comments and uncomments
|
4
|
+
output lines from a variety of different file types. Out of the box, this gem
|
5
|
+
handles java, javascript in .js and .jsp, and ruby files. You can configure it to handle
|
6
|
+
any file type of your choice.
|
7
|
+
|
8
|
+
== Use Case
|
9
|
+
|
10
|
+
Often when debugging, I find myself adding output statements to code,
|
11
|
+
for example alert statements to javascript code and System.out.println
|
12
|
+
statements to java code. Then I discover I need to comment out the statements
|
13
|
+
from some files, because they're cluttering up my console, or because I get tired
|
14
|
+
of crawling through javascript alerts. Later, I might need to uncomment them again.
|
15
|
+
|
16
|
+
So I wrote a straightforward ruby program to do what I needed, with support
|
17
|
+
for java and javascript.
|
18
|
+
|
19
|
+
When I decided to add JSP files to the mix, and had to hard code another set
|
20
|
+
of constants and and case statements, I realized that this was a prime opportunity
|
21
|
+
for ruby metaprogramming.
|
22
|
+
|
23
|
+
As a result, Standard Out Toggler dynamically builds support for default file types
|
24
|
+
from a config file in the lib/config directory and offers you the option
|
25
|
+
to add additional types via a YAML file in the current directory.
|
26
|
+
|
27
|
+
== Running the program
|
28
|
+
|
29
|
+
Run the executable from a directory of your choice using the stdouttoggler command.
|
30
|
+
The only required option is the instruction option (-i), which tells stdouttoggler
|
31
|
+
whether to comment or uncomment. Add one or more files as args (relative or absolute paths),
|
32
|
+
and run the program. For example:
|
33
|
+
|
34
|
+
>toggle -i comment JavaFile.java C:/programs/JavaScriptFile.js
|
35
|
+
|
36
|
+
== Command Line Options
|
37
|
+
|
38
|
+
-h Help screen.
|
39
|
+
|
40
|
+
-i <comment|uncomment> Tells stdouttoggler whether to comment or uncomment output lines.
|
41
|
+
|
42
|
+
-b Saves a backup of any changed file.
|
43
|
+
|
44
|
+
-f Tells stdouttoggler to find files for commenting or uncommenting
|
45
|
+
in a file called file_names.yaml, which you put in the current
|
46
|
+
directory. This can come in handy if you're changing a lot of files
|
47
|
+
or using files with long paths. Note that if you use this option,
|
48
|
+
you can't put any files on the command line.
|
49
|
+
|
50
|
+
-c Tells stdouttoggler that you're adding additional file types to the
|
51
|
+
default java, javascript, JSP, and ruby types, using a file called
|
52
|
+
additional_types.yaml in the current directory.
|
53
|
+
|
54
|
+
Here are some sample commands:
|
55
|
+
|
56
|
+
>stdouttoggler -i comment JavaFile.java C:/programs/JavaScriptFile.js
|
57
|
+
|
58
|
+
Comments out all System.out.print and System.out.println statements
|
59
|
+
in the java file, and all the alert statements in the javascript file.
|
60
|
+
|
61
|
+
>toggle -i uncomment JavaFile.java C:/programs/JavaScriptFile.js
|
62
|
+
|
63
|
+
Uncomments out all System.out.print and System.out.println statements
|
64
|
+
in the java file, and all the alert statements in the javascript file.
|
65
|
+
|
66
|
+
>toggle -i comment -b JavaFile.java
|
67
|
+
|
68
|
+
Comments out all System.out.print and System.out.println statements
|
69
|
+
in the java file and saves a backup (JavaFile.java.bak) of the original file.
|
70
|
+
|
71
|
+
>toggle -i comment -f
|
72
|
+
|
73
|
+
Comments out all output statements in the file_names.yaml file in your
|
74
|
+
current directory. See the Using a File section below for an explanation
|
75
|
+
of the structure of that file.
|
76
|
+
|
77
|
+
>toggle -i comment -c AnotherFileType.al
|
78
|
+
|
79
|
+
Comments out all the output statements in AnotherFileType.al
|
80
|
+
in your current directory, based on configuration instructions in
|
81
|
+
additional_types.yaml in your current directory. See the Configuration
|
82
|
+
section below for an explanation of the structure of the YAML configuration file.
|
83
|
+
|
84
|
+
>toggle -i comment -f -c
|
85
|
+
|
86
|
+
Comments out all output statements in the file_names.yaml file in your
|
87
|
+
current directory, based on configuration instructions in
|
88
|
+
additional_types.yaml in your current directory.
|
89
|
+
|
90
|
+
== Using a File
|
91
|
+
|
92
|
+
In the templates folder you'll find a sample YAML file called file_names.yaml that lists
|
93
|
+
files to comment/uncomment:
|
94
|
+
|
95
|
+
---
|
96
|
+
- JavaFile.java
|
97
|
+
- ./JavaScriptFile.js
|
98
|
+
- C:/programs/ruby/ruby_file.rb
|
99
|
+
- AnotherLanguage.al
|
100
|
+
|
101
|
+
Note that you can use relative or absolute paths.
|
102
|
+
|
103
|
+
== Configuration
|
104
|
+
|
105
|
+
In the templates folder you'll find a sample YAML configuration file called additional_types.yaml
|
106
|
+
that lists three (imaginary) additional languages for commenting/uncommenting. You can use this file
|
107
|
+
as a template for types you wish to add.
|
108
|
+
|
109
|
+
---
|
110
|
+
- :type: anotherlang
|
111
|
+
:extension: .al
|
112
|
+
:keyword: out
|
113
|
+
:comment_string: --
|
114
|
+
:comment_string_escaped: --
|
115
|
+
- :type: otherlang
|
116
|
+
:extension: .ol
|
117
|
+
:keyword: print
|
118
|
+
:comment_string: //
|
119
|
+
:comment_string_escaped: \/\/
|
120
|
+
- :type: rub
|
121
|
+
:extension: .rub
|
122
|
+
:keyword: putt
|
123
|
+
:comment_string: "#"
|
124
|
+
:comment_string_escaped: "#"
|
125
|
+
|
126
|
+
The comment_string_escaped is the tricky one. It will be used in a regular expression,
|
127
|
+
so if it contains metacharacters, they need to be escaped. Additionally, if any of the
|
128
|
+
values use a character that means something special to the ruby interpreter, such as
|
129
|
+
the hash sign, it must be put in quotation marks.
|
data/Rakefile
ADDED
data/bin/toggle
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!usr/bin/env ruby
|
2
|
+
|
3
|
+
##############################################################
|
4
|
+
# Copyright (c) 2012 Mark Buechler
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
##############################################################
|
11
|
+
|
12
|
+
###############################################
|
13
|
+
#This is the executable used to comment and
|
14
|
+
#uncomment output lines from a variety of different
|
15
|
+
#file types.
|
16
|
+
|
17
|
+
#A typical command to run the executable is as follows:
|
18
|
+
#>toggle -i comment JavaFile.java JavaScriptFile.js
|
19
|
+
|
20
|
+
#That command would comment out all System.out.print and
|
21
|
+
#System.out.println statements in the java file,
|
22
|
+
#and all the alert statements in the javascript file.
|
23
|
+
|
24
|
+
#To reactivate the output statements,
|
25
|
+
#you would run the corresponding uncomment command:
|
26
|
+
#>toggle -i uncomment JavaFile.java JavaScriptFile.js
|
27
|
+
|
28
|
+
#Out of the box, this gem handles java, javascript, jsp, and ruby files.
|
29
|
+
#Command line options are available that enable users
|
30
|
+
#to add language types, list files for commenting/uncommenting in a file
|
31
|
+
#instead of on the command line, and and create backups.
|
32
|
+
|
33
|
+
#See README for additional details.
|
34
|
+
###############################################
|
35
|
+
|
36
|
+
require 'stdouttoggler'
|
37
|
+
StdOutToggler::Application.new.run
|
@@ -0,0 +1,16 @@
|
|
1
|
+
---
|
2
|
+
- :type: anotherlang
|
3
|
+
:extension: .al
|
4
|
+
:keyword: out
|
5
|
+
:comment_string: --
|
6
|
+
:comment_string_escaped: --
|
7
|
+
- :type: otherlang
|
8
|
+
:extension: .ol
|
9
|
+
:keyword: print
|
10
|
+
:comment_string: //
|
11
|
+
:comment_string_escaped: \/\/
|
12
|
+
- :type: rub
|
13
|
+
:extension: .rub
|
14
|
+
:keyword: putt
|
15
|
+
:comment_string: "#"
|
16
|
+
:comment_string_escaped: "#"
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'stdouttoggler/types.rb'
|
2
|
+
require 'stdouttoggler/types_validator.rb'
|
3
|
+
require 'stdouttoggler/file_writer.rb'
|
4
|
+
require 'stdouttoggler/regex/stdout_regex.rb'
|
5
|
+
require 'optparse'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
module StdOutToggler
|
9
|
+
|
10
|
+
#parses and validates command line options and configuration;
|
11
|
+
#runs the application;
|
12
|
+
#key instance variables:
|
13
|
+
#@options: command line options
|
14
|
+
#@stdout_type_maps: used to generate the regex class methods
|
15
|
+
#@files: list of files to comment/uncomment
|
16
|
+
class Application
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
prepare_options
|
20
|
+
validate_instruction
|
21
|
+
prepare_files
|
22
|
+
build_stdout_type_maps
|
23
|
+
validate_stdout_type_maps
|
24
|
+
end
|
25
|
+
|
26
|
+
#parses command line options
|
27
|
+
def prepare_options
|
28
|
+
@options = {}
|
29
|
+
begin
|
30
|
+
optparse = OptionParser.new do |opts|
|
31
|
+
opts.banner = "usage: #{StdOutToggler.executable} [options] [file_paths]"
|
32
|
+
opts.on("-h", "--help", "Display help screen") do
|
33
|
+
puts opts
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
opts.on("-b", "--backup", "Keep backup file") do |b|
|
37
|
+
@options[:keep_backup] = b
|
38
|
+
end
|
39
|
+
opts.on("-i", "--instruction INSTRUCTION", "Indicate whether to comment or uncomment standard output", %w[comment uncomment]) do |i|
|
40
|
+
@options[:instruction] = i
|
41
|
+
end
|
42
|
+
opts.on("-f", "--file", "Retrieve file names from a file in the current directory called file_names.yaml, rather than as command-line args") do |f|
|
43
|
+
@options[:file] = f
|
44
|
+
end
|
45
|
+
opts.on("-c", "--config", "Configure comment out toggling for file types (other than the default java, javascript, jsp, and ruby) " +
|
46
|
+
"in a file in the current directory called additional_types.yaml") do |c|
|
47
|
+
@options[:config] = c
|
48
|
+
end
|
49
|
+
end.parse!
|
50
|
+
rescue => e
|
51
|
+
puts "Error parsing command line options: #{e.message}"
|
52
|
+
exit 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#ensures that we have the required instruction command
|
57
|
+
def validate_instruction
|
58
|
+
unless @options[:instruction]
|
59
|
+
puts "You need to have an -i (or --instruction) flag with an argument indicating comment or uncomment"
|
60
|
+
exit 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#builds the list of files designated for commenting/uncommenting
|
65
|
+
def prepare_files
|
66
|
+
if @options[:file]
|
67
|
+
unless ARGV.length == 0
|
68
|
+
puts "If you use the -f option, indicating that target files will be listed in a file, " +
|
69
|
+
"you cannot name any files on the command line"
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
begin
|
73
|
+
@files = File.open("file_names.yaml") do |f|
|
74
|
+
YAML.load(f)
|
75
|
+
end
|
76
|
+
rescue => e
|
77
|
+
puts "Your file_names.yaml file had the following error: #{e.message}"
|
78
|
+
exit 1
|
79
|
+
end
|
80
|
+
#sometimes the best we can do with YAML is ensure we get the data type back we expected
|
81
|
+
unless @files.is_a? Array
|
82
|
+
puts "Your file_names.yaml was invalid"
|
83
|
+
exit 1
|
84
|
+
end
|
85
|
+
else
|
86
|
+
unless ARGV.length > 0
|
87
|
+
puts "In the absence of the -f option, the command needs to name at least one file"
|
88
|
+
exit 1
|
89
|
+
end
|
90
|
+
@files = ARGV
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
#builds the list of type maps used to dynamically generate methods
|
95
|
+
#in the stdout_regex class
|
96
|
+
def build_stdout_type_maps
|
97
|
+
default_stdout_type_maps = [] #part of gem configuration
|
98
|
+
configured_stdout_type_maps = [] #user-defined
|
99
|
+
@stdout_type_maps = [] #merge
|
100
|
+
|
101
|
+
#grabs default file types and associated information (e.g., stdout keyword, comment-out symbol)
|
102
|
+
default_stdout_type_maps = StdOutToggler::Types.new.type_maps
|
103
|
+
|
104
|
+
#grabs user-defined file types
|
105
|
+
if @options[:config]
|
106
|
+
begin
|
107
|
+
configured_stdout_type_maps = File.open("additional_types.yaml") do |f|
|
108
|
+
YAML.load(f)
|
109
|
+
end
|
110
|
+
rescue => e
|
111
|
+
puts "Your additional_types.yaml file had the following error: #{e.message}"
|
112
|
+
exit 1
|
113
|
+
end
|
114
|
+
unless configured_stdout_type_maps.is_a? Array
|
115
|
+
puts "Your additional_types.yaml was invalid"
|
116
|
+
exit 1
|
117
|
+
end
|
118
|
+
end
|
119
|
+
#now merge and eliminate duplicates to arrive at list of type maps that
|
120
|
+
#will be used to setup our stdout regex classes
|
121
|
+
@stdout_type_maps = (default_stdout_type_maps + configured_stdout_type_maps).uniq
|
122
|
+
end
|
123
|
+
|
124
|
+
#ensures that all type maps are valid
|
125
|
+
def validate_stdout_type_maps
|
126
|
+
type_maps_validator = TypesValidator.new(@stdout_type_maps)
|
127
|
+
|
128
|
+
#makes sure the maps are all valid
|
129
|
+
begin
|
130
|
+
type_maps_validator.valid_type_maps?
|
131
|
+
rescue RuntimeError => e
|
132
|
+
puts "Your additional_types.yaml file had the following error: #{e.message}"
|
133
|
+
exit 1
|
134
|
+
end
|
135
|
+
|
136
|
+
#check files and file extensions
|
137
|
+
@files.each do |file|
|
138
|
+
unless File.file?(file)
|
139
|
+
puts "#{file} is not a file"
|
140
|
+
exit 1
|
141
|
+
end
|
142
|
+
extension = File.extname(file)
|
143
|
+
unless type_maps_validator.valid_extension? extension
|
144
|
+
puts "The file #{file} must have an extension corresponding " +
|
145
|
+
"to one of the following (based on default types and those configured in additional_types.yaml): " +
|
146
|
+
"#{type_maps_validator.valid_extensions.join(' ')}"
|
147
|
+
exit 1
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
#comment/uncomment designated files, per command line instruction
|
153
|
+
def run
|
154
|
+
@stdout_type_maps.each do |type_map|
|
155
|
+
StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(type_map)
|
156
|
+
end
|
157
|
+
|
158
|
+
begin
|
159
|
+
stdout_regex_producer = StdOutRegex::Producer.new()
|
160
|
+
|
161
|
+
#comment or uncomment each file
|
162
|
+
@files.each do |file|
|
163
|
+
type = ""
|
164
|
+
backup_file = file + ".bak"
|
165
|
+
#infer type from extension
|
166
|
+
extension = File.extname(file)
|
167
|
+
@stdout_type_maps.each do |type_map|
|
168
|
+
if (type_map[:extension] == extension)
|
169
|
+
type = type_map[:type]
|
170
|
+
break
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
#call dynamically generated method that produces regex and substitution string based on user input
|
175
|
+
stdout_regex = stdout_regex_producer.send("#{type}_#{@options[:instruction]}_regex");
|
176
|
+
|
177
|
+
#start with a fresh backup
|
178
|
+
if File.file? backup_file
|
179
|
+
File.delete backup_file
|
180
|
+
end
|
181
|
+
|
182
|
+
#original is now the backup
|
183
|
+
File.rename(file, backup_file)
|
184
|
+
|
185
|
+
#using file handles so we can pass to a testable method
|
186
|
+
#that modifies the original file according to the instruction
|
187
|
+
input_file_handle = File.new(backup_file)
|
188
|
+
output_file_handle = File.new(file, "w")
|
189
|
+
FileWriter.modify_file(input_file_handle, output_file_handle, stdout_regex)
|
190
|
+
|
191
|
+
if @options[:keep_backup]
|
192
|
+
puts "keeping backup file: #{backup_file}"
|
193
|
+
else
|
194
|
+
File.delete(backup_file)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
notify
|
199
|
+
rescue => e
|
200
|
+
puts "The application encountered the following problem: #{e.message}"
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
#displays results
|
206
|
+
def notify
|
207
|
+
file_string = @files.reduce(""){|a,file| a << (file + ", ")}.chop.chop
|
208
|
+
puts "All standard output lines in #{file_string} have been #{@options[:instruction]}ed#{@options[:instruction] == "comment" ? " out" : ""}."
|
209
|
+
end
|
210
|
+
|
211
|
+
end #end CommandLineHandler
|
212
|
+
|
213
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module StdOutToggler
|
2
|
+
|
3
|
+
#provides a clean, testable interface that
|
4
|
+
#handles the process of commenting out a file
|
5
|
+
class FileWriter
|
6
|
+
def self.modify_file(input_file_handle, output_file_handle, stdout_regex)
|
7
|
+
input_file_handle.each do |line|
|
8
|
+
output_file_handle.puts "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
9
|
+
end
|
10
|
+
input_file_handle.close()
|
11
|
+
output_file_handle.close()
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module StdOutToggler
|
2
|
+
|
3
|
+
#Given a list of maps containing information on a language type
|
4
|
+
#(file extension, output keyword, and comment string),
|
5
|
+
#the StdoutRegex module dynamically builds a Producer class
|
6
|
+
#that produces a pair of strings. One is designed for use in a regular expression that finds
|
7
|
+
#an output statement, or a commented-out output statement.
|
8
|
+
#The other is designed for use as the replacement string.
|
9
|
+
#See lib/stdouttoggler/types.rb for the default list of maps used by stdouttoggler.
|
10
|
+
module StdOutRegex
|
11
|
+
|
12
|
+
#data type for regex and substitution strings
|
13
|
+
class Holder
|
14
|
+
attr_accessor :regex_interpolation, :substitution_string_interpolation
|
15
|
+
def initialize(regex_interpolation, substitution_string_interpolation)
|
16
|
+
@regex_interpolation, @substitution_string_interpolation = regex_interpolation, substitution_string_interpolation
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
#uses dynamically generated methods to produce necessary regexes and string substitutions for files
|
21
|
+
class Producer
|
22
|
+
#From the options map argument, this macro creates methods of the form <type>_comment_regex and <type>_uncomment_regex,
|
23
|
+
#for example: java_comment_regex and java_uncomment_regex
|
24
|
+
def self.create_methods_for_producing_stdout_regex_strings (options)
|
25
|
+
type = options[:type].downcase
|
26
|
+
comment_regex_interpolation = "^(\\s*)" + options[:keyword]
|
27
|
+
comment_substitution_string_interpolation = "\\1" + options[:comment_string] + options[:keyword]
|
28
|
+
uncomment_regex_interpolation = "^(\\s*)" + options[:comment_string_escaped] + "(\\s*)" + options[:keyword]
|
29
|
+
uncomment_substitution_string_interpolation = "\\1\\2" + options[:keyword]
|
30
|
+
#comment method
|
31
|
+
define_method ("#{type}_comment_regex").to_sym do
|
32
|
+
Holder.new(comment_regex_interpolation,comment_substitution_string_interpolation)
|
33
|
+
end
|
34
|
+
#uncomment method
|
35
|
+
define_method ("#{type}_uncomment_regex").to_sym do
|
36
|
+
Holder.new(uncomment_regex_interpolation,uncomment_substitution_string_interpolation)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end #end StdOutRegex module
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module StdOutToggler
|
2
|
+
|
3
|
+
#class to hold our default file types
|
4
|
+
class Types
|
5
|
+
attr_accessor :type_maps
|
6
|
+
def initialize
|
7
|
+
@type_maps = []
|
8
|
+
type_maps[0] = {:type => "java", :extension => ".java", :keyword => "System.out.print", :comment_string => "//", :comment_string_escaped => "\\/\\/"}
|
9
|
+
type_maps[1] = {:type => "javascript", :extension => ".js", :keyword => "alert", :comment_string => "//", :comment_string_escaped => "\\/\\/"}
|
10
|
+
type_maps[2] = {:type => "jsp", :extension => ".jsp", :keyword => "alert", :comment_string => "//", :comment_string_escaped => "\\/\\/"}
|
11
|
+
type_maps[3] = {:type => "ruby", :extension => ".rb", :keyword => "puts", :comment_string => "#", :comment_string_escaped => "#"}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module StdOutToggler
|
2
|
+
|
3
|
+
#Validates the maps used to build the Producer class.
|
4
|
+
#This is important because users can add additional language types at runtime.
|
5
|
+
class TypesValidator
|
6
|
+
|
7
|
+
attr_reader :valid_extensions
|
8
|
+
|
9
|
+
def initialize(stdout_type_maps)
|
10
|
+
@valid_extensions = []
|
11
|
+
@stdout_type_maps = stdout_type_maps
|
12
|
+
@stdout_type_maps.each do |type_map|
|
13
|
+
@valid_extensions << type_map[:extension]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
#validates a file extension
|
18
|
+
def valid_extension?(extension)
|
19
|
+
@valid_extensions.include? extension
|
20
|
+
end
|
21
|
+
|
22
|
+
#validates the standard output information for each file type;
|
23
|
+
#validation rules: each option must exist, and
|
24
|
+
#extension options must be of form /^\.\w+/ (e.g., .java)
|
25
|
+
def valid_type_maps?()
|
26
|
+
@stdout_type_maps.each_with_index do |type_map|
|
27
|
+
unless (type_map[:type] && !type_map[:type].empty?)
|
28
|
+
raise "the type map with the extension #{type_map[:extension]} is missing a type"
|
29
|
+
end
|
30
|
+
unless (type_map[:keyword] && !type_map[:keyword].empty?)
|
31
|
+
raise "The type map for type #{type_map[:type]} is either missing a keyword or has an invalid keyword"
|
32
|
+
end
|
33
|
+
unless(type_map[:extension] && !type_map[:extension].empty?)
|
34
|
+
raise "The type map for type #{type_map[:type]} is missing an extension"
|
35
|
+
end
|
36
|
+
unless (type_map[:extension].match(/^\.\w+/))
|
37
|
+
raise "The extension for #{type_map[:type]} must be of the form .<ext>"
|
38
|
+
end
|
39
|
+
unless(type_map[:comment_string] && !type_map[:comment_string].empty?)
|
40
|
+
raise "The type map for type #{type_map[:type]} is either missing a comment string or has an invalid comment string. " +
|
41
|
+
"One solution may be to put quotation marks around the string."
|
42
|
+
end
|
43
|
+
unless(type_map[:comment_string_escaped] && !type_map[:comment_string_escaped].empty?)
|
44
|
+
raise "The type map for type #{type_map[:type]} is either missing an escaped comment string or has an invalid escaped comment string. " +
|
45
|
+
"One solution may be to put quotation marks around the string."
|
46
|
+
end
|
47
|
+
#otherwise we're good, return
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end #end Validator
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
##############################################################
|
2
|
+
# Copyright (c) 2012 Mark Buechler
|
3
|
+
# All rights reserved.
|
4
|
+
|
5
|
+
# Permission is granted for use, copying, modification, distribution,
|
6
|
+
# and distribution of modified versions of this work as long as the
|
7
|
+
# above copyright notice is included.
|
8
|
+
##############################################################
|
9
|
+
|
10
|
+
require 'stdouttoggler/application.rb'
|
11
|
+
require 'pathname'
|
12
|
+
|
13
|
+
#application namespace
|
14
|
+
module StdOutToggler
|
15
|
+
#returns the name of the executable file
|
16
|
+
def self.executable
|
17
|
+
bin = File.join("..", "bin")
|
18
|
+
Pathname.glob("bin/*") do |f|
|
19
|
+
name = File.basename(f)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name="stdouttoggler"
|
3
|
+
s.version="0.5.0.pre"
|
4
|
+
s.platform=Gem::Platform::RUBY
|
5
|
+
s.date="2012-09-14"
|
6
|
+
s.summary="Comments and uncomments output lines in code"
|
7
|
+
s.description="As a debugging convenience, sdtouttoggler comments and uncomments output lines, such as alert in javascript"
|
8
|
+
s.author="Mark Buechler"
|
9
|
+
s.files=Dir["stdouttoggler.gemspec", "Rakefile", "README.txt", "lib/**/*", "test/test*.rb", "examples/*.yaml"]
|
10
|
+
s.homepage="http://rubygems.org/stdouttoggler"
|
11
|
+
s.executables=["toggle"]
|
12
|
+
s.require_paths=["lib"]
|
13
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
#!usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'stdouttoggler/application.rb'
|
5
|
+
require 'stdouttoggler/types.rb'
|
6
|
+
|
7
|
+
#So here we are testing whether our FileWriter.modify_file method
|
8
|
+
#actually writes what we expect to be written
|
9
|
+
class FileWriterTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
#using the actual default type maps for the application
|
12
|
+
def setup
|
13
|
+
@stdout_type_maps = StdOutToggler::Types.new.type_maps
|
14
|
+
|
15
|
+
|
16
|
+
#puts java_file_commented
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
end #setup
|
21
|
+
|
22
|
+
def teardown
|
23
|
+
@stdout_type_maps = []
|
24
|
+
end
|
25
|
+
|
26
|
+
#####################################
|
27
|
+
def test_java
|
28
|
+
|
29
|
+
@java_file_uncommented = <<EOS
|
30
|
+
//don't touch this
|
31
|
+
|
32
|
+
public class Whatever {
|
33
|
+
|
34
|
+
private String s;
|
35
|
+
|
36
|
+
public Whatever(String s) {
|
37
|
+
System.out.println("in constructor");
|
38
|
+
this.s = s;
|
39
|
+
}
|
40
|
+
|
41
|
+
public meth1() {
|
42
|
+
s = s + "whatever";
|
43
|
+
System.out.println("s: " + s);
|
44
|
+
}
|
45
|
+
|
46
|
+
System.out.println("toto");
|
47
|
+
|
48
|
+
}
|
49
|
+
EOS
|
50
|
+
|
51
|
+
@java_file_commented = <<EOS
|
52
|
+
//don't touch this
|
53
|
+
|
54
|
+
public class Whatever {
|
55
|
+
|
56
|
+
private String s;
|
57
|
+
|
58
|
+
public Whatever(String s) {
|
59
|
+
//System.out.println("in constructor");
|
60
|
+
this.s = s;
|
61
|
+
}
|
62
|
+
|
63
|
+
public meth1() {
|
64
|
+
s = s + "whatever";
|
65
|
+
//System.out.println("s: " + s);
|
66
|
+
}
|
67
|
+
|
68
|
+
//System.out.println("toto");
|
69
|
+
|
70
|
+
}
|
71
|
+
EOS
|
72
|
+
|
73
|
+
#this is the java type map
|
74
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(@stdout_type_maps[0])
|
75
|
+
|
76
|
+
#comment
|
77
|
+
comment_regex_holder = StdOutToggler::StdOutRegex::Producer.new().java_comment_regex
|
78
|
+
input = StringIO.new(@java_file_uncommented)
|
79
|
+
output = StringIO.new
|
80
|
+
StdOutToggler::FileWriter.modify_file(input, output, comment_regex_holder)
|
81
|
+
assert_equal(@java_file_commented, output.string)
|
82
|
+
|
83
|
+
#uncomment
|
84
|
+
uncomment_regex_holder = StdOutToggler::StdOutRegex::Producer.new().java_uncomment_regex
|
85
|
+
input = StringIO.new(@java_file_commented)
|
86
|
+
output = StringIO.new
|
87
|
+
StdOutToggler::FileWriter.modify_file(input, output, uncomment_regex_holder)
|
88
|
+
assert_equal(@java_file_uncommented, output.string)
|
89
|
+
|
90
|
+
end #end java test
|
91
|
+
|
92
|
+
|
93
|
+
#####################################
|
94
|
+
def test_javascript
|
95
|
+
|
96
|
+
@javascript_file_uncommented = <<EOS
|
97
|
+
var x = 3
|
98
|
+
alert("hello");
|
99
|
+
if (x == 3) {
|
100
|
+
alert("OK");
|
101
|
+
}
|
102
|
+
alert()
|
103
|
+
EOS
|
104
|
+
|
105
|
+
@javascript_file_commented = <<EOS
|
106
|
+
var x = 3
|
107
|
+
//alert("hello");
|
108
|
+
if (x == 3) {
|
109
|
+
//alert("OK");
|
110
|
+
}
|
111
|
+
//alert()
|
112
|
+
EOS
|
113
|
+
|
114
|
+
#this is the javascript type map
|
115
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(@stdout_type_maps[1])
|
116
|
+
|
117
|
+
#comment
|
118
|
+
comment_regex_holder = StdOutToggler::StdOutRegex::Producer.new().javascript_comment_regex
|
119
|
+
input = StringIO.new(@javascript_file_uncommented)
|
120
|
+
output = StringIO.new
|
121
|
+
StdOutToggler::FileWriter.modify_file(input, output, comment_regex_holder)
|
122
|
+
assert_equal(@javascript_file_commented, output.string)
|
123
|
+
|
124
|
+
#uncomment
|
125
|
+
uncomment_regex_holder = StdOutToggler::StdOutRegex::Producer.new().javascript_uncomment_regex
|
126
|
+
input = StringIO.new(@javascript_file_commented)
|
127
|
+
output = StringIO.new
|
128
|
+
StdOutToggler::FileWriter.modify_file(input, output, uncomment_regex_holder)
|
129
|
+
assert_equal(@javascript_file_uncommented, output.string)
|
130
|
+
|
131
|
+
end #end javascript test
|
132
|
+
|
133
|
+
|
134
|
+
#####################################
|
135
|
+
def test_jsp
|
136
|
+
|
137
|
+
@jsp_file_uncommented = <<EOS
|
138
|
+
<!-- not touching this -->
|
139
|
+
|
140
|
+
<script>
|
141
|
+
var x = 3
|
142
|
+
alert("hello");
|
143
|
+
if (x == 3) {
|
144
|
+
alert("OK");
|
145
|
+
}
|
146
|
+
alert();
|
147
|
+
</script>
|
148
|
+
|
149
|
+
<h3>Hello</h3>
|
150
|
+
|
151
|
+
<%
|
152
|
+
System.out.println("don't touch this");
|
153
|
+
%>
|
154
|
+
EOS
|
155
|
+
|
156
|
+
@jsp_file_commented = <<EOS
|
157
|
+
<!-- not touching this -->
|
158
|
+
|
159
|
+
<script>
|
160
|
+
var x = 3
|
161
|
+
//alert("hello");
|
162
|
+
if (x == 3) {
|
163
|
+
//alert("OK");
|
164
|
+
}
|
165
|
+
//alert();
|
166
|
+
</script>
|
167
|
+
|
168
|
+
<h3>Hello</h3>
|
169
|
+
|
170
|
+
<%
|
171
|
+
System.out.println("don't touch this");
|
172
|
+
%>
|
173
|
+
EOS
|
174
|
+
|
175
|
+
#this is the jsp type map
|
176
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(@stdout_type_maps[2])
|
177
|
+
|
178
|
+
#comment
|
179
|
+
jsp_comment_regex_holder = StdOutToggler::StdOutRegex::Producer.new().jsp_comment_regex
|
180
|
+
input = StringIO.new(@jsp_file_uncommented)
|
181
|
+
output = StringIO.new
|
182
|
+
StdOutToggler::FileWriter.modify_file(input, output, jsp_comment_regex_holder)
|
183
|
+
assert_equal(@jsp_file_commented, output.string)
|
184
|
+
|
185
|
+
#uncomment
|
186
|
+
jsp_uncomment_regex_holder = StdOutToggler::StdOutRegex::Producer.new().jsp_uncomment_regex
|
187
|
+
input = StringIO.new(@jsp_file_commented)
|
188
|
+
output = StringIO.new
|
189
|
+
StdOutToggler::FileWriter.modify_file(input, output, jsp_uncomment_regex_holder)
|
190
|
+
assert_equal(@jsp_file_uncommented, output.string)
|
191
|
+
|
192
|
+
end #end jsp test
|
193
|
+
|
194
|
+
#####################################
|
195
|
+
def test_ruby
|
196
|
+
|
197
|
+
@ruby_file_uncommented = <<EOS
|
198
|
+
#don't touch this
|
199
|
+
|
200
|
+
s = "hello"
|
201
|
+
|
202
|
+
def meth1
|
203
|
+
puts "chase"
|
204
|
+
return false
|
205
|
+
end
|
206
|
+
|
207
|
+
puts "finished"
|
208
|
+
EOS
|
209
|
+
|
210
|
+
@ruby_file_commented = <<EOS
|
211
|
+
#don't touch this
|
212
|
+
|
213
|
+
s = "hello"
|
214
|
+
|
215
|
+
def meth1
|
216
|
+
#puts "chase"
|
217
|
+
return false
|
218
|
+
end
|
219
|
+
|
220
|
+
#puts "finished"
|
221
|
+
EOS
|
222
|
+
|
223
|
+
#this is the ruby type map
|
224
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(@stdout_type_maps[3])
|
225
|
+
|
226
|
+
#comment
|
227
|
+
ruby_comment_regex_holder = StdOutToggler::StdOutRegex::Producer.new().ruby_comment_regex
|
228
|
+
input = StringIO.new(@ruby_file_uncommented)
|
229
|
+
output = StringIO.new
|
230
|
+
StdOutToggler::FileWriter.modify_file(input, output, ruby_comment_regex_holder)
|
231
|
+
assert_equal(@ruby_file_commented, output.string)
|
232
|
+
|
233
|
+
#uncomment
|
234
|
+
ruby_uncomment_regex_holder = StdOutToggler::StdOutRegex::Producer.new().ruby_uncomment_regex
|
235
|
+
input = StringIO.new(@ruby_file_commented)
|
236
|
+
output = StringIO.new
|
237
|
+
StdOutToggler::FileWriter.modify_file(input, output, ruby_uncomment_regex_holder)
|
238
|
+
assert_equal(@ruby_file_uncommented, output.string)
|
239
|
+
|
240
|
+
end #end ruby test
|
241
|
+
|
242
|
+
|
243
|
+
|
244
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
#!usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'stdouttoggler/regex/stdout_regex.rb'
|
5
|
+
require 'stdouttoggler/types_validator.rb'
|
6
|
+
|
7
|
+
class TypesValidatorTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
#config maps for testing
|
10
|
+
#(these aren't real php and python characteristics, just using made up ones for testing)
|
11
|
+
def setup
|
12
|
+
@stdout_type_maps = []
|
13
|
+
@stdout_type_maps[0] = {:type => "PHP", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
14
|
+
@stdout_type_maps[1] = {:type => "Python", :extension => ".py", :keyword => "pp", :comment_string => "//", :comment_string_escaped => "\/\/"}
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
@stdout_type_maps = []
|
19
|
+
end
|
20
|
+
|
21
|
+
#making sure that the class macro is generating the correct methods
|
22
|
+
def test_respond_to
|
23
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(@stdout_type_maps[0])
|
24
|
+
crp = StdOutToggler::StdOutRegex::Producer.new()
|
25
|
+
assert(crp.respond_to? "php_comment_regex")
|
26
|
+
assert(crp.respond_to? "php_uncomment_regex")
|
27
|
+
end
|
28
|
+
|
29
|
+
#calling generated methods
|
30
|
+
def test_direct_method_calls
|
31
|
+
|
32
|
+
#php
|
33
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(@stdout_type_maps[0])
|
34
|
+
crp = StdOutToggler::StdOutRegex::Producer.new()
|
35
|
+
comment_regex_holder = crp.php_comment_regex() #I know what this method is called by examining variables in the test map
|
36
|
+
assert_equal("^(\\s*)printout", comment_regex_holder.regex_interpolation, "keyword for php comment should be printout")
|
37
|
+
assert_equal("\\1@@printout", comment_regex_holder.substitution_string_interpolation, "substitution string for php uncomment should be @@printout")
|
38
|
+
uncomment_regex_holder = crp.php_uncomment_regex() #I know what this method is called by examining variables in the test map
|
39
|
+
assert_equal("^(\\s*)@@(\\s*)printout", uncomment_regex_holder.regex_interpolation, "keyword for php uncomment should be @@printout")
|
40
|
+
assert_equal("\\1\\2printout", uncomment_regex_holder.substitution_string_interpolation, "substitution string for php uncomment should be printout")
|
41
|
+
|
42
|
+
#python
|
43
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(@stdout_type_maps[1])
|
44
|
+
crp = StdOutToggler::StdOutRegex::Producer.new()
|
45
|
+
comment_regex_holder = crp.python_comment_regex() #I know what this method is called by examining variables in the test map
|
46
|
+
assert_equal("^(\\s*)pp", comment_regex_holder.regex_interpolation, "keyword for python should be pp")
|
47
|
+
assert_equal("\\1//pp", comment_regex_holder.substitution_string_interpolation, "substitution string for python should be pp")
|
48
|
+
uncomment_regex_holder = crp.python_uncomment_regex()
|
49
|
+
assert_equal("^(\\s*)\/\/(\\s*)pp", uncomment_regex_holder.regex_interpolation, "keyword for python should be \/\/pp")
|
50
|
+
assert_equal("\\1\\2pp", uncomment_regex_holder.substitution_string_interpolation, "substitution string for python should be pp")
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
#testing same methods as the test_direct_method_calls, just making sure we
|
55
|
+
#can use send, because that's what the executable will use
|
56
|
+
def test_indirect_method_calls
|
57
|
+
|
58
|
+
#php
|
59
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(@stdout_type_maps[0])
|
60
|
+
crp = StdOutToggler::StdOutRegex::Producer.new()
|
61
|
+
comment_regex_holder = crp.send("php_comment_regex") #I know what this method is called by examining variables in the test map
|
62
|
+
assert_equal("^(\\s*)printout", comment_regex_holder.regex_interpolation, "keyword for php comment should be printout")
|
63
|
+
assert_equal("\\1@@printout", comment_regex_holder.substitution_string_interpolation, "substitution string for php uncomment should be @@printout")
|
64
|
+
uncomment_regex_holder = crp.send("php_uncomment_regex") #I know what this method is called by examining variables in the test map
|
65
|
+
assert_equal("^(\\s*)@@(\\s*)printout", uncomment_regex_holder.regex_interpolation, "keyword for php uncomment should be @@printout")
|
66
|
+
assert_equal("\\1\\2printout", uncomment_regex_holder.substitution_string_interpolation, "substitution string for php uncomment should be printout")
|
67
|
+
|
68
|
+
#python
|
69
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(@stdout_type_maps[1])
|
70
|
+
crp = StdOutToggler::StdOutRegex::Producer.new()
|
71
|
+
comment_regex_holder = crp.send("python_comment_regex") #I know what this method is called by examining variables in the test map
|
72
|
+
assert_equal("^(\\s*)pp", comment_regex_holder.regex_interpolation, "keyword for python should be pp")
|
73
|
+
assert_equal("\\1//pp", comment_regex_holder.substitution_string_interpolation, "substitution string for python should be pp")
|
74
|
+
uncomment_regex_holder = crp.send("python_uncomment_regex")
|
75
|
+
assert_equal("^(\\s*)\/\/(\\s*)pp", uncomment_regex_holder.regex_interpolation, "keyword for python should be \/\/pp")
|
76
|
+
assert_equal("\\1\\2pp", uncomment_regex_holder.substitution_string_interpolation, "substitution string for python should be pp")
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
#making sure we can use a list of maps
|
81
|
+
def test_list_of_maps
|
82
|
+
|
83
|
+
@stdout_type_maps.each do |type_map|
|
84
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(type_map)
|
85
|
+
end
|
86
|
+
|
87
|
+
#our object should now be completely set up
|
88
|
+
|
89
|
+
#php
|
90
|
+
crp = StdOutToggler::StdOutRegex::Producer.new()
|
91
|
+
comment_regex_holder = crp.send("php_comment_regex") #I know what this method is called by examining variables in the test map
|
92
|
+
assert_equal("^(\\s*)printout", comment_regex_holder.regex_interpolation, "keyword for php comment should be printout")
|
93
|
+
assert_equal("\\1@@printout", comment_regex_holder.substitution_string_interpolation, "substitution string for php uncomment should be @@printout")
|
94
|
+
uncomment_regex_holder = crp.send("php_uncomment_regex") #I know what this method is called by examining variables in the test map
|
95
|
+
assert_equal("^(\\s*)@@(\\s*)printout", uncomment_regex_holder.regex_interpolation, "keyword for php uncomment should be @@printout")
|
96
|
+
assert_equal("\\1\\2printout", uncomment_regex_holder.substitution_string_interpolation, "substitution string for php uncomment should be printout")
|
97
|
+
|
98
|
+
#python
|
99
|
+
crp = StdOutToggler::StdOutRegex::Producer.new()
|
100
|
+
comment_regex_holder = crp.send("python_comment_regex") #I know what this method is called by examining variables in the test map
|
101
|
+
assert_equal("^(\\s*)pp", comment_regex_holder.regex_interpolation, "keyword for python should be pp")
|
102
|
+
assert_equal("\\1//pp", comment_regex_holder.substitution_string_interpolation, "substitution string for python should be pp")
|
103
|
+
uncomment_regex_holder = crp.send("python_uncomment_regex")
|
104
|
+
assert_equal("^(\\s*)\/\/(\\s*)pp", uncomment_regex_holder.regex_interpolation, "keyword for python should be \/\/pp")
|
105
|
+
assert_equal("\\1\\2pp", uncomment_regex_holder.substitution_string_interpolation, "substitution string for python should be pp")
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
#we're not testing the API here, just testing (and demonstrating)
|
110
|
+
#the way the stdout classes use regexes to support commenting:
|
111
|
+
#the basic regex we're building dynamically for comment is something such as:
|
112
|
+
# /^(\s*)puts/
|
113
|
+
#the basic pattern for the substitution string is:
|
114
|
+
# "\\1#puts" (preserve spaces, add comment-out string)
|
115
|
+
#we're testing with a variety of spacing patterns
|
116
|
+
def test_comment_regex
|
117
|
+
|
118
|
+
line = "puts"
|
119
|
+
result = line.sub(/^(\s*)puts/,"\\1#puts")
|
120
|
+
assert_equal("#puts", result)
|
121
|
+
|
122
|
+
line = " puts" #space
|
123
|
+
result = line.sub(/^(\s*)puts/,"\\1#puts")
|
124
|
+
assert_equal(" #puts", result)
|
125
|
+
|
126
|
+
line = " puts" #tab
|
127
|
+
result = line.sub(/^(\s*)puts/,"\\1#puts")
|
128
|
+
assert_equal(" #puts", result)
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
#we're not testing the API here, just testing (and demonstrating)
|
134
|
+
#the way the stdout classes use regexes to support uncommenting:
|
135
|
+
#the basic regex we're building dynamically for uncomment is something such as:
|
136
|
+
# /^(\s*)#(\s*)puts/ #because we have to capture spaces after the comment string as well as before
|
137
|
+
#the basic pattern for the substitution string is:
|
138
|
+
# "\\1\\2puts" (preserve spaces, add comment-out string)
|
139
|
+
#we're testing with a variety of spacing patterns
|
140
|
+
def test_uncomment_regex
|
141
|
+
|
142
|
+
line = "puts"
|
143
|
+
result = line.sub(/^(\s*)puts/,"\\1#puts")
|
144
|
+
assert_equal("#puts", result)
|
145
|
+
|
146
|
+
line = " puts" #space
|
147
|
+
result = line.sub(/^(\s*)puts/,"\\1#puts")
|
148
|
+
assert_equal(" #puts", result)
|
149
|
+
|
150
|
+
line = " puts" #tab
|
151
|
+
result = line.sub(/^(\s*)puts/,"\\1#puts")
|
152
|
+
assert_equal(" #puts", result)
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
#these are the key tests, which build a stdout class according
|
157
|
+
#to provided data and apply regexes and substitutions from the class
|
158
|
+
#to actual strings
|
159
|
+
|
160
|
+
def test_comment_using_sample_lines
|
161
|
+
@stdout_type_maps.each do |type_map|
|
162
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(type_map)
|
163
|
+
end
|
164
|
+
stdout_regex_producer = StdOutToggler::StdOutRegex::Producer.new()
|
165
|
+
|
166
|
+
#"PHP comment"
|
167
|
+
stdout_regex = stdout_regex_producer.send("php_comment_regex");
|
168
|
+
|
169
|
+
line = "printout"
|
170
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
171
|
+
assert_equal("@@printout", result)
|
172
|
+
|
173
|
+
#test with tab
|
174
|
+
line = " printout"
|
175
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
176
|
+
assert_equal(" @@printout", result)
|
177
|
+
|
178
|
+
#test with 3 spaces
|
179
|
+
line = " printout"
|
180
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
181
|
+
assert_equal(" @@printout", result)
|
182
|
+
|
183
|
+
#"python comment"
|
184
|
+
stdout_regex = stdout_regex_producer.send("python_comment_regex");
|
185
|
+
|
186
|
+
line = "pp"
|
187
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
188
|
+
assert_equal("//pp", result)
|
189
|
+
|
190
|
+
#test with tab
|
191
|
+
line = " pp"
|
192
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
193
|
+
assert_equal(" //pp", result)
|
194
|
+
|
195
|
+
#test with 3 spaces
|
196
|
+
line = " pp"
|
197
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
198
|
+
assert_equal(" //pp", result)
|
199
|
+
|
200
|
+
#make sure nothing changes if the lines are already commented out
|
201
|
+
#and I run the comment method
|
202
|
+
stdout_regex = stdout_regex_producer.send("php_comment_regex");
|
203
|
+
|
204
|
+
line = "@@printout"
|
205
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
206
|
+
assert_equal("@@printout", result)
|
207
|
+
|
208
|
+
#test with tab
|
209
|
+
line = " @@printout"
|
210
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
211
|
+
assert_equal(" @@printout", result)
|
212
|
+
|
213
|
+
#test with 3 spaces
|
214
|
+
line = " @@printout"
|
215
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
216
|
+
assert_equal(" @@printout", result)
|
217
|
+
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_uncomment_using_sample_lines
|
221
|
+
@stdout_type_maps.each do |type_map|
|
222
|
+
StdOutToggler::StdOutRegex::Producer.create_methods_for_producing_stdout_regex_strings(type_map)
|
223
|
+
end
|
224
|
+
stdout_regex_producer = StdOutToggler::StdOutRegex::Producer.new()
|
225
|
+
|
226
|
+
#"PHP uncomment"
|
227
|
+
stdout_regex = stdout_regex_producer.send("php_uncomment_regex");
|
228
|
+
|
229
|
+
line = "@@printout"
|
230
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
231
|
+
assert_equal("printout", result)
|
232
|
+
|
233
|
+
#test with tab
|
234
|
+
line = " @@printout"
|
235
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
236
|
+
assert_equal(" printout", result)
|
237
|
+
|
238
|
+
#test with 3 spaces
|
239
|
+
line = " @@printout"
|
240
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
241
|
+
assert_equal(" printout", result)
|
242
|
+
|
243
|
+
#"python uncomment"
|
244
|
+
stdout_regex = stdout_regex_producer.send("python_uncomment_regex");
|
245
|
+
|
246
|
+
line = "//pp"
|
247
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
248
|
+
assert_equal("pp", result)
|
249
|
+
|
250
|
+
#test with tab
|
251
|
+
line = " //pp"
|
252
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
253
|
+
assert_equal(" pp", result)
|
254
|
+
|
255
|
+
#test with 3 spaces
|
256
|
+
line = " //pp"
|
257
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
258
|
+
assert_equal(" pp", result)
|
259
|
+
|
260
|
+
#make sure nothing changes if the lines are already uncommented
|
261
|
+
#and I run the uncomment method
|
262
|
+
stdout_regex = stdout_regex_producer.send("php_uncomment_regex");
|
263
|
+
|
264
|
+
line = "printout"
|
265
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
266
|
+
assert_equal("printout", result)
|
267
|
+
|
268
|
+
#test with tab
|
269
|
+
line = " printout"
|
270
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
271
|
+
assert_equal(" printout", result)
|
272
|
+
|
273
|
+
#test with 3 spaces
|
274
|
+
line = " printout"
|
275
|
+
result = "#{line.sub(/#{stdout_regex.regex_interpolation}/, "#{stdout_regex.substitution_string_interpolation}")}"
|
276
|
+
assert_equal(" printout", result)
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#!usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'stdouttoggler/types_validator.rb'
|
5
|
+
|
6
|
+
class StdOutRegexTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
#config maps for testing
|
9
|
+
#(these aren't real php and python characteristics, just using made up ones for testing)
|
10
|
+
def setup
|
11
|
+
@stdout_type_maps = []
|
12
|
+
@stdout_type_maps[0] = {:type => "PHP", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
13
|
+
@stdout_type_maps[1] = {:type => "Python", :extension => ".py", :keyword => "pp", :comment_string => "//", :comment_string_escaped => "\/\/"}
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
@stdout_type_maps = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_valid_extensions
|
21
|
+
crp = StdOutToggler::TypesValidator.new(@stdout_type_maps)
|
22
|
+
assert(crp.respond_to? "valid_extension?")
|
23
|
+
assert(crp.valid_extension?(".php"))
|
24
|
+
assert(crp.valid_extension?(".py"))
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_valid_type_maps
|
28
|
+
assert(StdOutToggler::TypesValidator.new(@stdout_type_maps).valid_type_maps?())
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_invalid_type_map_missing_type
|
32
|
+
|
33
|
+
#nil
|
34
|
+
stdout_type_maps_with_typeless_map = []
|
35
|
+
stdout_type_maps_with_typeless_map[0] = {:extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
36
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
37
|
+
assert_equal("the type map with the extension .php is missing a type", exception.message)
|
38
|
+
|
39
|
+
#empty
|
40
|
+
stdout_type_maps_with_typeless_map = []
|
41
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
42
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
43
|
+
assert_equal("the type map with the extension .php is missing a type", exception.message)
|
44
|
+
|
45
|
+
#make sure we get the index right
|
46
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
47
|
+
stdout_type_maps_with_typeless_map[1] = {:extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
48
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
49
|
+
assert_equal("the type map with the extension .php is missing a type", exception.message)
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_invalid_type_map_missing_keyword
|
54
|
+
|
55
|
+
#nil
|
56
|
+
stdout_type_maps_with_typeless_map = []
|
57
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
58
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :comment_string => "@@", :comment_string_escaped => "@@"}
|
59
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
60
|
+
assert_equal("The type map for type whatever2 is either missing a keyword or has an invalid keyword", exception.message)
|
61
|
+
|
62
|
+
#empty
|
63
|
+
stdout_type_maps_with_typeless_map = []
|
64
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".php", :keyword => "", :comment_string => "@@", :comment_string_escaped => "@@"}
|
65
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
66
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
67
|
+
assert_equal("The type map for type whatever1 is either missing a keyword or has an invalid keyword", exception.message)
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_invalid_type_map_missing_extension
|
72
|
+
|
73
|
+
#nil
|
74
|
+
stdout_type_maps_with_typeless_map = []
|
75
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
76
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :keyword => "printout", :comment_string_escaped => "@@"}
|
77
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
78
|
+
assert_equal("The type map for type whatever2 is either missing a comment string or has an invalid comment string. One solution may be to put quotation marks around the string.", exception.message)
|
79
|
+
|
80
|
+
#empty
|
81
|
+
stdout_type_maps_with_typeless_map = []
|
82
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".php", :keyword => "printout", :comment_string => "", :comment_string_escaped => "@@"}
|
83
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
84
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
85
|
+
assert_equal("The type map for type whatever1 is either missing a comment string or has an invalid comment string. One solution may be to put quotation marks around the string.", exception.message)
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_invalid_type_map_invalid_extension
|
90
|
+
|
91
|
+
#no dot
|
92
|
+
stdout_type_maps_with_typeless_map = []
|
93
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
94
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => "php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
95
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
96
|
+
assert_equal("The extension for whatever2 must be of the form .<ext>", exception.message)
|
97
|
+
|
98
|
+
#nothing after dot
|
99
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
100
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
101
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
102
|
+
assert_equal("The extension for whatever1 must be of the form .<ext>", exception.message)
|
103
|
+
|
104
|
+
#invalid characters
|
105
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".&&&", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
106
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
107
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
108
|
+
assert_equal("The extension for whatever1 must be of the form .<ext>", exception.message)
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
def test_invalid_type_map_missing_comment_string
|
114
|
+
|
115
|
+
#nil
|
116
|
+
stdout_type_maps_with_typeless_map = []
|
117
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
118
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :keyword => "printout", :comment_string_escaped => "@@"}
|
119
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
120
|
+
assert_equal("The type map for type whatever2 is either missing a comment string or has an invalid comment string. One solution may be to put quotation marks around the string.", exception.message)
|
121
|
+
|
122
|
+
#empty
|
123
|
+
stdout_type_maps_with_typeless_map = []
|
124
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".php", :keyword => "printout", :comment_string => "", :comment_string_escaped => "@@"}
|
125
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
126
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
127
|
+
assert_equal("The type map for type whatever1 is either missing a comment string or has an invalid comment string. One solution may be to put quotation marks around the string.", exception.message)
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_invalid_type_map_missing_comment_string_escaped
|
132
|
+
|
133
|
+
#nil
|
134
|
+
stdout_type_maps_with_typeless_map = []
|
135
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
136
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :keyword => "printout", :comment_string => "@@"}
|
137
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
138
|
+
assert_equal("The type map for type whatever2 is either missing an escaped comment string or has an invalid escaped comment string. One solution may be to put quotation marks around the string.", exception.message)
|
139
|
+
|
140
|
+
#empty
|
141
|
+
stdout_type_maps_with_typeless_map = []
|
142
|
+
stdout_type_maps_with_typeless_map[0] = {:type => "whatever1", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => ""}
|
143
|
+
stdout_type_maps_with_typeless_map[1] = {:type => "whatever2", :extension => ".php", :keyword => "printout", :comment_string => "@@", :comment_string_escaped => "@@"}
|
144
|
+
exception = assert_raise(RuntimeError) {StdOutToggler::TypesValidator.new(stdout_type_maps_with_typeless_map).valid_type_maps?()}
|
145
|
+
assert_equal("The type map for type whatever1 is either missing an escaped comment string or has an invalid escaped comment string. One solution may be to put quotation marks around the string.", exception.message)
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stdouttoggler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0.pre
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mark Buechler
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-14 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: As a debugging convenience, sdtouttoggler comments and uncomments output
|
15
|
+
lines, such as alert in javascript
|
16
|
+
email:
|
17
|
+
executables:
|
18
|
+
- toggle
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- stdouttoggler.gemspec
|
23
|
+
- Rakefile
|
24
|
+
- README.txt
|
25
|
+
- lib/stdouttoggler/application.rb
|
26
|
+
- lib/stdouttoggler/file_writer.rb
|
27
|
+
- lib/stdouttoggler/regex/stdout_regex.rb
|
28
|
+
- lib/stdouttoggler/types.rb
|
29
|
+
- lib/stdouttoggler/types_validator.rb
|
30
|
+
- lib/stdouttoggler.rb
|
31
|
+
- test/test_file_writer.rb
|
32
|
+
- test/test_std_out_regex.rb
|
33
|
+
- test/test_types_validator.rb
|
34
|
+
- examples/additional_types.yaml
|
35
|
+
- examples/file_names.yaml
|
36
|
+
- bin/toggle
|
37
|
+
homepage: http://rubygems.org/stdouttoggler
|
38
|
+
licenses: []
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>'
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.3.1
|
55
|
+
requirements: []
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.8.24
|
58
|
+
signing_key:
|
59
|
+
specification_version: 3
|
60
|
+
summary: Comments and uncomments output lines in code
|
61
|
+
test_files: []
|