pastel 0.2.1 → 0.3.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: c4843971da301b5bca7d4d9a6c69702859a3e9f9
4
- data.tar.gz: d176a98f33737965a8ae4a710b19c27ad31fe021
3
+ metadata.gz: a3a74798586ce6f5429d3c76faad4e3445319463
4
+ data.tar.gz: c2b581122d3029f273f29d5c6fcb9cbca064cc64
5
5
  SHA512:
6
- metadata.gz: 6c61ddb8e9be7aa678dde278f6229871f67ce53d60929367417fae521b35548e8cb7392bb029eb94bcceb141eca2705cb3fe214bcbc333162de591b4174b63f8
7
- data.tar.gz: acea298f36654c11b706bf72574e3b08980212188e6e432a95dd4fb10ae169e3026e344c28b9858dc1c0daed53c05aa059281e9bfc6044f35a3bb9ccf5f3a0bc
6
+ metadata.gz: c47eac8d882f22e8dc9c1217497ce9f4a2aea4371d523801e8c37261aad1fc9f03d8f2e7f45c7ab168f22c68621331e9201d7363d5ae357a129596110a7fa27c
7
+ data.tar.gz: e7fdf3e1428864ad525fb50dfb3fe6f9f760ce7923d91af73b7f9df054f22e51dbc0db969cbd2def2bcce3b4d6b8337addbc0ac1b406395fb88bf106f5ae8434
@@ -18,7 +18,6 @@ matrix:
18
18
  - rvm: jruby-head
19
19
  - rvm: jruby-20mode
20
20
  - rvm: jruby-21mode
21
- - rvm: rbx-2
22
21
  fast_finish: true
23
22
  branches:
24
23
  only: master
@@ -1,3 +1,10 @@
1
+ 0.3.0 (November 8, 2014)
2
+
3
+ * Add ability to alias colors through alias_color method
4
+ * Add ability to alias colors through the environment variable
5
+ * Improve performance of Pastel::Color styles and lookup methods
6
+ * Fix bug concerned with lack of escaping for nested styles
7
+
1
8
  0.2.1 (October 13, 2014)
2
9
 
3
10
  * Fix issue #1 with unitialize dependency
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ group :development do
6
6
  gem 'rake', '~> 10.3.2'
7
7
  gem 'rspec', '~> 3.1.0'
8
8
  gem 'yard', '~> 0.8.7'
9
+ gem 'benchmark-ips', '~> 2.0.0'
9
10
  end
10
11
 
11
12
  group :metrics do
data/README.md CHANGED
@@ -13,6 +13,8 @@ Terminal output styling with intuitive and clean API that doesn't monkey patch S
13
13
 
