pastel 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20dcaf43ced285d36ad7074808b52e6963e2da79
4
- data.tar.gz: 592af5b9be60dbd781e909a3dc29222cfc68eef0
3
+ metadata.gz: ad29856f8ce21205b25f4318d1f26833d14ef771
4
+ data.tar.gz: efeb5f5eb350302edb488269972623ba7e92bfaa
5
5
  SHA512:
6
- metadata.gz: bf6a4be639512821cf4e990dbb0a6a15a4e0f009912161be8b9f429bf9287985baa02202378d80ae2b2d8b3de218319150b713f929ed6ec5fb17006e96a530e7
7
- data.tar.gz: 204a5342e5b5e2e29d1cd50896db08c8d543467a18d0efac9cfe39a77536aca277f630a7716981aff33239b1a05cac2701d6644c0f224e232704b90eb6a62ba2
6
+ metadata.gz: 35ee51a33ca2d5dd17d187304ae98e447cb91fbf2e0df607bb4cc13aa2b23eb7bbe0ceeec6c3823c0b588b4e753a23e422f0342f563cfb403ce7c6e1d75dd72e
7
+ data.tar.gz: 389f85a431b62154d914a42f68ed13526ef4c172b1c4da2ab2123cedd932e349b2aa9e223948349ad4145c504df94f97191027acef23f7fdf868d6bdd25c91cd
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
2
  --require spec_helper
3
+ --warnings
data/.travis.yml CHANGED
@@ -3,8 +3,9 @@ bundler_args: --without yard benchmarks
3
3
  script: "bundle exec rake ci"
4
4
  rvm:
5
5
  - 1.9.3
6
- - 2.0.0
7
- - 2.1.0
6
+ - 2.0
7
+ - 2.1
8
+ - 2.2
8
9
  - ruby-head
9
10
  matrix:
10
11
  include:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ 0.5.0 (Sept 13, 2015)
2
+
3
+ * Add external dependency to check for color support
4
+ * Add #colored? to check if string has color escape codes
5
+ * Add #eachline option to allow coloring of multiline strings
6
+ * Further refine #strip method accuracy
7
+ * Fix redefining inspect method
8
+ * Fix string representation for pastel instance
9
+
1
10
  0.4.0 (November 22, 2014)
2
11
 
3
12
  * Fix Delegator#respond_to method to correctly report existence of methods
data/Gemfile CHANGED
@@ -3,14 +3,14 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :development do
6
- gem 'rake', '~> 10.3.2'
7
- gem 'rspec', '~> 3.1.0'
6
+ gem 'rake', '~> 10.4.2'
7
+ gem 'rspec', '~> 3.3.0'
8
8
  gem 'yard', '~> 0.8.7'
9
9
  gem 'benchmark-ips', '~> 2.0.0'
10
10
  end
11
11
 
12
12
  group :metrics do
13
- gem 'coveralls', '~> 0.7.0'
14
- gem 'simplecov', '~> 0.8.2'
13
+ gem 'coveralls', '~> 0.8.2'
14
+ gem 'simplecov', '~> 0.10.0'
15
15
  gem 'yardstick', '~> 0.9.9'
16
16
  end
data/README.md CHANGED
@@ -1,13 +1,18 @@
1
+ <div align="center">
2
+ <img width="215" src="https://cdn.rawgit.com/peter-murach/pastel/master/assets/pastel_logo.png" alt="pastel logo" />
3
+ </div>
1
4
  # Pastel
