lucid 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +30 -10
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -2
- data/HISTORY.md +22 -0
- data/{LICENSE.txt → LICENSE} +6 -3
- data/README.md +22 -8
- data/Rakefile +2 -1
- data/bin/lucid +10 -10
- data/bin/lucid-gen +4 -0
- data/lib/autotest/discover.rb +11 -0
- data/lib/autotest/lucid.rb +6 -0
- data/lib/autotest/lucid_mixin.rb +135 -0
- data/lib/autotest/lucid_rails.rb +6 -0
- data/lib/autotest/lucid_rails_rspec.rb +6 -0
- data/lib/autotest/lucid_rails_rspec2.rb +6 -0
- data/lib/autotest/lucid_rspec.rb +6 -0
- data/lib/autotest/lucid_rspec2.rb +6 -0
- data/lib/lucid.rb +32 -1
- data/lib/lucid/ast.rb +20 -0
- data/lib/lucid/ast/background.rb +116 -0
- data/lib/lucid/ast/comment.rb +24 -0
- data/lib/lucid/ast/doc_string.rb +44 -0
- data/lib/lucid/ast/empty_background.rb +33 -0
- data/lib/lucid/ast/examples.rb +49 -0
- data/lib/lucid/ast/feature.rb +99 -0
- data/lib/lucid/ast/has_steps.rb +74 -0
- data/lib/lucid/ast/location.rb +41 -0
- data/lib/lucid/ast/multiline_argument.rb +31 -0
- data/lib/lucid/ast/names.rb +13 -0
- data/lib/lucid/ast/outline_table.rb +194 -0
- data/lib/lucid/ast/scenario.rb +103 -0
- data/lib/lucid/ast/scenario_outline.rb +144 -0
- data/lib/lucid/ast/specs.rb +38 -0
- data/lib/lucid/ast/step.rb +122 -0
- data/lib/lucid/ast/step_collection.rb +92 -0
- data/lib/lucid/ast/step_invocation.rb +196 -0
- data/lib/lucid/ast/table.rb +730 -0
- data/lib/lucid/ast/tags.rb +28 -0
- data/lib/lucid/ast/tdl_walker.rb +195 -0
- data/lib/lucid/cli/app.rb +78 -0
- data/lib/lucid/cli/configuration.rb +261 -0
- data/lib/lucid/cli/options.rb +463 -0
- data/lib/lucid/cli/profile.rb +101 -0
- data/lib/lucid/configuration.rb +53 -0
- data/lib/lucid/core_ext/disable_autorunners.rb +15 -0
- data/lib/lucid/core_ext/instance_exec.rb +70 -0
- data/lib/lucid/core_ext/proc.rb +36 -0
- data/lib/lucid/core_ext/string.rb +9 -0
- data/lib/lucid/errors.rb +40 -0
- data/lib/lucid/factory.rb +43 -0
- data/lib/lucid/formatter/ansicolor.rb +168 -0
- data/lib/lucid/formatter/console.rb +218 -0
- data/lib/lucid/formatter/debug.rb +33 -0
- data/lib/lucid/formatter/duration.rb +11 -0
- data/lib/lucid/formatter/gherkin_formatter_adapter.rb +94 -0
- data/lib/lucid/formatter/gpretty.rb +24 -0
- data/lib/lucid/formatter/html.rb +610 -0
- data/lib/lucid/formatter/interceptor.rb +66 -0
- data/lib/lucid/formatter/io.rb +31 -0
- data/lib/lucid/formatter/jquery-min.js +154 -0
- data/lib/lucid/formatter/json.rb +19 -0
- data/lib/lucid/formatter/json_pretty.rb +10 -0
- data/lib/lucid/formatter/junit.rb +177 -0
- data/lib/lucid/formatter/lucid.css +283 -0
- data/lib/lucid/formatter/lucid.sass +244 -0
- data/lib/lucid/formatter/ordered_xml_markup.rb +24 -0
- data/lib/lucid/formatter/progress.rb +95 -0
- data/lib/lucid/formatter/rerun.rb +91 -0
- data/lib/lucid/formatter/standard.rb +235 -0
- data/lib/lucid/formatter/stepdefs.rb +14 -0
- data/lib/lucid/formatter/steps.rb +49 -0
- data/lib/lucid/formatter/summary.rb +35 -0
- data/lib/lucid/formatter/unicode.rb +53 -0
- data/lib/lucid/formatter/usage.rb +132 -0
- data/lib/lucid/generator.rb +21 -0
- data/lib/lucid/generators/project.rb +70 -0
- data/lib/lucid/generators/project/Gemfile.tt +6 -0
- data/lib/lucid/generators/project/browser-symbiont.rb +24 -0
- data/lib/lucid/generators/project/driver-symbiont.rb +4 -0
- data/lib/lucid/generators/project/errors.rb +26 -0
- data/lib/lucid/generators/project/events-symbiont.rb +36 -0
- data/lib/lucid/generators/project/lucid-symbiont.yml +6 -0
- data/lib/lucid/interface.rb +8 -0
- data/lib/lucid/interface_methods.rb +125 -0
- data/lib/lucid/interface_rb/matcher.rb +108 -0
- data/lib/lucid/interface_rb/rb_hook.rb +18 -0
- data/lib/lucid/interface_rb/rb_language.rb +190 -0
- data/lib/lucid/interface_rb/rb_lucid.rb +119 -0
- data/lib/lucid/interface_rb/rb_step_definition.rb +122 -0
- data/lib/lucid/interface_rb/rb_transform.rb +57 -0
- data/lib/lucid/interface_rb/rb_world.rb +136 -0
- data/lib/lucid/interface_rb/regexp_argument_matcher.rb +21 -0
- data/lib/lucid/load_path.rb +13 -0
- data/lib/lucid/parser.rb +2 -126
- data/lib/lucid/platform.rb +27 -0
- data/lib/lucid/rspec/allow_doubles.rb +20 -0
- data/lib/lucid/rspec/disallow_options.rb +27 -0
- data/lib/lucid/runtime.rb +200 -0
- data/lib/lucid/runtime/facade.rb +60 -0
- data/lib/lucid/runtime/interface_io.rb +60 -0
- data/lib/lucid/runtime/orchestrator.rb +218 -0
- data/lib/lucid/runtime/results.rb +64 -0
- data/lib/lucid/runtime/specs_loader.rb +79 -0
- data/lib/lucid/spec_file.rb +112 -0
- data/lib/lucid/step_definition_light.rb +20 -0
- data/lib/lucid/step_definitions.rb +13 -0
- data/lib/lucid/step_match.rb +99 -0
- data/lib/lucid/tdl_builder.rb +282 -0
- data/lib/lucid/term/ansicolor.rb +118 -0
- data/lib/lucid/unit.rb +11 -0
- data/lib/lucid/wire_support/configuration.rb +38 -0
- data/lib/lucid/wire_support/connection.rb +61 -0
- data/lib/lucid/wire_support/request_handler.rb +32 -0
- data/lib/lucid/wire_support/wire_exception.rb +32 -0
- data/lib/lucid/wire_support/wire_language.rb +54 -0
- data/lib/lucid/wire_support/wire_packet.rb +34 -0
- data/lib/lucid/wire_support/wire_protocol.rb +43 -0
- data/lib/lucid/wire_support/wire_protocol/requests.rb +125 -0
- data/lib/lucid/wire_support/wire_step_definition.rb +26 -0
- data/lucid.gemspec +25 -14
- metadata +220 -12
- data/lib/lucid/app.rb +0 -103
- data/lib/lucid/options.rb +0 -168
- data/lib/lucid/version.rb +0 -3
- data/lucid.yml +0 -8
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Lucid
|
4
|
+
module CLI
|
5
|
+
class Profile
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@lucid_yml = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def args_from(profile)
|
12
|
+
unless lucid_yml.has_key?(profile)
|
13
|
+
raise(ProfileNotFound, <<-END_OF_ERROR)
|
14
|
+
Could not find profile: '#{profile}'
|
15
|
+
|
16
|
+
Defined profiles in lucid.yml:
|
17
|
+
* #{lucid_yml.keys.sort.join("\n * ")}
|
18
|
+
END_OF_ERROR
|
19
|
+
end
|
20
|
+
|
21
|
+
args_from_yml = lucid_yml[profile] || ''
|
22
|
+
|
23
|
+
case(args_from_yml)
|
24
|
+
when String
|
25
|
+
raise YmlLoadError, ["The '#{profile}' profile in lucid.yml was blank. You must define",
|
26
|
+
"command line arguments if you are are going to include a profile",
|
27
|
+
"in lucid.yml.\n"].join("\n") if args_from_yml =~ /^\s*$/
|
28
|
+
if(Lucid::WINDOWS)
|
29
|
+
args_from_yml = args_from_yml.split
|
30
|
+
args_from_yml = args_from_yml.collect {|x| x.gsub(/^\"(.*)\"/,'\1') }
|
31
|
+
else
|
32
|
+
require 'shellwords'
|
33
|
+
args_from_yml = Shellwords.shellwords(args_from_yml)
|
34
|
+
end
|
35
|
+
when Array
|
36
|
+
raise YmlLoadError, ["The '#{profile}' profile in lucid.yml contained an empty array.",
|
37
|
+
"You must define any command line arguments within the array.\n"].join("\n") if args_from_yml.empty?
|
38
|
+
else
|
39
|
+
raise YmlLoadError, ["The '#{profile}' profile in lucid.yml was a #{args_from_yml.class}.",
|
40
|
+
"A profile must be a a String or an Array."].join("\n")
|
41
|
+
end
|
42
|
+
args_from_yml
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_profile?(profile)
|
46
|
+
lucid_yml.has_key?(profile)
|
47
|
+
end
|
48
|
+
|
49
|
+
def lucid_yml_defined?
|
50
|
+
lucid_file && File.exist?(lucid_file)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Loads the profile, processing it through ERB and YAML, and returns it as a hash.
|
56
|
+
def lucid_yml
|
57
|
+
return @lucid_yml if @lucid_yml
|
58
|
+
unless lucid_yml_defined?
|
59
|
+
raise ProfilesNotDefinedError, ["A lucid.yml file was not found. The current directory is #{Dir.pwd}.",
|
60
|
+
"Refer to Lucid's documentation on defining profiles in lucid.yml.",
|
61
|
+
"You must define a 'default' profile to use the lucid command without",
|
62
|
+
"any arguments.\nType 'lucid --help' for usage.\n"].join("\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
require 'erb'
|
66
|
+
require 'yaml'
|
67
|
+
begin
|
68
|
+
@lucid_erb = ERB.new(IO.read(lucid_file)).result(binding)
|
69
|
+
rescue Exception => e
|
70
|
+
raise YmlLoadError, ["A lucid.yml file was found, but could not be parsed. Double-check",
|
71
|
+
"the contents of the file. Refer to Lucid's documentation on correct",
|
72
|
+
"profile usage.\n#{$!.inspect}"].join("\n")
|
73
|
+
end
|
74
|
+
|
75
|
+
begin
|
76
|
+
@lucid_yml = YAML::load(@lucid_erb)
|
77
|
+
rescue StandardError => e
|
78
|
+
raise YmlLoadError, ["A lucid.yml file was found, but could not be parsed. Double-check",
|
79
|
+
"the contents of the file. Refer to Lucid's documentation on correct",
|
80
|
+
"profile usage.\n"].join("\n")
|
81
|
+
end
|
82
|
+
|
83
|
+
if @lucid_yml.nil? || !@lucid_yml.is_a?(Hash)
|
84
|
+
raise YmlLoadError, ["The lucid.yml file was found, but was blank or malformed. Please",
|
85
|
+
"refer to Lucid's documentation on defining profiles in lucid.yml.\n"].join("\n")
|
86
|
+
end
|
87
|
+
|
88
|
+
return @lucid_yml
|
89
|
+
end
|
90
|
+
|
91
|
+
# Locates lucid.yml file. The file can end in .yml or .yaml, and be
|
92
|
+
# located in the current directory (e.g., project root) or in a
|
93
|
+
# .config/ or config/ subdirectory of the current directory.
|
94
|
+
def lucid_file
|
95
|
+
@lucid_file ||= Dir.glob('{,.config/,config/}lucid{.yml,.yaml}').first
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Lucid
|
2
|
+
# The base class for configuring settings for a Lucid run.
|
3
|
+
class Configuration
|
4
|
+
def self.default
|
5
|
+
new
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.parse(argument)
|
9
|
+
return new(argument) if argument.is_a?(Hash)
|
10
|
+
argument
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(user_options = {})
|
14
|
+
@options = default_options.merge(user_options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def dry_run?
|
18
|
+
@options[:dry_run]
|
19
|
+
end
|
20
|
+
|
21
|
+
def guess?
|
22
|
+
@options[:guess]
|
23
|
+
end
|
24
|
+
|
25
|
+
def strict?
|
26
|
+
@options[:strict]
|
27
|
+
end
|
28
|
+
|
29
|
+
def expand?
|
30
|
+
@options[:expand]
|
31
|
+
end
|
32
|
+
|
33
|
+
def spec_source
|
34
|
+
@options[:spec_source]
|
35
|
+
end
|
36
|
+
|
37
|
+
def autoload_code_paths
|
38
|
+
@options[:autoload_code_paths]
|
39
|
+
end
|
40
|
+
|
41
|
+
def matcher_type
|
42
|
+
@options[:matcher_type]
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def default_options
|
48
|
+
{
|
49
|
+
:autoload_code_paths => ['common', 'steps']
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
begin
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
if defined?(Test::Unit::AutoRunner.need_auto_run?)
|
5
|
+
# For test-unit gem >= 2.4.9
|
6
|
+
Test::Unit::AutoRunner.need_auto_run = false
|
7
|
+
elsif defined?(Test::Unit.run?)
|
8
|
+
# For test-unit gem < 2.4.9
|
9
|
+
Test::Unit.run = true
|
10
|
+
elsif defined?(Test::Unit::Runner)
|
11
|
+
# For test/unit bundled in Ruby >= 1.9.3
|
12
|
+
Test::Unit::Runner.module_eval("@@stop_auto_run = true")
|
13
|
+
end
|
14
|
+
rescue LoadError => ignore
|
15
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'lucid/platform'
|
2
|
+
|
3
|
+
module Lucid
|
4
|
+
# Raised if the number of a StepDefinition's Regexp match groups
|
5
|
+
# is different from the number of Proc arguments.
|
6
|
+
class ArityMismatchError < StandardError
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Object #:nodoc:
|
11
|
+
# TODO: Move most of this stuff out to an InstanceExecutor class.
|
12
|
+
def lucid_instance_exec(check_arity, pseudo_method, *args, &block)
|
13
|
+
lucid_run_with_backtrace_filtering(pseudo_method) do
|
14
|
+
if check_arity && !lucid_compatible_arity?(args, block)
|
15
|
+
instance_exec do
|
16
|
+
ari = block.arity
|
17
|
+
ari = ari < 0 ? (ari.abs-1).to_s+"+" : ari
|
18
|
+
s1 = ari == 1 ? "" : "s"
|
19
|
+
s2 = args.length == 1 ? "" : "s"
|
20
|
+
raise Lucid::ArityMismatchError.new(
|
21
|
+
"Your block takes #{ari} argument#{s1}, but the regexp matched #{args.length} argument#{s2}."
|
22
|
+
)
|
23
|
+
end
|
24
|
+
else
|
25
|
+
instance_exec(*args, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def lucid_compatible_arity?(args, block)
|
33
|
+
return true if block.arity == args.length
|
34
|
+
if block.arity < 0
|
35
|
+
return true if args.length >= (block.arity.abs - 1)
|
36
|
+
end
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
def lucid_run_with_backtrace_filtering(pseudo_method)
|
41
|
+
begin
|
42
|
+
yield
|
43
|
+
rescue Exception => e
|
44
|
+
instance_exec_invocation_line = "#{__FILE__}:#{__LINE__ - 2}:in `lucid_run_with_backtrace_filtering'"
|
45
|
+
replace_instance_exec_invocation_line!((e.backtrace || []), instance_exec_invocation_line, pseudo_method)
|
46
|
+
raise e
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
INSTANCE_EXEC_OFFSET = (Lucid::RUBY_2_0 || Lucid::RUBY_1_9 || Lucid::JRUBY) ? -3 : -4
|
51
|
+
|
52
|
+
def replace_instance_exec_invocation_line!(backtrace, instance_exec_invocation_line, pseudo_method)
|
53
|
+
return if Lucid.use_full_backtrace
|
54
|
+
|
55
|
+
instance_exec_pos = backtrace.index(instance_exec_invocation_line)
|
56
|
+
if instance_exec_pos
|
57
|
+
replacement_line = instance_exec_pos + INSTANCE_EXEC_OFFSET
|
58
|
+
backtrace[replacement_line].gsub!(/`.*'/, "`#{pseudo_method}'") if pseudo_method
|
59
|
+
|
60
|
+
depth = backtrace.count { |line| line == instance_exec_invocation_line }
|
61
|
+
end_pos = depth > 1 ? instance_exec_pos : -1
|
62
|
+
|
63
|
+
backtrace[replacement_line+1..end_pos] = nil
|
64
|
+
backtrace.compact!
|
65
|
+
else
|
66
|
+
# This happens with rails, because they screw up the backtrace
|
67
|
+
# before we get here (injecting erb stacktrace and such)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Proc extension to get more location info out of a proc
|
2
|
+
require 'lucid/platform'
|
3
|
+
class Proc #:nodoc:
|
4
|
+
PROC_PATTERN = /[\d\w]+@(.+):(\d+).*>/
|
5
|
+
PWD = Dir.pwd
|
6
|
+
|
7
|
+
def to_comment_line
|
8
|
+
"# #{file_colon_line}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def backtrace_line(name)
|
12
|
+
"#{file_colon_line}:in `#{name}'"
|
13
|
+
end
|
14
|
+
|
15
|
+
if Proc.new{}.to_s =~ PROC_PATTERN
|
16
|
+
def file_colon_line
|
17
|
+
path, line = *to_s.match(PROC_PATTERN)[1..2]
|
18
|
+
path = File.expand_path(path)
|
19
|
+
pwd = File.expand_path(PWD)
|
20
|
+
pwd.force_encoding(path.encoding)
|
21
|
+
if path.index(pwd)
|
22
|
+
path = path[pwd.length+1..-1]
|
23
|
+
elsif path =~ /.*\/gems\/(.*\.rb)$/
|
24
|
+
path = $1
|
25
|
+
end
|
26
|
+
"#{path}:#{line}"
|
27
|
+
end
|
28
|
+
else
|
29
|
+
# This Ruby implementation doesn't implement Proc#to_s correctly
|
30
|
+
STDERR.puts "*** THIS RUBY IMPLEMENTATION DOESN'T REPORT FILE AND LINE FOR PROCS ***"
|
31
|
+
|
32
|
+
def file_colon_line
|
33
|
+
"UNKNOWN:-1"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/lucid/errors.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Lucid
|
2
|
+
# Raised when there is no matching StepDefinition for a step.
|
3
|
+
class Undefined < StandardError
|
4
|
+
attr_reader :step_name
|
5
|
+
|
6
|
+
def initialize(step_name)
|
7
|
+
super %{Undefined step: "#{step_name}"}
|
8
|
+
@step_name = step_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def nested!
|
12
|
+
@nested = true
|
13
|
+
end
|
14
|
+
|
15
|
+
def nested?
|
16
|
+
@nested
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Raised when a StepDefinition's block invokes Domain#pending
|
21
|
+
class Pending < StandardError
|
22
|
+
end
|
23
|
+
|
24
|
+
# Raised when a step matches 2 or more StepDefinitions
|
25
|
+
class Ambiguous < StandardError
|
26
|
+
def initialize(step_name, step_definitions, used_guess)
|
27
|
+
message = "Ambiguous match of \"#{step_name}\":\n\n"
|
28
|
+
message << step_definitions.map{|sd| sd.backtrace_line}.join("\n")
|
29
|
+
message << "\n\n"
|
30
|
+
message << "You can run again with --guess to make Lucid be a little more smart about it.\n" unless used_guess
|
31
|
+
super(message)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class TagExcess < StandardError
|
36
|
+
def initialize(messages)
|
37
|
+
super(messages.join("\n"))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Lucid
|
2
|
+
module ObjectFactory #:nodoc:
|
3
|
+
def create_object_of(phrase)
|
4
|
+
try = 0
|
5
|
+
begin
|
6
|
+
try += 1
|
7
|
+
names = phrase.split('::')
|
8
|
+
names.shift if names.empty? || names.first.empty?
|
9
|
+
|
10
|
+
constant = ::Object
|
11
|
+
names.each do |name|
|
12
|
+
constant = provide_object_name(constant, name)
|
13
|
+
end
|
14
|
+
constant
|
15
|
+
rescue NameError => e
|
16
|
+
require underscore(phrase)
|
17
|
+
if try < 2
|
18
|
+
retry
|
19
|
+
else
|
20
|
+
raise e
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def underscore(phrase)
|
26
|
+
phrase.to_s.gsub(/::/, '/').
|
27
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
28
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
29
|
+
tr("-", "_").
|
30
|
+
downcase
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def provide_object_name(constant, name)
|
36
|
+
if constant.const_defined?(name, false)
|
37
|
+
constant.const_get(name, false)
|
38
|
+
else
|
39
|
+
constant.const_missing(name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'lucid/platform'
|
2
|
+
require 'lucid/term/ansicolor'
|
3
|
+
|
4
|
+
if Lucid::IRONRUBY
|
5
|
+
begin
|
6
|
+
require 'iron-term-ansicolor'
|
7
|
+
rescue LoadError
|
8
|
+
STDERR.puts %{*** WARNING: You must "igem install iron-term-ansicolor" to get coloured ouput in on IronRuby}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
if Lucid::WINDOWS_MRI
|
13
|
+
unless ENV['ANSICON']
|
14
|
+
STDERR.puts %{*** WARNING: You must use ANSICON 1.31 or higher (https://github.com/adoxa/ansicon/) to get coloured output on Windows}
|
15
|
+
Lucid::Term::ANSIColor.coloring = false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Lucid::Term::ANSIColor.coloring = false if !STDOUT.tty? && !ENV.has_key?("AUTOTEST")
|
20
|
+
|
21
|
+
module Lucid
|
22
|
+
module Formatter
|
23
|
+
# Defines aliases for coloured output. You don't invoke any methods from this
|
24
|
+
# module directly, but you can change the output colours by defining
|
25
|
+
# a <tt>CUCUMBER_COLORS</tt> variable in your shell, very much like how you can
|
26
|
+
# tweak the familiar POSIX command <tt>ls</tt> with
|
27
|
+
# <a href="http://mipsisrisc.com/rambling/2008/06/27/lscolorsls_colors-now-with-linux-support/">$LSCOLORS/$LS_COLORS</a>
|
28
|
+
#
|
29
|
+
# The colours that you can change are:
|
30
|
+
#
|
31
|
+
# * <tt>undefined</tt> - defaults to <tt>yellow</tt>
|
32
|
+
# * <tt>pending</tt> - defaults to <tt>yellow</tt>
|
33
|
+
# * <tt>pending_param</tt> - defaults to <tt>yellow,bold</tt>
|
34
|
+
# * <tt>failed</tt> - defaults to <tt>red</tt>
|
35
|
+
# * <tt>failed_param</tt> - defaults to <tt>red,bold</tt>
|
36
|
+
# * <tt>passed</tt> - defaults to <tt>green</tt>
|
37
|
+
# * <tt>passed_param</tt> - defaults to <tt>green,bold</tt>
|
38
|
+
# * <tt>outline</tt> - defaults to <tt>cyan</tt>
|
39
|
+
# * <tt>outline_param</tt> - defaults to <tt>cyan,bold</tt>
|
40
|
+
# * <tt>skipped</tt> - defaults to <tt>cyan</tt>
|
41
|
+
# * <tt>skipped_param</tt> - defaults to <tt>cyan,bold</tt>
|
42
|
+
# * <tt>comment</tt> - defaults to <tt>grey</tt>
|
43
|
+
# * <tt>tag</tt> - defaults to <tt>cyan</tt>
|
44
|
+
#
|
45
|
+
# For instance, if your shell has a black background and a green font (like the
|
46
|
+
# "Homebrew" settings for OS X' Terminal.app), you may want to override passed
|
47
|
+
# steps to be white instead of green.
|
48
|
+
#
|
49
|
+
# Although not listed, you can also use <tt>grey</tt>.
|
50
|
+
#
|
51
|
+
# Examples: (On Windows, use SET instead of export.)
|
52
|
+
#
|
53
|
+
# export CUCUMBER_COLORS="passed=white"
|
54
|
+
# export CUCUMBER_COLORS="passed=white,bold:passed_param=white,bold,underline"
|
55
|
+
#
|
56
|
+
# To see what colours and effects are available, just run this in your shell:
|
57
|
+
#
|
58
|
+
# ruby -e "require 'rubygems'; require 'term/ansicolor'; puts Lucid::Term::ANSIColor.attributes"
|
59
|
+
#
|
60
|
+
module ANSIColor
|
61
|
+
include Lucid::Term::ANSIColor
|
62
|
+
|
63
|
+
ALIASES = Hash.new do |h,k|
|
64
|
+
if k.to_s =~ /(.*)_param/
|
65
|
+
h[$1] + ',bold'
|
66
|
+
end
|
67
|
+
end.merge({
|
68
|
+
'undefined' => 'yellow',
|
69
|
+
'pending' => 'yellow',
|
70
|
+
'failed' => 'red',
|
71
|
+
'passed' => 'green',
|
72
|
+
'outline' => 'cyan',
|
73
|
+
'skipped' => 'cyan',
|
74
|
+
'comment' => 'grey',
|
75
|
+
'tag' => 'cyan'
|
76
|
+
})
|
77
|
+
|
78
|
+
if ENV['CUCUMBER_COLORS'] # Example: export CUCUMBER_COLORS="passed=red:failed=yellow"
|
79
|
+
ENV['CUCUMBER_COLORS'].split(':').each do |pair|
|
80
|
+
a = pair.split('=')
|
81
|
+
ALIASES[a[0]] = a[1]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Eval to define the color-named methods required by Term::ANSIColor.
|
86
|
+
#
|
87
|
+
# Examples:
|
88
|
+
#
|
89
|
+
# def failed(string=nil, &proc)
|
90
|
+
# red(string, &proc)
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
# def failed_param(string=nil, &proc)
|
94
|
+
# red(bold(string, &proc)) + red
|
95
|
+
# end
|
96
|
+
ALIASES.each_key do |method_name|
|
97
|
+
unless method_name =~ /.*_param/
|
98
|
+
code = <<-EOF
|
99
|
+
def #{method_name}(string=nil, &proc)
|
100
|
+
#{ALIASES[method_name].split(",").join("(") + "(string, &proc" + ")" * ALIASES[method_name].split(",").length}
|
101
|
+
end
|
102
|
+
# This resets the colour to the non-param colour
|
103
|
+
def #{method_name}_param(string=nil, &proc)
|
104
|
+
#{ALIASES[method_name+'_param'].split(",").join("(") + "(string, &proc" + ")" * ALIASES[method_name+'_param'].split(",").length} + #{ALIASES[method_name].split(",").join(' + ')}
|
105
|
+
end
|
106
|
+
EOF
|
107
|
+
eval(code)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.define_grey #:nodoc:
|
112
|
+
begin
|
113
|
+
gem 'genki-ruby-terminfo'
|
114
|
+
require 'terminfo'
|
115
|
+
case TermInfo.default_object.tigetnum("colors")
|
116
|
+
when 0
|
117
|
+
raise "Your terminal doesn't support colours."
|
118
|
+
when 1
|
119
|
+
::Lucid::Term::ANSIColor.coloring = false
|
120
|
+
alias grey white
|
121
|
+
when 2..8
|
122
|
+
alias grey white
|
123
|
+
else
|
124
|
+
define_real_grey
|
125
|
+
end
|
126
|
+
rescue Exception => e
|
127
|
+
if e.class.name == 'TermInfo::TermInfoError'
|
128
|
+
STDERR.puts "*** WARNING ***"
|
129
|
+
STDERR.puts "You have the genki-ruby-terminfo gem installed, but you haven't set your TERM variable."
|
130
|
+
STDERR.puts "Try setting it to TERM=xterm-256color to get grey colour in output."
|
131
|
+
STDERR.puts "\n"
|
132
|
+
alias grey white
|
133
|
+
else
|
134
|
+
define_real_grey
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.define_real_grey #:nodoc:
|
140
|
+
def grey(string) #:nodoc:
|
141
|
+
if ::Lucid::Term::ANSIColor.coloring?
|
142
|
+
"\e[90m#{string}\e[0m"
|
143
|
+
else
|
144
|
+
string
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
define_grey
|
150
|
+
|
151
|
+
def cukes(n)
|
152
|
+
("(::) " * n).strip
|
153
|
+
end
|
154
|
+
|
155
|
+
def green_cukes(n)
|
156
|
+
blink(green(cukes(n)))
|
157
|
+
end
|
158
|
+
|
159
|
+
def red_cukes(n)
|
160
|
+
blink(red(cukes(n)))
|
161
|
+
end
|
162
|
+
|
163
|
+
def yellow_cukes(n)
|
164
|
+
blink(yellow(cukes(n)))
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|