From d60dd83161055153f932df26811dfc0558ad495e Mon Sep 17 00:00:00 2001 From: Nathan Weizenbaum Date: Tue, 10 Nov 2009 18:03:53 -0800 Subject: [PATCH 1/3] [Sass] Expand the tests for HSL-RGB conversion. --- test/sass/data/hsl-rgb.txt | 319 ++++++++++++++++++++++++++++++++++++ test/sass/functions_test.rb | 54 ++---- 2 files changed, 330 insertions(+), 43 deletions(-) create mode 100644 test/sass/data/hsl-rgb.txt diff --git a/test/sass/data/hsl-rgb.txt b/test/sass/data/hsl-rgb.txt new file mode 100644 index 00000000..2e9e470d --- /dev/null +++ b/test/sass/data/hsl-rgb.txt @@ -0,0 +1,319 @@ +hsl(0, 100%, 50%) +hsl(60, 100%, 50%) +hsl(120, 100%, 50%) +hsl(180, 100%, 50%) +hsl(240, 100%, 50%) +hsl(300, 100%, 50%) +==== +rgb(255, 0, 0) +rgb(255, 255, 0) +rgb(0, 255, 0) +rgb(0, 255, 255) +rgb(0, 0, 255) +rgb(255, 0, 255) + +hsl(-360, 100%, 50%) +hsl(-300, 100%, 50%) +hsl(-240, 100%, 50%) +hsl(-180, 100%, 50%) +hsl(-120, 100%, 50%) +hsl(-60, 100%, 50%) +==== +rgb(255, 0, 0) +rgb(255, 255, 0) +rgb(0, 255, 0) +rgb(0, 255, 255) +rgb(0, 0, 255) +rgb(255, 0, 255) + +hsl(360, 100%, 50%) +hsl(420, 100%, 50%) +hsl(480, 100%, 50%) +hsl(540, 100%, 50%) +hsl(600, 100%, 50%) +hsl(660, 100%, 50%) +==== +rgb(255, 0, 0) +rgb(255, 255, 0) +rgb(0, 255, 0) +rgb(0, 255, 255) +rgb(0, 0, 255) +rgb(255, 0, 255) + +hsl(6120, 100%, 50%) +hsl(-9660, 100%, 50%) +hsl(99840, 100%, 50%) +hsl(-900, 100%, 50%) +hsl(-104880, 100%, 50%) +hsl(2820, 100%, 50%) +==== +rgb(255, 0, 0) +rgb(255, 255, 0) +rgb(0, 255, 0) +rgb(0, 255, 255) +rgb(0, 0, 255) +rgb(255, 0, 255) + +hsl(0, 100%, 50%) +hsl(12, 100%, 50%) +hsl(24, 100%, 50%) +hsl(36, 100%, 50%) +hsl(48, 100%, 50%) +hsl(60, 100%, 50%) +hsl(72, 100%, 50%) +hsl(84, 100%, 50%) +hsl(96, 100%, 50%) +hsl(108, 100%, 50%) +hsl(120, 100%, 50%) +==== +rgb(255, 0, 0) +rgb(255, 51, 0) +rgb(255, 102, 0) +rgb(255, 153, 0) +rgb(255, 204, 0) +rgb(255, 255, 0) +rgb(204, 255, 0) +rgb(153, 255, 0) +rgb(102, 255, 0) +rgb(51, 255, 0) +rgb(0, 255, 0) + +hsl(120, 100%, 50%) +hsl(132, 100%, 50%) +hsl(144, 100%, 50%) +hsl(156, 100%, 50%) +hsl(168, 100%, 50%) +hsl(180, 100%, 50%) +hsl(192, 100%, 50%) +hsl(204, 100%, 50%) +hsl(216, 100%, 50%) +hsl(228, 100%, 50%) +hsl(240, 100%, 50%) +==== +rgb(0, 255, 0) +rgb(0, 255, 51) +rgb(0, 255, 102) +rgb(0, 255, 153) +rgb(0, 255, 204) +rgb(0, 255, 255) +rgb(0, 204, 255) +rgb(0, 153, 255) +rgb(0, 102, 255) +rgb(0, 51, 255) +rgb(0, 0, 255) + +hsl(240, 100%, 50%) +hsl(252, 100%, 50%) +hsl(264, 100%, 50%) +hsl(276, 100%, 50%) +hsl(288, 100%, 50%) +hsl(300, 100%, 50%) +hsl(312, 100%, 50%) +hsl(324, 100%, 50%) +hsl(336, 100%, 50%) +hsl(348, 100%, 50%) +hsl(360, 100%, 50%) +==== +rgb(0, 0, 255) +rgb(51, 0, 255) +rgb(102, 0, 255) +rgb(153, 0, 255) +rgb(204, 0, 255) +rgb(255, 0, 255) +rgb(255, 0, 204) +rgb(255, 0, 153) +rgb(255, 0, 102) +rgb(255, 0, 51) +rgb(255, 0, 0) + +hsl(0, 20%, 50%) +hsl(0, 60%, 50%) +hsl(0, 100%, 50%) +==== +rgb(153, 102, 102) +rgb(204, 51, 51) +rgb(255, 0, 0) + +hsl(60, 20%, 50%) +hsl(60, 60%, 50%) +hsl(60, 100%, 50%) +==== +rgb(153, 153, 102) +rgb(204, 204, 51) +rgb(255, 255, 0) + +hsl(120, 20%, 50%) +hsl(120, 60%, 50%) +hsl(120, 100%, 50%) +==== +rgb(102, 153, 102) +rgb(51, 204, 51) +rgb(0, 255, 0) + +hsl(180, 20%, 50%) +hsl(180, 60%, 50%) +hsl(180, 100%, 50%) +==== +rgb(102, 153, 153) +rgb(51, 204, 204) +rgb(0, 255, 255) + +hsl(240, 20%, 50%) +hsl(240, 60%, 50%) +hsl(240, 100%, 50%) +==== +rgb(102, 102, 153) +rgb(51, 51, 204) +rgb(0, 0, 255) + +hsl(300, 20%, 50%) +hsl(300, 60%, 50%) +hsl(300, 100%, 50%) +==== +rgb(153, 102, 153) +rgb(204, 51, 204) +rgb(255, 0, 255) + +hsl(0, 100%, 0%) +hsl(0, 100%, 10%) +hsl(0, 100%, 20%) +hsl(0, 100%, 30%) +hsl(0, 100%, 40%) +hsl(0, 100%, 50%) +hsl(0, 100%, 60%) +hsl(0, 100%, 70%) +hsl(0, 100%, 80%) +hsl(0, 100%, 90%) +hsl(0, 100%, 100%) +==== +rgb(0, 0, 0) +rgb(51, 0, 0) +rgb(102, 0, 0) +rgb(153, 0, 0) +rgb(204, 0, 0) +rgb(255, 0, 0) +rgb(255, 51, 51) +rgb(255, 102, 102) +rgb(255, 153, 153) +rgb(255, 204, 204) +rgb(255, 255, 255) + +hsl(60, 100%, 0%) +hsl(60, 100%, 10%) +hsl(60, 100%, 20%) +hsl(60, 100%, 30%) +hsl(60, 100%, 40%) +hsl(60, 100%, 50%) +hsl(60, 100%, 60%) +hsl(60, 100%, 70%) +hsl(60, 100%, 80%) +hsl(60, 100%, 90%) +hsl(60, 100%, 100%) +==== +rgb(0, 0, 0) +rgb(51, 51, 0) +rgb(102, 102, 0) +rgb(153, 153, 0) +rgb(204, 204, 0) +rgb(255, 255, 0) +rgb(255, 255, 51) +rgb(255, 255, 102) +rgb(255, 255, 153) +rgb(255, 255, 204) +rgb(255, 255, 255) + +hsl(120, 100%, 0%) +hsl(120, 100%, 10%) +hsl(120, 100%, 20%) +hsl(120, 100%, 30%) +hsl(120, 100%, 40%) +hsl(120, 100%, 50%) +hsl(120, 100%, 60%) +hsl(120, 100%, 70%) +hsl(120, 100%, 80%) +hsl(120, 100%, 90%) +hsl(120, 100%, 100%) +==== +rgb(0, 0, 0) +rgb(0, 51, 0) +rgb(0, 102, 0) +rgb(0, 153, 0) +rgb(0, 204, 0) +rgb(0, 255, 0) +rgb(51, 255, 51) +rgb(102, 255, 102) +rgb(153, 255, 153) +rgb(204, 255, 204) +rgb(255, 255, 255) + +hsl(180, 100%, 0%) +hsl(180, 100%, 10%) +hsl(180, 100%, 20%) +hsl(180, 100%, 30%) +hsl(180, 100%, 40%) +hsl(180, 100%, 50%) +hsl(180, 100%, 60%) +hsl(180, 100%, 70%) +hsl(180, 100%, 80%) +hsl(180, 100%, 90%) +hsl(180, 100%, 100%) +==== +rgb(0, 0, 0) +rgb(0, 51, 51) +rgb(0, 102, 102) +rgb(0, 153, 153) +rgb(0, 204, 204) +rgb(0, 255, 255) +rgb(51, 255, 255) +rgb(102, 255, 255) +rgb(153, 255, 255) +rgb(204, 255, 255) +rgb(255, 255, 255) + +hsl(240, 100%, 0%) +hsl(240, 100%, 10%) +hsl(240, 100%, 20%) +hsl(240, 100%, 30%) +hsl(240, 100%, 40%) +hsl(240, 100%, 50%) +hsl(240, 100%, 60%) +hsl(240, 100%, 70%) +hsl(240, 100%, 80%) +hsl(240, 100%, 90%) +hsl(240, 100%, 100%) +==== +rgb(0, 0, 0) +rgb(0, 0, 51) +rgb(0, 0, 102) +rgb(0, 0, 153) +rgb(0, 0, 204) +rgb(0, 0, 255) +rgb(51, 51, 255) +rgb(102, 102, 255) +rgb(153, 153, 255) +rgb(204, 204, 255) +rgb(255, 255, 255) + +hsl(300, 100%, 0%) +hsl(300, 100%, 10%) +hsl(300, 100%, 20%) +hsl(300, 100%, 30%) +hsl(300, 100%, 40%) +hsl(300, 100%, 50%) +hsl(300, 100%, 60%) +hsl(300, 100%, 70%) +hsl(300, 100%, 80%) +hsl(300, 100%, 90%) +hsl(300, 100%, 100%) +==== +rgb(0, 0, 0) +rgb(51, 0, 51) +rgb(102, 0, 102) +rgb(153, 0, 153) +rgb(204, 0, 204) +rgb(255, 0, 255) +rgb(255, 51, 255) +rgb(255, 102, 255) +rgb(255, 153, 255) +rgb(255, 204, 255) +rgb(255, 255, 255) diff --git a/test/sass/functions_test.rb b/test/sass/functions_test.rb index 446ab202..2e76679f 100644 --- a/test/sass/functions_test.rb +++ b/test/sass/functions_test.rb @@ -3,44 +3,17 @@ require File.dirname(__FILE__) + '/../../lib/sass' require 'sass/script' class SassFunctionTest < Test::Unit::TestCase - def test_hsl - # These tests adapted from the w3c browser tests - # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-h-rotating-b.htm - red = [255, 0, 0] - assert_rgb_hsl(red, ['0', '100%', '50%']) - assert_rgb_hsl(red, ['-360', '100%', '50%']) - assert_rgb_hsl(red, ['360', '100%', '50%']) - assert_rgb_hsl(red, ['6120', '100%', '50%']) - - yellow = [255, 255, 0] - assert_rgb_hsl(yellow, ['60', '100%', '50%']) - assert_rgb_hsl(yellow, ['-300', '100%', '50%']) - assert_rgb_hsl(yellow, ['420', '100%', '50%']) - assert_rgb_hsl(yellow, ['-9660', '100%', '50%']) - - green = [0, 255, 0] - assert_rgb_hsl(green, ['120', '100%', '50%']) - assert_rgb_hsl(green, ['-240', '100%', '50%']) - assert_rgb_hsl(green, ['480', '100%', '50%']) - assert_rgb_hsl(green, ['99840', '100%', '50%']) - - cyan = [0, 255, 255] - assert_rgb_hsl(cyan, ['180', '100%', '50%']) - assert_rgb_hsl(cyan, ['-180', '100%', '50%']) - assert_rgb_hsl(cyan, ['540', '100%', '50%']) - assert_rgb_hsl(cyan, ['-900', '100%', '50%']) - - blue = [0, 0, 255] - assert_rgb_hsl(blue, ['240', '100%', '50%']) - assert_rgb_hsl(blue, ['-120', '100%', '50%']) - assert_rgb_hsl(blue, ['600', '100%', '50%']) - assert_rgb_hsl(blue, ['-104880', '100%', '50%']) - - purple = [255, 0, 255] - assert_rgb_hsl(purple, ['300', '100%', '50%']) - assert_rgb_hsl(purple, ['-60', '100%', '50%']) - assert_rgb_hsl(purple, ['660', '100%', '50%']) - assert_rgb_hsl(purple, ['2820', '100%', '50%']) + # Tests taken from: + # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-h-rotating-b.htm + # http://www.w3.org/Style/CSS/Test/CSS3/Color/20070927/html4/t040204-hsl-values-b.htm + File.read(File.dirname(__FILE__) + "/data/hsl-rgb.txt").split("\n\n").each do |chunk| + hsls, rgbs = chunk.strip.split("====") + hsls.strip.split("\n").zip(rgbs.strip.split("\n")) do |hsl, rgb| + method = "test_hsl: #{hsl} = #{rgb}" + define_method(method) do + assert_equal(evaluate(rgb), evaluate(hsl)) + end + end end def test_hsl_checks_bounds @@ -107,11 +80,6 @@ class SassFunctionTest < Test::Unit::TestCase private - def assert_rgb_hsl(rgb, hsl) - hsl = hsl.map {|v| Sass::Script::Parser.parse v, 0, 0 } - assert_equal(rgb, Sass::Script::Functions::EvaluationContext.new({}).hsl(*hsl).value) - end - def evaluate(value) Sass::Script::Parser.parse(value, 0, 0).perform(Sass::Environment.new).to_s end From a5c26d047c40110b470bd0ee30304c97d38d250f Mon Sep 17 00:00:00 2001 From: Nathan Weizenbaum Date: Tue, 10 Nov 2009 18:27:13 -0800 Subject: [PATCH 2/3] [Sass] Deprecate Sass::Script::Color#value in favor of Sass::Script::Color#rgb. --- doc-src/SASS_CHANGELOG.md | 5 +++++ lib/sass/script/color.rb | 32 +++++++++++++++++++++++++------- test/sass/functions_test.rb | 2 +- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/doc-src/SASS_CHANGELOG.md b/doc-src/SASS_CHANGELOG.md index 790a7900..3f9d65ca 100644 --- a/doc-src/SASS_CHANGELOG.md +++ b/doc-src/SASS_CHANGELOG.md @@ -5,6 +5,11 @@ ## 2.2.14 (Unreleased) +* {Sass::Script::Color#value} attribute is deprecated. + Use {Sass::Script::Color#rgb} instead. + This only affects people defining their own Sass functions + in Ruby. + ### Rack Support Sass 2.2.14 includes Rack middleware for running Sass, diff --git a/lib/sass/script/color.rb b/lib/sass/script/color.rb index 5681e58e..49d0116d 100644 --- a/lib/sass/script/color.rb +++ b/lib/sass/script/color.rb @@ -36,6 +36,25 @@ module Sass::Script super(rgb) end + # @deprecated This will be removed in version 2.6. + # @see #rgb + def value + warn <] A three-element array of the red, green, and blue + # values (respectively) of the color + def rgb + @value + end + # The SassScript `+` operation. # Its functionality depends on the type of its argument: # @@ -157,8 +176,8 @@ module Sass::Script # # @return [String] The string representation def to_s - return HTML4_COLORS_REVERSE[@value] if HTML4_COLORS_REVERSE[@value] - red, green, blue = @value.map { |num| num.to_s(16).rjust(2, '0') } + return HTML4_COLORS_REVERSE[rgb] if HTML4_COLORS_REVERSE[rgb] + red, green, blue = rgb.map { |num| num.to_s(16).rjust(2, '0') } "##{red}#{green}#{blue}" end alias_method :inspect, :to_s @@ -167,17 +186,16 @@ module Sass::Script def piecewise(other, operation) other_num = other.is_a? Number - other_val = other.value if other_num && !other.unitless? raise Sass::SyntaxError.new("Cannot add a number with units (#{other}) to a color (#{self}).") end - rgb = [] + result = [] for i in (0...3) - res = @value[i].send(operation, other_num ? other_val : other_val[i]) - rgb[i] = [ [res, 255].min, 0 ].max + res = rgb[i].send(operation, other_num ? other.value : other.rgb[i]) + result[i] = [ [res, 255].min, 0 ].max end - Color.new(rgb) + Color.new(result) end end end diff --git a/test/sass/functions_test.rb b/test/sass/functions_test.rb index 446ab202..85992612 100644 --- a/test/sass/functions_test.rb +++ b/test/sass/functions_test.rb @@ -109,7 +109,7 @@ class SassFunctionTest < Test::Unit::TestCase def assert_rgb_hsl(rgb, hsl) hsl = hsl.map {|v| Sass::Script::Parser.parse v, 0, 0 } - assert_equal(rgb, Sass::Script::Functions::EvaluationContext.new({}).hsl(*hsl).value) + assert_equal(rgb, Sass::Script::Functions::EvaluationContext.new({}).hsl(*hsl).rgb) end def evaluate(value) From 6098d2345f98ea22bd529d142e74d7d34174c205 Mon Sep 17 00:00:00 2001 From: Nathan Weizenbaum Date: Tue, 10 Nov 2009 18:29:48 -0800 Subject: [PATCH 3/3] [Sass] Add #red, #green, and #blue accessors for Script::Color. --- lib/sass/script/color.rb | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/sass/script/color.rb b/lib/sass/script/color.rb index 49d0116d..cb3c43da 100644 --- a/lib/sass/script/color.rb +++ b/lib/sass/script/color.rb @@ -27,13 +27,31 @@ module Sass::Script # A hash from [red, green, blue] value arrays to color names. HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]} + # The red component of the color. + # + # @return [Fixnum] + attr_reader :red + + # The green component of the color. + # + # @return [Fixnum] + attr_reader :green + + # The blue component of the color. + # + # @return [Fixnum] + attr_reader :blue + # @param rgb [Array] A three-element array of the red, green, and blue values (respectively) # of the color # @raise [Sass::SyntaxError] if any color value isn't between 0 and 255 def initialize(rgb) rgb = rgb.map {|c| c.to_i} raise Sass::SyntaxError.new("Color values must be between 0 and 255") if rgb.any? {|c| c < 0 || c > 255} - super(rgb) + @red = rgb[0] + @green = rgb[1] + @blue = rgb[2] + super(nil) end # @deprecated This will be removed in version 2.6. @@ -52,7 +70,18 @@ END # @return [Array] A three-element array of the red, green, and blue # values (respectively) of the color def rgb - @value + [red, green, blue] + end + + # The SassScript `==` operation. + # **Note that this returns a {Sass::Script::Bool} object, + # not a Ruby boolean**. + # + # @param other [Literal] The right-hand side of the operator + # @return [Bool] True if this literal is the same as the other, + # false otherwise + def eq(other) + Sass::Script::Bool.new(other.is_a?(Color) && rgb == other.rgb) end # The SassScript `+` operation.