2
- [![Gem Version](https://badge.fury.io/rb/pastel.png)][gem]
3
- [![Build Status](https://secure.travis-ci.org/peter-murach/pastel.png?branch=master)][travis]
4
- [![Code Climate](https://codeclimate.com/github/peter-murach/pastel.png)][codeclimate]
5
- [![Coverage Status](https://coveralls.io/repos/peter-murach/pastel/badge.png)][coverage]
5
+ [![Gem Version](https://badge.fury.io/rb/pastel.svg)][gem]
6
+ [![Build Status](https://secure.travis-ci.org/peter-murach/pastel.svg?branch=master)][travis]
7
+ [![Code Climate](https://codeclimate.com/github/peter-murach/pastel/badges/gpa.svg)][codeclimate]
8
+ [![Coverage Status](https://coveralls.io/repos/peter-murach/pastel/badge.svg)][coverage]
9
+ [![Inline docs](http://inch-ci.org/github/peter-murach/tty.svg?branch=master)][inchpages]
6
10
 
7
11
  [gem]: http://badge.fury.io/rb/pastel
8
12
  [travis]: http://travis-ci.org/peter-murach/pastel
9
13
  [codeclimate]: https://codeclimate.com/github/peter-murach/pastel
10
14
  [coverage]: https://coveralls.io/r/peter-murach/pastel
15
+ [inchpages]: http://inch-ci.org/github/peter-murach/pastel
11
16
 
12
17
  > Terminal output styling with intuitive and clean API that doesn't monkey patch String class.
13
18
 
@@ -23,6 +28,7 @@
23
28
  * Intuitive and expressive API
24
29
  * Minimal and focused to work on all terminal emulators
25
30
  * Auto-detection of color support
31
+ * Allows nested styles
26
32
  * Performant
27
33
 
28
34
  ## Installation
@@ -49,8 +55,10 @@ Or install it yourself as:
49
55
  * [2.4 Strip](#24-strip)
50
56
  * [2.5 Styles](#25-styles)
51
57
  * [2.6 Valid?](#26-valid)
52
- * [2.7 Enabled?](#27-enabled)
53
- * [2.8 Alias Color](#28-alias-color)
58
+ * [2.7 Colored?](#27-colored)
59
+ * [2.8 Enabled?](#28-enabled)
60
+ * [2.9 Eachline](#29-eachline)
61
+ * [2.10 Alias Color](#30-alias-color)
54
62
  * [3. Supported Colors](#3-supported-colors)
55
63
  * [4. Environment](#4-environment)
56
64
 
@@ -61,7 +69,7 @@ Or install it yourself as:
61
69
  ```ruby
62
70
  pastel = Pastel.new
63
71
 
64
- puts pastel.red('Unicorns!')
72
+ pastel.red('Unicorns!')
65
73
  ```
66
74
 
67
75
  You can compose multiple styles through chainable API:
@@ -104,6 +112,12 @@ pastel.red.on_green('Unicorns') {
104
112
  }
105
113
  ```
106
114
 
115
+ When dealing with multiline strings you can set `eachline` option(more info see [eachline](#29-eachline)):
116
+
117
+ ```
118
+ pastel = Pastel.new(eachline: "\n")
119
+ ```
120
+
107
121
  You can also predefine needed styles and reuse them:
108
122
 
109
123
  ```ruby
@@ -118,7 +132,9 @@ puts warning('Warning')
118
132
 
119
133
  ### 2.1 Color
120
134
 
121
- You can pass variable number of styled strings like so:
135
+ pastel.`<color>[.<color>...](string, [string...])`
136
+
137
+ Color styles are invoked as method calls with a string argument. A given color can take any number of strings as arguments. Then it returns a colored string which isn't printed out to terminal. You need to print it yourself if you need to. This is done so that you can save it as a string, pass to something else, send it to a file handle and so on.
122
138
 
123
139
  ```ruby
124
140
  pastel.red('Unicorns ', pastel.bold.underline('everywhere'), '!')
@@ -128,13 +144,13 @@ Please refer to [3. Supported Colors](#3-supported-colors) section for full list
128
144
 
129
145
  ### 2.2 Decorate
130
146
 
131
- This method is a lower level string styling call that takes as the first argument the string to style and any number of attributes, and returns string wrapped in styles.
147
+ This method is a lower level string styling call that takes as the first argument the string to style followed by any number of color attributes, and returns string wrapped in styles.
132
148
 
133
149
  ```ruby
134
150
  pastel.decorate('Unicorn', :green, :on_blue, :bold)
135
151
  ```
136
152
 
137
- This method will be useful in situations where colors are provided as a list of parameters.
153
+ This method will be useful in situations where colors are provided as a list of parameters that have been generated dynamically.
138
154
 
139
155
  ### 2.3 Detach
140
156
 
@@ -148,7 +164,7 @@ puts notice.call('They are super wild')
148
164
 
149
165
  ### 2.4 Strip
150
166
 
151
- Strip all color sequence characters from the provided strings. The return value will be eithre array of modified strings or a single string. The arguments are not modified.
167
+ Strip only color sequence characters from the provided strings and preserve any movement codes or other escape sequences. The return value will be either array of modified strings or a single string. The arguments are not modified.
152
168
 
153
169
  ```ruby
154
170
  pastel.strip("\e[1m\e[34mbold blue text\e[0m") # => "bold blue text"
@@ -171,7 +187,15 @@ pastel.valid?(:red, :blue) # => true
171
187
  pastel.valid?(:unicorn) # => false
172
188
  ```
173
189
 
174
- ### 2.7 Enabled?
190
+ ### 2.7 Colored?
191
+
192
+ In order to determine if string has color escape codes use `colored?` like so
193
+
194
+ ```ruby
195
+ pastel.colored?("\e[31mcolorful\e[0m") # => true
196
+ ```
197
+
198
+ ### 2.8 Enabled?
175
199
 
176
200
  In order to detect if your terminal supports coloring do:
177
201
 
@@ -186,7 +210,16 @@ pastel = Pastel.new(enabled: true)
186
210
  pastel.enabled? # => false
187
211
  ```
188
212
 
189
- ### 2.8 Alias Color
213
+ ### 2.9 Eachline
214
+
215
+ Normally **Pastel** colors string by putting color codes at the beginning and end of the string, but if you provide `eachline` option set to some string, that string will be considered the line delimiter. Consequently, each line will be separately colored with escape sequence and reset code at the end. This option is desirable if the output string contains newlines and you're using background colors. Since color code that spans more than one line is often interpreted by terminal as providing background for all the lines that follow. This in turn may cause programs such as pagers to spill the colors throughout the text. In most cases you will want to set `eachline` to `\n` character like so:
216
+
217
+ ```ruby
218
+ pastel = Pastel.new(eachline: "\n")
219
+ pastel.red("foo\nbar") # => "\e[31mfoo\e[0m\n\e[31mbar\e[0m"
220
+ ```
221
+
222
+ ### 2.10 Alias Color
190
223
 
191
224
  In order to setup an alias for the standard color do:
192
225
 
@@ -283,4 +316,4 @@ PASTEL_COLORS_ALIASES='newcolor_1=red,newcolor_2=on_green'
283
316
 
284
317
  ## Copyright
285
318
 
286
- Copyright (c) 2014 Piotr Murach. See LICENSE for further details.
319
+ Copyright (c) 2014-2015 Piotr Murach. See LICENSE for further details.
Binary file
@@ -0,0 +1,14 @@
1
+ require_relative 'lib/pastel'
2
+
3
+ pastel = Pastel.new
4
+
5
+ puts pastel.bold('bold ') + ' ' + pastel.dim('dim ') + ' ' + pastel.italic('italic ') + ' ' + pastel.underline('underline') + ' ' + pastel.inverse('inverse ') + ' ' + pastel.strikethrough('strikethrough')
6
+
7
+ puts pastel.red('red ') + ' ' + pastel.green('green ') + ' ' + pastel.yellow('yellow ') + ' ' + pastel.blue('blue ') + ' ' + pastel.magenta('magenta ') + ' ' + pastel.cyan('cyan ') + ' ' + pastel.white('white')
8
+
9
+ puts pastel.bright_red('red ') + ' ' + pastel.bright_green('green ') + ' ' + pastel.bright_yellow('yellow ') + ' ' + pastel.bright_blue('blue ') + ' ' + pastel.bright_magenta('magenta ') + ' ' + pastel.bright_cyan('cyan ') + ' ' + pastel.bright_white('white')
10
+
11
+
12
+ puts pastel.on_red('on_red') + ' ' + pastel.on_green('on_green') + ' ' + pastel.on_yellow('on_yellow') + ' ' + pastel.on_blue('on_blue') + ' ' + pastel.on_magenta('on_magenta') + ' ' + pastel.on_cyan('on_cyan') + ' ' + pastel.on_white('on_white')
13
+
14
+ puts pastel.on_bright_red('on_red') + ' ' + pastel.on_bright_green('on_green') + ' ' + pastel.on_bright_yellow('on_yellow') + ' ' + pastel.on_bright_blue('on_blue') + ' ' + pastel.on_bright_magenta('on_magenta') + ' ' + pastel.on_bright_cyan('on_cyan') + ' ' + pastel.on_bright_white('on_white')
data/lib/pastel.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'forwardable'
4
4
  require 'equatable'
5
+ require 'tty-screen'
5
6
 
6
7
  require 'pastel/ansi'
7
8
  require 'pastel/alias_importer'
data/lib/pastel/color.rb CHANGED
@@ -8,14 +8,20 @@ module Pastel
8
8
 
9
9
  ALIASES = {}
10
10
 
11
+ ANSI_REGEX = /(\[)?\033(\[)?[:;?\d]*[\dA-Za-z](\])?/.freeze
12
+
11
13
  attr_reader :enabled
12
14
  alias_method :enabled?, :enabled
13
15
 
16
+ attr_reader :eachline
17
+
14
18
  # Initialize a Terminal Color
15
19
  #
16
20
  # @api public
17
21
  def initialize(options = {})
18
- @enabled = options.fetch(:enabled) { supports? }
22
+ @enabled = options.fetch(:enabled) { TTY::Screen.color? }
23
+ @eachline = options.fetch(:eachline) { false }
24
+ freeze
19
25
  end
20
26
 
21
27
  # Disable coloring of this terminal session
@@ -25,22 +31,6 @@ module Pastel
25
31
  @enabled = false
26
32
  end
27
33
 
28
- # Detect terminal color support
29
- #
30
- # @return [Boolean]
31
- # true when terminal supports color, false otherwise
32
- #
33
- # @api public
34
- def supports?
35
- return false unless $stdout.tty?
36
- return false if ENV['TERM'] == 'dumb'
37
- if ENV['TERM'] =~ /^screen|^xterm|^vt100|color|ansi|cygwin|linux/i
38
- return true
39
- end
40
- return true if ENV.include?('COLORTERM')
41
- true
42
- end
43
-
44
34
  # Apply ANSI color to the given string.
45
35
  #
46
36
  # @param [String] string
@@ -60,15 +50,39 @@ module Pastel
60
50
  return string if string.empty? || !enabled
61
51
 
62
52
  ansi_colors = lookup(*colors)
63
- ansi_string = "#{ansi_colors}#{string}#{clear}"
53
+ ansi_string = wrap_eachline(string, ansi_colors)
64
54
  ansi_string = nest_color(collapse_reset(ansi_string), ansi_colors)
65
55
  ansi_string
66
56
  end
67
57
 
58
+ # Reset sequence
59
+ #
60
+ # @api public
68
61
  def clear
69
62
  lookup(:clear)
70
63
  end
71
64
 
65
+ # Wraps eachline with clear character
66
+ #
67
+ # @param [String] string
68
+ # string to wrap with multiline characters
69
+ #
70
+ # @param [String] ansi_colors
71
+ # colors to apply to string
72
+ #
73
+ # @return [String]
74
+ #
75
+ # @api private
76
+ def wrap_eachline(string, ansi_colors)
77
+ if eachline
78
+ string.split(eachline).map do |line|
79
+ "#{ansi_colors}#{line}#{clear}"
80
+ end.join(eachline)
81
+ else
82
+ "#{ansi_colors}#{string}#{clear}"
83
+ end
84
+ end
85
+
72
86
  # Collapse reset
73
87
  #
74
88
  # @param [String] string
@@ -99,32 +113,43 @@ module Pastel
99
113
  def nest_color(string, ansi_colors)
100
114
  ansi_string = string.dup
101
115
  matches = ansi_string.scan(/#{Regexp.quote(clear)}/)
102
- if matches.length > 1
116
+ if matches.length > 1 && !eachline
103
117
  ansi_string.sub!(/#{Regexp.quote(clear)}/, ansi_colors)
104
118
  end
105
119
  ansi_string
106
120
  end
107
121
  private :collapse_reset, :nest_color
108
122
 
109
- # Same as instance method.
123
+ # Strip ANSI color codes from a string.
124
+ #
125
+ # Only ANSI color codes are removed, not movement codes or
126
+ # other escapes sequences are stripped.
127
+ #
128
+ # @param [Array[String]] strings
129
+ # a string or array of strings to sanitize
130
+ #
131
+ # @example
132
+ # strip("foo\e[1mbar\e[0m") # => "foobar"
110
133
  #
111
134
  # @return [String]
112
135
  #
113
136
  # @api public
114
- def self.decorate(string, *colors)
115
- new.decorate(string, *colors)
137
+ def strip(*strings)
138
+ modified = strings.map { |string| string.dup.gsub(ANSI_REGEX, '') }
139
+ modified.size == 1 ? modified[0] : modified
116
140
  end
117
141
 
118
- # Strip ANSI color codes from a string.
142
+ # Check if string has color escape codes
119
143
  #
120
144
  # @param [String] string
121
- # the string to sanitize
145
+ # the string to check for color strings
122
146
  #
123
- # @return [String]
147
+ # @return [Boolean]
148
+ # true when string contains color codes, false otherwise
124
149
  #
125
150
  # @api public
126
- def strip(string)
127
- string.to_s.gsub(/(\[)?\033(\[)?[;?\d]*[\dA-Za-z](\])?/, '')
151
+ def colored?(string)
152
+ !ANSI_REGEX.match(string).nil?
128
153
  end
129
154
 
130
155
  # Return raw color code without embeding it into a string.
@@ -146,7 +171,7 @@ module Pastel
146
171
  attribute
147
172
  end
148
173
 
149
- # Find color representation.
174
+ # Find the escape code for color attribute.
150
175
  #
151
176
  # @param [Symbol,String] colors
152
177
  # the color name(s) to lookup
@@ -183,7 +208,10 @@ module Pastel
183
208
  # @param [Array[Symbol,String]]
184
209
  # the list of colors to check
185
210
  #
186
- # @reutrn [Boolean]
211
+ # @example
212
+ # valid?(:red) # => true
213
+ #
214
+ # @return [Boolean]
187
215
  # true if all colors are valid, false otherwise
188
216
  #
189
217
  # @api public
@@ -10,7 +10,7 @@ module Pastel
10
10
  include Equatable
11
11
 
12
12
  def_delegators '@resolver.color', :valid?, :styles, :strip, :decorate,
13
- :enabled?, :alias_color
13
+ :enabled?, :colored?, :alias_color
14
14
 
15
15
  # Create Delegator
16
16
  #
@@ -31,12 +31,17 @@ module Pastel
31
31
  new(resolver, base)
32
32
  end
33
33
 
34
+ remove_method :inspect
35
+
34
36
  # Object string representation
35
37
  #
38
+ # @return [String]
39
+ #
36
40
  # @api
37
41
  def inspect
38
- "<##{self.class.name}>"
42
+ "#<Pastel @styles=#{base.map(&:to_s)}>"
39
43
  end
44
+ alias_method :to_s, :inspect
40
45
 
41
46
  protected
42
47
 
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Pastel
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
data/pastel.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "equatable", "~> 0.5"
22
+ spec.add_dependency "tty-screen", "~> 0.4"
22
23
 
23
24
  spec.add_development_dependency "bundler", "~> 1.6"
24
25
  end
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Pastel::AliasImporter, '.import' do
6
- let(:color) { double(:color, alias_color: true) }
6
+ let(:color) { spy(:color, alias_color: true) }
7
7
  let(:output) { StringIO.new }
8
8
 
9
9
  subject(:importer) { described_class.new(color, output) }
@@ -12,15 +12,19 @@ RSpec.describe Pastel::AliasImporter, '.import' do
12
12
  color_aliases = "funky=red,base=bright_yellow"
13
13
  allow(ENV).to receive(:[]).with('PASTEL_COLORS_ALIASES').
14
14
  and_return(color_aliases)
15
+
15
16
  importer.import
17
+
16
18
  expect(color).to have_received(:alias_color).twice
17
19
  end
18
20
 
19
- it "fails to import incorrectly formattd colors" do
21
+ it "fails to import incorrectly formatted colors" do
20
22
  color_aliases = "funky red,base=bright_yellow"
21
23
  allow(ENV).to receive(:[]).with('PASTEL_COLORS_ALIASES').
22
24
  and_return(color_aliases)
25
+
23
26
  importer.import
27
+
24
28
  output.rewind
25
29
  expect(output.string).to eq("Bad color mapping `funky red`\n")
26
30
  expect(color).to have_received(:alias_color).with(:base, :bright_yellow)
@@ -18,4 +18,9 @@ RSpec.describe Pastel::Color, '.code' do
18
18
  it "doesn't find code" do
19
19
  expect { color.code(:unkown) }.to raise_error(ArgumentError)
20
20
  end
21
+
22
+ it "finds alias code" do
23
+ color.alias_color(:funky, :red)
24
+ expect(color.code(:funky)).to eq(color.code(:red))
25
+ end
21
26
  end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel::Color, '.colored?' do
6
+ subject(:color) { described_class.new(enabled: true) }
7
+
8
+ it "checks if string has color codes" do
9
+ string = "foo\e[31mbar\e[0m"
10
+ expect(color.colored?(string)).to eq(true)
11
+ end
12
+
13
+ it "checks that string doesn't contain color codes" do
14
+ string = "foo\nbar"
15
+ expect(color.colored?(string)).to eq(false)
16
+ end
17
+ end
@@ -38,6 +38,21 @@ RSpec.describe Pastel::Color, '.decorate' do
38
38
  expect(decorated).to eq("\e[32m#{string}\e[31m#{string}\e[32m#{string}\e[0m")
39
39
  end
40
40
 
41
+ it "decorates multiline string as regular by default" do
42
+ string = "foo\nbar\nbaz"
43
+ expect(color.decorate(string, :red)).to eq("\e[31mfoo\nbar\nbaz\e[0m")
44
+ end
45
+
46
+ it "allows to decorate each line separately" do
47
+ string = "foo\nbar\nbaz"
48
+ color = described_class.new(enabled: true, eachline: "\n")
49
+ expect(color.decorate(string, :red)).to eq([
50
+ "\e[31mfoo\e[0m",
51
+ "\e[31mbar\e[0m",
52
+ "\e[31mbaz\e[0m"
53
+ ].join("\n"))
54
+ end
55
+
41
56
  it 'errors for unknown color' do
42
57
  expect {
43
58
  color.decorate(string, :crimson)
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel::Color, '#==' do
6
+ it "is true with the same enabled and eachline attributes" do
7
+ expect(Pastel::Color.new(enabled: false, eachline: "\n")).
8
+ to eq(Pastel::Color.new(enabled: false, eachline: "\n"))
9
+ end
10
+
11
+ it "is false with different enabled attribute" do
12
+ expect(Pastel::Color.new(enabled: true, eachline: "\n")).
13
+ not_to eq(Pastel::Color.new(enabled: false, eachline: "\n"))
14
+ end
15
+
16
+ it "is false with different eachline attribute" do
17
+ expect(Pastel::Color.new(enabled: false, eachline: "\n")).
18
+ not_to eq(Pastel::Color.new(enabled: false, eachline: "\r\n"))
19
+ end
20
+
21
+ it "is false with non-color" do
22
+ expect(Pastel::Color.new(enabled: true)).not_to eq(:other)
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel::Color, '.new' do
6
+ it "is immutable" do
7
+ expect(described_class.new).to be_frozen
8
+ end
9
+
10
+ it "allows to disable coloring" do
11
+ color = described_class.new(enabled: false)
12
+
13
+ expect(color.enabled?).to eq(false)
14
+ expect(color.decorate("Unicorn", :red)).to eq("Unicorn")
15
+ end
16
+
17
+ it "invokes screen dependency to check color support" do
18
+ allow(TTY::Screen).to receive(:color?).and_return(true)
19
+ color = described_class.new
20
+
21
+ expect(color.enabled?).to eq(true)
22
+ expect(TTY::Screen).to have_received(:color?)
23
+ end
24
+ end
@@ -3,45 +3,56 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Pastel::Color, '.strip' do
6
- let(:instance) { described_class.new(enabled: true) }
7
6
 
8
- subject(:color) { instance.strip(string) }
7
+ subject(:color) { described_class.new(enabled: true) }
9
8
 
10
- context 'with ansi colors' do
11
- let(:string) { "This is a \e[1m\e[34mbold blue text\e[0m" }
12
-
13
- it 'removes color from string' do
14
- is_expected.to eq('This is a bold blue text')
15
- end
9
+ it 'strips ansi color from string' do
10
+ string = "This is a \e[1m\e[34mbold blue text\e[0m"
11
+ expect(color.strip(string)).to eq('This is a bold blue text')
16
12
  end
17
13
 
18
- context 'with octal in encapsulating brackets' do
19
- let(:string) { "\[\033[01;32m\]u@h \[\033[01;34m\]W $ \[\033[00m\]" }
20
-
21
- it { is_expected.to eq('u@h W $ ') }
14
+ it "strips partial ansi color" do
15
+ string = "foo\e[1mbar"
16
+ expect(color.strip(string)).to eq('foobar')
22
17
  end
23
18
 
24
- context 'with octal without brackets' do
25
- let(:string) { "\033[01;32mu@h \033[01;34mW $ \033[00m" }
19
+ it 'preserves movement characters' do
20
+ # [176A - move cursor up n lines
21
+ expect(color.strip("foo\e[176Abar")).to eq('foobar')
22
+ end
26
23
 
27
- it { is_expected.to eq('u@h W $ ') }
24
+ it 'strips reset/setfg/setbg/italics/strike/underline sequence' do
25
+ string = "\x1b[0;33;49;3;9;4mfoo\x1b[0m"
26
+ expect(color.strip(string)).to eq("foo")
28
27
  end
29
28
 
30
- context 'with octal with multiple colors' do
31
- let(:string) { "\e[3;0;0;t\e[8;50;0t" }
29
+ it 'strips octal in encapsulating brackets' do
30
+ string = "\[\033[01;32m\]u@h \[\033[01;34m\]W $ \[\033[00m\]"
31
+ expect(color.strip(string)).to eq('u@h W $ ')
32
+ end
32
33
 
33
- it { is_expected.to eq('') }
34
+ it 'strips octal codes without brackets' do
35
+ string = "\033[01;32mu@h \033[01;34mW $ \033[00m"
36
+ expect(color.strip(string)).to eq('u@h W $ ')
34
37
  end
35
38
 
36
- context 'with control codes' do
37
- let(:string ) { "WARN. \x1b[1m&\x1b[0m ERR. \x1b[7m&\x1b[0m" }
39
+ it 'strips octal with multiple colors' do
40
+ string = "\e[3;0;0;tfoo\e[8;50;0t"
41
+ expect(color.strip(string)).to eq('foo')
42
+ end
38
43
 
39
- it { is_expected.to eq('WARN. & ERR. &') }
44
+ it "strips multiple colors delimited by :" do
45
+ string = "\e[31:44:4mfoo\e[0m"
46
+ expect(color.strip(string)).to eq('foo')
40
47
  end
41
48
 
42
- context 'with escape byte' do
43
- let(:string) { "This is a \e[1m\e[34mbold blue text\e[0m" }
49
+ it 'strips control codes' do
50
+ string = "WARN. \x1b[1m&\x1b[0m ERR. \x1b[7m&\x1b[0m"
51
+ expect(color.strip(string)).to eq('WARN. & ERR. &')
52
+ end
44
53
 
45
- it { is_expected.to eq("This is a bold blue text") }
54
+ it 'strips escape bytes' do
55
+ string = "This is a \e[1m\e[34mbold blue text\e[0m"
56
+ expect(color.strip(string)).to eq("This is a bold blue text")
46
57
  end
47
58
  end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel::Color, '.valid?' do
6
+ it "detects valid colors" do
7
+ color = described_class.new
8
+ expect(color.valid?(:red, :on_green, :bold)).to eq(true)
9
+ end
10
+
11
+ it "detects valid color aliases" do
12
+ color = described_class.new
13
+ color.alias_color(:funky, :red)
14
+ expect(color.valid?(:funky)).to eq(true)
15
+ end
16
+
17
+ it "detects invalid color" do
18
+ color = described_class.new
19
+ expect(color.valid?(:red, :unknown)).to eq(false)
20
+ end
21
+ end
@@ -3,6 +3,21 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Pastel::Delegator do
6
+
7
+ it "returns delegator for color without argument" do
8
+ pastel = Pastel.new(enabled: true)
9
+ expect(pastel.red).to be_a(Pastel::Delegator)
10
+ end
11
+
12
+ describe ".inspect" do
13
+ it "inspects delegator styles chain" do
14
+ chain = ['red', 'on_green']
15
+ delegator = described_class.new(:resolver, chain)
16
+ allow(delegator).to receive(:styles).and_return({red: 31, on_green: 42})
17
+ expect(delegator.inspect).to eq("#<Pastel @styles=[\"red\", \"on_green\"]>")
18
+ end
19
+ end
20
+
6
21
  describe ".respond_to_missing?" do
7
22
  context 'for a method defined on' do
8
23
  it "returns true" do
@@ -93,11 +93,22 @@ RSpec.describe Pastel do
93
93
  end
94
94
  end
95
95
 
96
+ describe '.colored?' do
97
+ it "checks if string is colored" do
98
+ expect(pastel.colored?("\e[31mfoo\e[0m")).to eq(true)
99
+ end
100
+ end
101
+
96
102
  describe 'options passed in' do
97
103
  it "receives enabled option" do
98
104
  pastel = described_class.new(enabled: false)
99
105
  expect(pastel.enabled?).to eq(false)
100
106
  expect(pastel.red('Unicorn', pastel.green('!'))).to eq('Unicorn!')
101
107
  end
108
+
109
+ it "sets eachline option" do
110
+ pastel = described_class.new(enabled: true, eachline: "\n")
111
+ expect(pastel.red("foo\nbar")).to eq("\e[31mfoo\e[0m\n\e[31mbar\e[0m")
112
+ end
102
113
  end
103
114
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pastel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-22 00:00:00.000000000 Z
11
+ date: 2015-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: equatable
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: tty-screen
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.4'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -55,9 +69,11 @@ files:
55
69
  - LICENSE.txt
56
70
  - README.md
57
71
  - Rakefile
72
+ - assets/pastel_logo.png
58
73
  - assets/screenshot.png
59
74
  - benchmarks/nesting_speed.rb
60
75
  - benchmarks/speed.rb
76
+ - examples/palette.rb
61
77
  - lib/pastel.rb
62
78
  - lib/pastel/alias_importer.rb
63
79
  - lib/pastel/ansi.rb
@@ -73,10 +89,13 @@ files:
73
89
  - spec/unit/alias_importer_spec.rb
74
90
  - spec/unit/color/alias_color_spec.rb
75
91
  - spec/unit/color/code_spec.rb
92
+ - spec/unit/color/colored_spec.rb
76
93
  - spec/unit/color/decorate_spec.rb
94
+ - spec/unit/color/equal_spec.rb
95
+ - spec/unit/color/new_spec.rb
77
96
  - spec/unit/color/strip_spec.rb
78
97
  - spec/unit/color/styles_spec.rb
79
- - spec/unit/color/supports_spec.rb
98
+ - spec/unit/color/valid_spec.rb
80
99
  - spec/unit/decorator_chain_spec.rb
81
100
  - spec/unit/delegator_spec.rb
82
101
  - spec/unit/detach_spec.rb
@@ -115,10 +134,13 @@ test_files:
115
134
  - spec/unit/alias_importer_spec.rb
116
135
  - spec/unit/color/alias_color_spec.rb
117
136
  - spec/unit/color/code_spec.rb
137
+ - spec/unit/color/colored_spec.rb
118
138
  - spec/unit/color/decorate_spec.rb
139
+ - spec/unit/color/equal_spec.rb
140
+ - spec/unit/color/new_spec.rb
119
141
  - spec/unit/color/strip_spec.rb
120
142
  - spec/unit/color/styles_spec.rb
121
- - spec/unit/color/supports_spec.rb
143
+ - spec/unit/color/valid_spec.rb
122
144
  - spec/unit/decorator_chain_spec.rb
123
145
  - spec/unit/delegator_spec.rb
124
146
  - spec/unit/detach_spec.rb
@@ -1,49 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe Pastel::Color, '.supports?' do
6
-
7
- before { allow(ENV).to receive(:[]).with('PASTEL_COLORS_ALIASES') }
8
-
9
- it "isn't enabled for non tty terminal" do
10
- allow($stdout).to receive(:tty?).and_return(false)
11
- color = described_class.new
12
-
13
- expect(color.enabled?).to eq(false)
14
- expect(color.decorate("Unicorn", :red)).to eq("Unicorn")
15
- end
16
-
17
- it "isn't enabled for dumb terminal" do
18
- allow($stdout).to receive(:tty?).and_return(true)
19
- allow(ENV).to receive(:[]).with('TERM').and_return('dumb')
20
- color = described_class.new
21
-
22
- expect(color.enabled?).to eq(false)
23
- end
24
-
25
- it "is enabled for term with color support" do
26
- allow($stdout).to receive(:tty?).and_return(true)
27
- allow(ENV).to receive(:[]).with('TERM').and_return('xterm')
28
- color = described_class.new
29
-
30
- expect(color.enabled?).to eq(true)
31
- end
32
-
33
- it "is enabled for color terminal" do
34
- allow($stdout).to receive(:tty?).and_return(true)
35
- allow(ENV).to receive(:[]).with('TERM').and_return('unknown')
36
- allow(ENV).to receive(:[]).with('COLORTERM').and_return(true)
37
- color = described_class.new
38
-
39
- expect(color.enabled?).to eq(true)
40
- end
41
-
42
- it "forces to be enabled with supports? check" do
43
- color = described_class.new(enabled: false)
44
- allow(color).to receive(:supports?)
45
-
46
- expect(color.enabled?).to eq(false)
47
- expect(color).to_not have_received(:supports?)
48
- end
49
- end