14
14
  ![screenshot](https://github.com/peter-murach/pastel/raw/master/assets/screenshot.png)
15
15
 
16
+ **Pastel** provides independent coloring component for [TTY](https://github.com/peter-murach/tty) toolkit.
17
+
16
18
  ## Features
17
19
 
18
20
  * Doesn't monkey patch `String`
@@ -45,7 +47,9 @@ Or install it yourself as:
45
47
  * [2.4 Styles](#24-styles)
46
48
  * [2.5 Valid?](#25-valid)
47
49
  * [2.6 Enabled?](#26-enabled)
48
- * [3. The available styles](#3-the-available-styles)
50
+ * [2.7 Alias Color](#27-alias-color)
51
+ * [3. Supported Colors](#3-supported-colors)
52
+ * [4. Environment](#4-environment)
49
53
 
50
54
  ## 1 Usage
51
55
 
@@ -91,7 +95,7 @@ You can pass variable number of styled strings like so:
91
95
  pastel.red('Unicorns ', pastel.bold.underline('everywhere'), '!')
92
96
  ```
93
97
 
94
- Please refer to [3. The available styles](#3-the-available-styles) section for full list of supported styles.
98
+ Please refer to [3. Supported Colors](#3-supported-colors) section for full list of supported styles.
95
99
 
96
100
  ### 2.2 Decorate
97
101
 
@@ -101,9 +105,11 @@ This method is a lower level string styling call that takes as the first argumen
101
105
  pastel.decorate('Unicorn', :green, :on_blue, :bold)
102
106
  ```
103
107
 
108
+ This method will be useful in situations where colors are provided as a list of parameters.
109
+
104
110
  ### 2.3 Strip
105
111
 
106
- Strip all color sequence characters:
112
+ 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.
107
113
 
108
114
  ```ruby
109
115
  pastel.strip("\e[1m\e[34mbold blue text\e[0m"") # => "bold blue text"
@@ -119,11 +125,11 @@ pastel.styles
119
125
 
120
126
  ### 2.5 Valid?
121
127
 
122
- Determine whether a color is valid:
128
+ Determine whether a color or a list of colors are valid. `valid?` takes one or more attribute strings or symbols and returns true if all attributes are known and false otherwise.
123
129
 
124
130
  ```ruby
125
- pastel.valid?(:red) # => true
126
- pastel.valid?(:unicorn) # => false
131
+ pastel.valid?(:red, :blue) # => true
132
+ pastel.valid?(:unicorn) # => false
127
133
  ```
128
134
 
129
135
  ### 2.6 Enabled?
@@ -141,7 +147,27 @@ pastel = Pastel.new(enabled: true)
141
147
  pastel.enabled? # => false
142
148
  ```
143
149
 
144
- ## 3 The available styles
150
+ ### 2.7 Alias Color
151
+
152
+ In order to setup an alias for the standard color do:
153
+
154
+ ```ruby
155
+ pastel.alias_color(:funky, :red)
156
+ ```
157
+
158
+ From that point forward, `:funky` alias can be passed to `decorate`, `valid?` with the same meaning as standard color:
159
+
160
+ ```ruby
161
+ pastel.funky.on_green('unicorn') # => will use :red color
162
+ ```
163
+
164
+ This method allows you to give more meaningful names to existing colors.
165
+
166
+ You can also use the `PASTEL_COLORS_ALIASES` environment variable (see [Environment](#4-environment)) to specify aliases.
167
+
168
+ Note: Aliases are global and affect all callers in the same process.
169
+
170
+ ## 3 Supported Colors
145
171
 
146
172
  **Pastel** works with terminal emulators that support minimum sixteen colors. It provides `16` basic colors and `8` styles with further `16` bright color pairs. The corresponding bright color is obtained by prepending the `bright` to the normal color name. For example, color `red` will have `bright_red` as its pair.
147
173
 
@@ -196,9 +222,21 @@ Generic styles:
196
222
  * `hidden`
197
223
  * `strikethrough`
198
224
 
225
+ ## 4 Environment
226
+
227
+ ### 4.1 PASTEL_COLORS_ALIASES
228
+
229
+ This environment variable allows you to specify custom color aliases at runtime that will be understood by **Pastel**. The environment variable is read and used when the instance of **Pastel** is created. You can also use `alias_color` to create aliases.
230
+
231
+ Only alphanumeric and `_` are allowed in the alias names with the following format:
232
+
233
+ ```ruby
234
+ PASTEL_COLORS_ALIASES='newcolor_1=red,newcolor_2=on_gree'
235
+ ```
236
+
199
237
  ## Contributing
200
238
 
201
- 1. Fork it ( https://github.com/[my-github-username]/pastel/fork )
239
+ 1. Fork it ( https://github.com/peter-murach/pastel/fork )
202
240
  2. Create your feature branch (`git checkout -b my-new-feature`)
203
241
  3. Commit your changes (`git commit -am 'Add some feature'`)
204
242
  4. Push to the branch (`git push origin my-new-feature`)
@@ -0,0 +1,16 @@
1
+ require 'pastel'
2
+ require 'benchmark/ips'
3
+
4
+ pastel = Pastel.new
5
+
6
+ Benchmark.ips do |bench|
7
+ bench.config(time: 5, warmup: 2)
8
+
9
+ bench.report('styles') do
10
+ pastel.styles
11
+ end
12
+
13
+ bench.report('decorate') do
14
+ pastel.decorate('string', :red, :on_green, :bold)
15
+ end
16
+ end
@@ -4,6 +4,7 @@ require 'forwardable'
4
4
  require 'equatable'
5
5
 
6
6
  require 'pastel/ansi'
7
+ require 'pastel/alias_importer'
7
8
  require 'pastel/color'
8
9
  require 'pastel/color_resolver'
9
10
  require 'pastel/delegator'
@@ -14,6 +15,9 @@ module Pastel
14
15
  # Raised when the style attribute is not supported
15
16
  InvalidAttributeNameError = Class.new(::ArgumentError)
16
17
 
18
+ # Raised when the color alias is not supported
19
+ InvalidAliasNameError = Class.new(::ArgumentError)
20
+
17
21
  # Create Pastel chainable API
18
22
  #
19
23
  # @example
@@ -24,6 +28,8 @@ module Pastel
24
28
  # @api public
25
29
  def new(options = {})
26
30
  color = Color.new(options)
31
+ importer = AliasImporter.new(color)
32
+ importer.import
27
33
  resolver = ColorResolver.new(color)
28
34
  Delegator.for(resolver, DecoratorChain.empty)
29
35
  end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ module Pastel
4
+ # A class responsible for importing color aliases
5
+ class AliasImporter
6
+ # Create alias importer
7
+ #
8
+ # @example
9
+ # importer = Pastel::AliasImporter.new(Pastel::Color.new)
10
+ #
11
+ # @api public
12
+ def initialize(color, output = $stderr)
13
+ @color = color
14
+ @output = output
15
+ end
16
+
17
+ # Import aliases from the environment
18
+ #
19
+ # @example
20
+ # importer = Pastel::AliasImporter.new(Pastel::Color.new)
21
+ # importer.import
22
+ #
23
+ # @return [nil]
24
+ #
25
+ # @api public
26
+ def import
27
+ color_aliases = ENV['PASTEL_COLORS_ALIASES']
28
+ return unless color_aliases
29
+ color_aliases.split(',').each do |color_alias|
30
+ new_color, old_color = color_alias.split('=').map(&:to_sym)
31
+ if !new_color || !old_color
32
+ output.puts "Bad color mapping `#{color_alias}`"
33
+ else
34
+ color.alias_color(new_color, old_color)
35
+ end
36
+ end
37
+ end
38
+
39
+ protected
40
+
41
+ attr_reader :color, :output
42
+ end # AliasImporter
43
+ end # Pastel
@@ -3,54 +3,54 @@
3
3
  module Pastel
4
4
  # Mixin that provides ANSI codes
5
5
  module ANSI
6
- CLEAR = "\e[0m"
6
+ ATTRIBUTES = {
7
+ clear: 0,
8
+ reset: 0,
9
+ bold: 1,
10
+ dark: 2,
11
+ dim: 2,
12
+ italic: 3,
13
+ underline: 4,
14
+ underscore: 4,
15
+ inverse: 7,
16
+ hidden: 8,
17
+ strikethrough: 9,
7
18
 
8
- BOLD = "\e[1m"
9
- DIM = "\e[2m"
10
- ITALIC = "\e[3m"
11
- UNDERLINE = "\e[4m"
12
- INVERSE = "\e[7m"
13
- HIDDEN = "\e[8m"
14
- STRIKETHROUGH = "\e[9m"
19
+ black: 30,
20
+ red: 31,
21
+ green: 32,
22
+ yellow: 33,
23
+ blue: 34,
24
+ magenta: 35,
25
+ cyan: 36,
26
+ white: 37,
15
27
 
16
- # Escape codes for text color.
17
- BLACK = "\e[30m"
18
- RED = "\e[31m"
19
- GREEN = "\e[32m"
20
- YELLOW = "\e[33m"
21
- BLUE = "\e[34m"
22
- MAGENTA = "\e[35m"
23
- CYAN = "\e[36m"
24
- WHITE = "\e[37m"
28
+ on_black: 40,
29
+ on_red: 41,
30
+ on_green: 42,
31
+ on_yellow: 43,
32
+ on_blue: 44,
33
+ on_magenta: 45,
34
+ on_cyan: 46,
35
+ on_white: 47,
25
36
 
26
- BRIGHT_BLACK = "\e[90m"
27
- BRIGHT_RED = "\e[91m"
28
- BRIGHT_GREEN = "\e[92m"
29
- BRIGHT_YELLOW = "\e[93m"
30
- BRIGHT_BLUE = "\e[94m"
31
- BRIGHT_MAGENTA = "\e[95m"
32
- BRIGHT_CYAN = "\e[96m"
33
- BRIGHT_WHITE = "\e[97m"
37
+ bright_black: 90,
38
+ bright_red: 91,
39
+ bright_green: 92,
40
+ bright_yellow: 93,
41
+ bright_blue: 94,
42
+ bright_magenta: 95,
43
+ bright_cyan: 96,
44
+ bright_white: 97,
34
45
 
35
- # Escape codes for background color.
36
- ON_BLACK = "\e[40m"
37
- ON_RED = "\e[41m"
38
- ON_GREEN = "\e[42m"
39
- ON_YELLOW = "\e[43m"
40
- ON_BLUE = "\e[44m"
41
- ON_MAGENTA = "\e[45m"
42
- ON_CYAN = "\e[46m"
43
- ON_WHITE = "\e[47m"
44
-
45
- ON_BRIGHT_BLACK = "\e[100m"
46
- ON_BRIGHT_RED = "\e[101m"
47
- ON_BRIGHT_GREEN = "\e[102m"
48
- ON_BRIGHT_YELLOW = "\e[103m"
49
- ON_BRIGHT_BLUE = "\e[104m"
50
- ON_BRIGHT_MAGENTA = "\e[105m"
51
- ON_BRIGHT_CYAN = "\e[106m"
52
- ON_BRIGHT_WHITE = "\e[107m"
53
-
54
- BACKGROUND_COLORS = constants.grep(/^ON_*/).freeze
46
+ on_bright_black: 100,
47
+ on_bright_red: 101,
48
+ on_bright_green: 102,
49
+ on_bright_yellow: 103,
50
+ on_bright_blue: 104,
51
+ on_bright_magenta: 105,
52
+ on_bright_cyan: 106,
53
+ on_bright_white: 107
54
+ }
55
55
  end # ANSI
56
56
  end # Pastel
@@ -6,6 +6,8 @@ module Pastel
6
6
  include Equatable
7
7
  include ANSI
8
8
 
9
+ ALIASES = {}
10
+
9
11
  attr_reader :enabled
10
12
  alias_method :enabled?, :enabled
11
13
 
@@ -45,27 +47,64 @@ module Pastel
45
47
  # text to add ANSI strings
46
48
  #
47
49
  # @param [Array[Symbol]] colors
50
+ # the color names
48
51
  #
49
52
  # @example
50
53
  # color.decorate "text", :yellow, :on_green, :underline
51
54
  #
52
55
  # @return [String]
56
+ # the colored string
53
57
  #
54
58
  # @api public
55
59
  def decorate(string, *colors)
56
60
  return string if string.empty? || !enabled
57
- validate(*colors)
58
- ansi_colors = colors.map { |color| lookup(color) }
59
- ansi_string = "#{ansi_colors.join}#{string}#{ANSI::CLEAR}"
60
- if ansi_string =~ /(#{Regexp.quote(ANSI::CLEAR)}){2,}/
61
- ansi_string.gsub!(/(#{Regexp.quote(ANSI::CLEAR)}){2,}/, '')
61
+
62
+ ansi_colors = lookup(*colors)
63
+ ansi_string = "#{ansi_colors}#{string}#{clear}"
64
+ ansi_string = nest_color(collapse_reset(ansi_string), ansi_colors)
65
+ ansi_string
66
+ end
67
+
68
+ def clear
69
+ lookup(:clear)
70
+ end
71
+
72
+ # Collapse reset
73
+ #
74
+ # @param [String] string
75
+ # the string to remove duplicates from
76
+ #
77
+ # @return [String]
78
+ #
79
+ # @api private
80
+ def collapse_reset(string)
81
+ ansi_string = string.dup
82
+ if ansi_string =~ /(#{Regexp.quote(clear)}){2,}/
83
+ ansi_string.gsub!(/(#{Regexp.quote(clear)}){2,}/, clear)
62
84
  end
63
- matches = ansi_string.scan(/#{Regexp.quote(ANSI::CLEAR)}/)
64
- if matches.length >= 2
65
- ansi_string.sub!(/#{Regexp.quote(ANSI::CLEAR)}/, ansi_colors.join)
85
+ ansi_string
86
+ end
87
+
88
+ # Nest color
89
+ #
90
+ # @param [String] string
91
+ # the string to decorate
92
+ #
93
+ # @param [String] ansi_colors
94
+ # the ansi colors to apply
95
+ #
96
+ # @return [String]
97
+ #
98
+ # @api private
99
+ def nest_color(string, ansi_colors)
100
+ ansi_string = string.dup
101
+ matches = ansi_string.scan(/#{Regexp.quote(clear)}/)
102
+ if matches.length > 1
103
+ ansi_string.sub!(/#{Regexp.quote(clear)}/, ansi_colors)
66
104
  end
67
105
  ansi_string
68
106
  end
107
+ private :collapse_reset, :nest_color
69
108
 
70
109
  # Same as instance method.
71
110
  #
@@ -79,6 +118,7 @@ module Pastel
79
118
  # Strip ANSI color codes from a string.
80
119
  #
81
120
  # @param [String] string
121
+ # the string to sanitize
82
122
  #
83
123
  # @return [String]
84
124
  #
@@ -94,21 +134,30 @@ module Pastel
94
134
  #
95
135
  # @api public
96
136
  def code(*colors)
97
- validate(*colors)
98
- colors.map { |color| lookup(color) }
137
+ attribute = []
138
+ colors.each do |color|
139
+ value = ANSI::ATTRIBUTES[color] || ALIASES[color]
140
+ if value
141
+ attribute << value
142
+ else
143
+ validate(color)
144
+ end
145
+ end
146
+ attribute
99
147
  end
100
148
 
101
149
  # Find color representation.
102
150
  #
103
- # @param [Symbol,String] color
104
- # the color name to lookup by
151
+ # @param [Symbol,String] colors
152
+ # the color name(s) to lookup
105
153
  #
106
154
  # @return [String]
107
- # the ANSI code
155
+ # the ANSI code(s)
108
156
  #
109
157
  # @api private
110
- def lookup(color)
111
- self.class.const_get(color.to_s.upcase)
158
+ def lookup(*colors)
159
+ attribute = code(*colors)
160
+ "\e[#{attribute.join(';')}m"
112
161
  end
113
162
 
114
163
  # Expose all ANSI color names and their codes
@@ -117,10 +166,7 @@ module Pastel
117
166
  #
118
167
  # @api public
119
168
  def styles
120
- ANSI.constants(false).each_with_object({}) do |col, acc|
121
- acc[col.to_sym.downcase] = lookup(col)
122
- acc
123
- end
169
+ ANSI::ATTRIBUTES.merge(ALIASES)
124
170
  end
125
171
 
126
172
  # List all available style names
@@ -135,16 +181,42 @@ module Pastel
135
181
  # Check if provided colors are known colors
136
182
  #
137
183
  # @param [Array[Symbol,String]]
138
- # the colors to check
184
+ # the list of colors to check
139
185
  #
140
186
  # @reutrn [Boolean]
187
+ # true if all colors are valid, false otherwise
141
188
  #
142
189
  # @api public
143
190
  def valid?(*colors)
144
191
  colors.all? { |color| style_names.include?(color.to_sym) }
145
192
  end
146
193
 
147
- protected
194
+ # Define a new color alias
195
+ #
196
+ # @param [String] alias_name
197
+ # the color alias to define
198
+ # @param [String] color
199
+ # the color the alias will correspond to
200
+ #
201
+ # @return [String]
202
+ # the standard color value of the alias
203
+ #
204
+ # @api public
205
+ def alias_color(alias_name, color)
206
+ validate(color)
207
+
208
+ if !(alias_name.to_s =~ /^[\w]+$/)
209
+ fail InvalidAliasNameError, "Invalid alias name `#{alias_name}`"
210
+ elsif ANSI::ATTRIBUTES[alias_name]
211
+ fail InvalidAliasNameError,
212
+ "Cannot alias standard color `#{alias_name}`"
213
+ end
214
+
215
+ ALIASES[alias_name.to_sym] = ANSI::ATTRIBUTES[color]
216
+ color
217
+ end
218
+
219
+ private
148
220
 
149
221
  # @api private
150
222
  def validate(*colors)
@@ -18,11 +18,12 @@ module Pastel
18
18
  @color = color
19
19
  end
20
20
 
21
+ # Resolve uncolored string
22
+ #
23
+ # @api private
21
24
  def resolve(base, *args)
22
25
  unprocessed_string = args.join
23
- base.reduce(unprocessed_string) do |component, decorator|
24
- color.decorate(component, decorator)
25
- end
26
+ color.decorate(unprocessed_string, *base)
26
27
  end
27
28
  end # ColorResolver
28
29
  end # Pastel
@@ -10,7 +10,7 @@ module Pastel
10
10
  include Equatable
11
11
 
12
12
  def_delegators '@resolver.color', :valid?, :styles, :strip, :decorate,
13
- :enabled?
13
+ :enabled?, :alias_color
14
14
 
15
15
  # Create Delegator
16
16
  #
@@ -31,6 +31,13 @@ module Pastel
31
31
  new(resolver, base)
32
32
  end
33
33
 
34
+ # Object string representation
35
+ #
36
+ # @api
37
+ def inspect
38
+ "<##{self.class.name}>"
39
+ end
40
+
34
41
  protected
35
42
 
36
43
  attr_reader :base
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Pastel
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel, '.alias_color' do
6
+
7
+ subject(:pastel) { described_class.new(enabled: true) }
8
+
9
+ it "aliases color" do
10
+ pastel.alias_color(:funky, :red)
11
+ expect(pastel.funky('unicorn')).to eq("\e[31municorn\e[0m")
12
+ end
13
+
14
+ it "aliases color and combines with regular ones" do
15
+ pastel.alias_color(:funky, :red)
16
+ expect(pastel.funky.on_green('unicorn')).to eq("\e[31;42municorn\e[0m")
17
+ end
18
+
19
+ it "reads aliases from the environment" do
20
+ color_aliases = "funky=red"
21
+ allow(ENV).to receive(:[]).with('PASTEL_COLORS_ALIASES').
22
+ and_return(color_aliases)
23
+ described_class.new(enabled: true)
24
+ expect(pastel.valid?(:funky)).to eq(true)
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel::AliasImporter, '.import' do
6
+ let(:color) { double(:color, alias_color: true) }
7
+ let(:output) { StringIO.new }
8
+
9
+ subject(:importer) { described_class.new(color, output) }
10
+
11
+ it "imports aliases from environment" do
12
+ color_aliases = "funky=red,base=bright_yellow"
13
+ allow(ENV).to receive(:[]).with('PASTEL_COLORS_ALIASES').
14
+ and_return(color_aliases)
15
+ importer.import
16
+ expect(color).to have_received(:alias_color).twice
17
+ end
18
+
19
+ it "fails to import incorrectly formattd colors" do
20
+ color_aliases = "funky red,base=bright_yellow"
21
+ allow(ENV).to receive(:[]).with('PASTEL_COLORS_ALIASES').
22
+ and_return(color_aliases)
23
+ importer.import
24
+ output.rewind
25
+ expect(output.string).to eq("Bad color mapping `funky red`\n")
26
+ expect(color).to have_received(:alias_color).with(:base, :bright_yellow)
27
+ end
28
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Pastel::Color, '.alias_color' do
6
+
7
+ subject(:color) { described_class.new(enabled: true) }
8
+
9
+ it 'aliases non existent color' do
10
+ expect {
11
+ color.alias_color(:funky, :unknown)
12
+ }.to raise_error(Pastel::InvalidAttributeNameError)
13
+ end
14
+
15
+ it 'aliases color with invalid name' do
16
+ expect {
17
+ color.alias_color('some name', :red)
18
+ }.to raise_error(Pastel::InvalidAliasNameError, /Invalid alias name/)
19
+ end
20
+
21
+ it 'aliases standard color' do
22
+ expect {
23
+ color.alias_color(:red, :red)
24
+ }.to raise_error(Pastel::InvalidAliasNameError, /alias standard color/)
25
+ end
26
+
27
+ it 'aliases color :red to :funky' do
28
+ color.alias_color(:funky, :red)
29
+ expect(color.valid?(:funky)).to eq(true)
30
+ expect(color.code(:funky)).to eq([31])
31
+ expect(color.lookup(:funky)).to eq("\e[31m")
32
+ end
33
+
34
+ it "has global aliases" do
35
+ color_foo = described_class.new(enabled: true)
36
+ color_bar = described_class.new(enabled: true)
37
+ color_foo.alias_color(:foo, :red)
38
+ color_bar.alias_color(:bar, :red)
39
+ expect(color_foo.valid?(:foo)).to eq(true)
40
+ expect(color_foo.valid?(:bar)).to eq(true)
41
+ end
42
+ end
@@ -8,11 +8,11 @@ RSpec.describe Pastel::Color, '.code' do
8
8
  subject(:color) { described_class.new(enabled: true) }
9
9
 
10
10
  it 'finds single code' do
11
- expect(color.code(:black)).to eq(["\e[30m"])
11
+ expect(color.code(:black)).to eq([30])
12
12
  end
13
13
 
14
14
  it 'finds more than one code' do
15
- expect(color.code(:black, :green)).to eq(["\e[30m", "\e[32m"])
15
+ expect(color.code(:black, :green)).to eq([30, 32])
16
16
  end
17
17
 
18
18
  it "doesn't find code" do
@@ -20,12 +20,12 @@ RSpec.describe Pastel::Color, '.decorate' do
20
20
  end
21
21
 
22
22
  it 'applies style and color to string' do
23
- expect(color.decorate(string, :bold, :green)).to eq("\e[1m\e[32m#{string}\e[0m")
23
+ expect(color.decorate(string, :bold, :green)).to eq("\e[1;32m#{string}\e[0m")
24
24
  end
25
25
 
26
26
  it 'applies style, color and background to string' do
27
27
  text = color.decorate(string, :bold, :green, :on_blue)
28
- expect(text).to eq("\e[1m\e[32m\e[44m#{string}\e[0m")
28
+ expect(text).to eq("\e[1;32;44m#{string}\e[0m")
29
29
  end
30
30
 
31
31
  it "applies styles to nested text" do
@@ -7,6 +7,6 @@ RSpec.describe Pastel::Color do
7
7
  subject(:color) { described_class.new(enabled: true) }
8
8
 
9
9
  it "exposes all available style ANSI codes" do
10
- expect(color.styles[:red]).to eq("\e[31m")
10
+ expect(color.styles[:red]).to eq(31)
11
11
  end
12
12
  end
@@ -3,6 +3,9 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Pastel::Color, '.supports?' do
6
+
7
+ before { allow(ENV).to receive(:[]).with('PASTEL_COLORS_ALIASES') }
8
+
6
9
  it "isn't enabled for non tty terminal" do
7
10
  allow($stdout).to receive(:tty?).and_return(false)
8
11
  color = described_class.new
@@ -24,14 +24,29 @@ RSpec.describe Pastel do
24
24
  to eq("\e[31mUnicorns\e[0m will rule \e[32mthe World!\e[0m")
25
25
  end
26
26
 
27
- it "composes color strings" do
27
+ it "composes two color strings " do
28
+ expect(pastel.red.on_green("unicorn")).to eq("\e[31;42municorn\e[0m")
29
+ end
30
+
31
+ it "composes three color strings" do
28
32
  expect(pastel.red.on_green.underline("unicorn")).
29
- to eq("\e[4m\e[42m\e[31municorn\e[0m")
33
+ to eq("\e[31;42;4municorn\e[0m")
34
+ end
35
+
36
+ it "combines colored composed strings with regular ones" do
37
+ expect(pastel.red.on_green("Unicorns") + ' will rule ' +
38
+ pastel.green.on_red('the World!')).
39
+ to eq("\e[31;42mUnicorns\e[0m will rule \e[32;41mthe World!\e[0m")
40
+ end
41
+
42
+ it "allows one level nesting" do
43
+ expect(pastel.red("Unicorn" + pastel.blue("rule!"))).
44
+ to eq("\e[31mUnicorn\e[34mrule!\e[0m")
30
45
  end
31
46
 
32
47
  it "allows to nest mixed styles" do
33
48
  expect(pastel.red("Unicorn" + pastel.green.on_yellow.underline('running') + '!')).
34
- to eq("\e[31mUnicorn\e[4m\e[43m\e[32mrunning\e[31m!\e[0m")
49
+ to eq("\e[31mUnicorn\e[32;43;4mrunning\e[31m!\e[0m")
35
50
  end
36
51
 
37
52
  it "allows for deep nesting" do
@@ -44,9 +59,15 @@ RSpec.describe Pastel do
44
59
  to eq("\e[31mr\e[32mg\e[31mr\e[0m")
45
60
  end
46
61
 
62
+ it "raises error when chained with unrecognized color" do
63
+ expect {
64
+ pastel.unknown.on_red('unicorn')
65
+ }.to raise_error(Pastel::InvalidAttributeNameError)
66
+ end
67
+
47
68
  it "raises error when doesn't recognize color" do
48
69
  expect {
49
- pastel.uknown('unicorn')
70
+ pastel.unknown('unicorn')
50
71
  }.to raise_error(Pastel::InvalidAttributeNameError)
51
72
  end
52
73
  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.2.1
4
+ version: 0.3.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-10-13 00:00:00.000000000 Z
11
+ date: 2014-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: equatable
@@ -56,7 +56,9 @@ files:
56
56
  - README.md
57
57
  - Rakefile
58
58
  - assets/screenshot.png
59
+ - benchmarks/speed.rb
59
60
  - lib/pastel.rb
61
+ - lib/pastel/alias_importer.rb
60
62
  - lib/pastel/ansi.rb
61
63
  - lib/pastel/color.rb
62
64
  - lib/pastel/color_resolver.rb
@@ -65,6 +67,9 @@ files:
65
67
  - lib/pastel/version.rb
66
68
  - pastel.gemspec
67
69
  - spec/spec_helper.rb
70
+ - spec/unit/alias_color_spec.rb
71
+ - spec/unit/alias_importer_spec.rb
72
+ - spec/unit/color/alias_color_spec.rb
68
73
  - spec/unit/color/code_spec.rb
69
74
  - spec/unit/color/decorate_spec.rb
70
75
  - spec/unit/color/strip_spec.rb
@@ -102,6 +107,9 @@ specification_version: 4
102
107
  summary: Terminal strings styling with intuitive and clean API.
103
108
  test_files:
104
109
  - spec/spec_helper.rb
110
+ - spec/unit/alias_color_spec.rb
111
+ - spec/unit/alias_importer_spec.rb
112
+ - spec/unit/color/alias_color_spec.rb
105
113
  - spec/unit/color/code_spec.rb
106
114
  - spec/unit/color/decorate_spec.rb
107
115
  - spec/unit/color/strip_spec.rb