diff options
author | HASUMI Hitoshi <hasumikin@gmail.com> | 2023-11-06 23:40:38 +0900 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2023-11-06 14:40:42 +0000 |
commit | 16403f41abcbaccf32484d10575d3542dbb3247e (patch) | |
tree | afca50d51bcb5bcb432dc35581fa7f251ea02dc0 /test | |
parent | f6ba87ca8899cd753306ffbca475b16c367995a3 (diff) |
[ruby/reline] Introduce a new class Reline::Face to configure
character attributes
(https://github.com/ruby/reline/pull/552)
* Reine::Face
* fix test_yamatanooroti
* Define singleton methods to make accessors to attributes of a face
* s/display/foreground/
* s/default/default_style/ && s/normal_line/default/ && s/enhanced_line/enhanced/
* fix typo
* FaceConfig.new now takes keyword arguments
* Update lib/reline/face.rb
Co-authored-by: Stan Lo <stan001212@gmail.com>
* Update test/reline/test_face.rb
Co-authored-by: Stan Lo <stan001212@gmail.com>
* Fix to correspond to frozen_string_literal
* Face::FaceConfig -> Face::Config
* ref https://github.com/ruby/reline/pull/552#pullrequestreview-1677282576
* delete unused ivar
* ref https://github.com/ruby/reline/pull/552#discussion_r1358783723
* insert "\e[0m" into all SGR
* tiny fix
* ESSENTIAL_DEFINE_NAMES
ref https://github.com/ruby/reline/pull/552#discussion_r1367722247
* Change to Hash-accessor style
- Reline::Face[:completion_dialog].enhanced ->
Reline::Face[:completion_dialog][:enhanced]
- Reline::Face.configs shows all defined values
* Cache array method call in local variable
* Tests for Face configuration variations
* resolve https://github.com/ruby/reline/pull/552#pullrequestreview-1710938154
* amend to
* check invalid SGR parameter in :style
* The order of define values should be preserved
* Update test/reline/test_face.rb
Co-authored-by: Stan Lo <stan001212@gmail.com>
* Update test/reline/test_face.rb
Co-authored-by: Stan Lo <stan001212@gmail.com>
* Add methods: load_initial_config and reset_to_initial_config. And teardown in tests
* omission in amending "style: :default" to "style: :reset"
* refs https://github.com/ruby/reline/issues/598
* Fix link
* amend method name
* Update lib/reline/face.rb
Co-authored-by: ima1zumi <52617472+ima1zumi@users.noreply.github.com>
---------
https://github.com/ruby/reline/commit/fdc1d3b1e5
Co-authored-by: Stan Lo <stan001212@gmail.com>
Co-authored-by: ima1zumi <52617472+ima1zumi@users.noreply.github.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/reline/helper.rb | 1 | ||||
-rw-r--r-- | test/reline/test_face.rb | 204 | ||||
-rwxr-xr-x | test/reline/yamatanooroti/multiline_repl | 2 | ||||
-rw-r--r-- | test/reline/yamatanooroti/test_rendering.rb | 155 |
4 files changed, 301 insertions, 61 deletions
diff --git a/test/reline/helper.rb b/test/reline/helper.rb index fb2262e7f5..4d0c883c86 100644 --- a/test/reline/helper.rb +++ b/test/reline/helper.rb @@ -4,6 +4,7 @@ ENV['TERM'] = 'xterm' # for some CI environments require 'reline' require 'test/unit' +require 'test/unit/rr' begin require 'rbconfig' diff --git a/test/reline/test_face.rb b/test/reline/test_face.rb new file mode 100644 index 0000000000..371b4b0d2e --- /dev/null +++ b/test/reline/test_face.rb @@ -0,0 +1,204 @@ +# frozen_string_literal: true + +require_relative 'helper' + +class Reline::Face::Test < Reline::TestCase + RESET_SGR = "\e[0m" + + def teardown + Reline::Face.reset_to_initial_configs + end + + class WithInsufficientSetupTest < self + def setup + Reline::Face.config(:my_insufficient_config) do |face| + end + @face = Reline::Face[:my_insufficient_config] + end + + def test_my_insufficient_config_line + assert_equal RESET_SGR, @face[:default] + assert_equal RESET_SGR, @face[:enhanced] + assert_equal RESET_SGR, @face[:scrollbar] + end + + def test_my_insufficient_configs + my_configs = Reline::Face.configs[:my_insufficient_config] + assert_equal( + { + default: { style: :reset, escape_sequence: RESET_SGR }, + enhanced: { style: :reset, escape_sequence: RESET_SGR }, + scrollbar: { style: :reset, escape_sequence: RESET_SGR } + }, + my_configs + ) + end + end + + class WithSetupTest < self + def setup + Reline::Face.config(:my_config) do |face| + face.define :default, foreground: :blue + face.define :enhanced, foreground: "#FF1020", background: :black, style: [:bold, :underlined] + end + Reline::Face.config(:another_config) do |face| + face.define :another_label, foreground: :red + end + @face = Reline::Face[:my_config] + end + + def test_now_there_are_four_configs + assert_equal %i(default completion_dialog my_config another_config), Reline::Face.configs.keys + end + + def test_resetting_config_discards_user_defined_configs + Reline::Face.reset_to_initial_configs + assert_equal %i(default completion_dialog), Reline::Face.configs.keys + end + + def test_my_configs + my_configs = Reline::Face.configs[:my_config] + assert_equal( + { + default: { + escape_sequence: "#{RESET_SGR}\e[34m", foreground: :blue + }, + enhanced: { + background: :black, + foreground: "#FF1020", + style: [:bold, :underlined], + escape_sequence: "\e[0m\e[38;2;255;16;32;40;1;4m" + }, + scrollbar: { + style: :reset, + escape_sequence: "\e[0m" + } + }, + my_configs + ) + end + + def test_my_config_line + assert_equal "#{RESET_SGR}\e[34m", @face[:default] + end + + def test_my_config_enhanced + assert_equal "#{RESET_SGR}\e[38;2;255;16;32;40;1;4m", @face[:enhanced] + end + + def test_not_respond_to_another_label + assert_equal false, @face.respond_to?(:another_label) + end + end + + class WithoutSetupTest < self + def test_my_config_default + Reline::Face.config(:my_config) do |face| + # do nothing + end + face = Reline::Face[:my_config] + assert_equal RESET_SGR, face[:default] + end + + def test_style_does_not_exist + face = Reline::Face[:default] + assert_raise ArgumentError do + face[:style_does_not_exist] + end + end + + def test_invalid_keyword + assert_raise ArgumentError do + Reline::Face.config(:invalid_config) do |face| + face.define :default, invalid_keyword: :red + end + end + end + + def test_invalid_foreground_name + assert_raise ArgumentError do + Reline::Face.config(:invalid_config) do |face| + face.define :default, foreground: :invalid_name + end + end + end + + def test_invalid_background_name + assert_raise ArgumentError do + Reline::Face.config(:invalid_config) do |face| + face.define :default, background: :invalid_name + end + end + end + + def test_invalid_style_name + assert_raise ArgumentError do + Reline::Face.config(:invalid_config) do |face| + face.define :default, style: :invalid_name + end + end + end + + def test_private_constants + [:SGR_PARAMETER, :Config, :CONFIGS].each do |name| + assert_equal false, Reline::Face.constants.include?(name) + end + end + end + + class ConfigTest < self + def setup + @config = Reline::Face.const_get(:Config).new(:my_config) { } + end + + def test_the_order_of_define_values_should_be_preserved + any_instance_of(Reline::Face.const_get(:Config)) do |config| + mock(config).format_to_sgr( + [[:foreground, :blue], [:style, [:bold, :italicized]], [:background, :red]] + ) + end + Reline::Face.config(:my_config) do |face| + face.define :default, foreground: :blue, style: [:bold, :italicized], background: :red + end + end + + def test_rgb? + assert_equal true, @config.send(:rgb_expression?, "#FFFFFF") + end + + def test_invalid_rgb? + assert_equal false, @config.send(:rgb_expression?, "FFFFFF") + assert_equal false, @config.send(:rgb_expression?, "#FFFFF") + end + + def test_format_to_sgr + assert_equal( + "#{RESET_SGR}\e[37;41;1;3m", + @config.send(:format_to_sgr, foreground: :white, background: :red, style: [:bold, :italicized]) + ) + end + + def test_format_to_sgr_with_reset + assert_equal( + RESET_SGR, + @config.send(:format_to_sgr, style: :reset) + ) + assert_equal( + "#{RESET_SGR}\e[37;0;41m", + @config.send(:format_to_sgr, foreground: :white, style: :reset, background: :red) + ) + end + + def test_format_to_sgr_with_single_style + assert_equal( + "#{RESET_SGR}\e[37;41;1m", + @config.send(:format_to_sgr, foreground: :white, background: :red, style: :bold) + ) + end + + def test_sgr_rgb + assert_equal "38;2;255;255;255", @config.send(:sgr_rgb, :foreground, "#ffffff") + assert_equal "48;2;18;52;86", @config.send(:sgr_rgb, :background, "#123456") + end + end +end diff --git a/test/reline/yamatanooroti/multiline_repl b/test/reline/yamatanooroti/multiline_repl index bdefc48faa..e2a900b251 100755 --- a/test/reline/yamatanooroti/multiline_repl +++ b/test/reline/yamatanooroti/multiline_repl @@ -136,7 +136,7 @@ opt.on('--dialog VAL') { |v| if v.include?('alt-scrollbar') scrollbar = true end - Reline::DialogRenderInfo.new(pos: cursor_pos, contents: contents, height: height, scrollbar: scrollbar) + Reline::DialogRenderInfo.new(pos: cursor_pos, contents: contents, height: height, scrollbar: scrollbar, face: :completion_dialog) }) if v.include?('alt-scrollbar') ENV['RELINE_ALT_SCROLLBAR'] = '1' diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb index 8ac0c0c096..670432d86b 100644 --- a/test/reline/yamatanooroti/test_rendering.rb +++ b/test/reline/yamatanooroti/test_rendering.rb @@ -4,6 +4,33 @@ begin require 'yamatanooroti' class Reline::RenderingTest < Yamatanooroti::TestCase + + FACE_CONFIGS = { no_config: "", valid_config: <<~VALID_CONFIG, incomplete_config: <<~INCOMPLETE_CONFIG } + require "reline" + Reline::Face.config(:completion_dialog) do |face| + face.define :default, foreground: :white, background: :blue + face.define :enhanced, foreground: :white, background: :magenta + face.define :scrollbar, foreground: :white, background: :blue + end + VALID_CONFIG + require "reline" + Reline::Face.config(:completion_dialog) do |face| + face.define :default, foreground: :white, background: :black + face.define :scrollbar, foreground: :white, background: :cyan + end + INCOMPLETE_CONFIG + + def iterate_over_face_configs(&block) + FACE_CONFIGS.each do |config_name, face_config| + config_file = Tempfile.create(%w{face_config- .rb}) + config_file.write face_config + block.call(config_name, config_file) + config_file.close + ensure + File.delete(config_file) + end + end + def setup @pwd = Dir.pwd suffix = '%010d' % Random.rand(0..65535) @@ -954,75 +981,83 @@ begin end def test_simple_dialog - start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') - write('a') - write('b') - write('c') - write("\C-h") - close - assert_screen(<<~'EOC') - Multiline REPL. - prompt> ab - Ruby is... - A dynamic, open source programming - language with a focus on simplicity - and productivity. It has an elegant - syntax that is natural to read and - easy to write. - EOC + iterate_over_face_configs do |config_name, config_file| + start_terminal(20, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') + write('a') + write('b') + write('c') + write("\C-h") + close + assert_screen(<<~'EOC', "Failed with `#{config_name}` in Face") + Multiline REPL. + prompt> ab + Ruby is... + A dynamic, open source programming + language with a focus on simplicity + and productivity. It has an elegant + syntax that is natural to read and + easy to write. + EOC + end end def test_simple_dialog_at_right_edge - start_terminal(20, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') - write('a') - write('b') - write('c') - write("\C-h") - close - assert_screen(<<~'EOC') - Multiline REPL. - prompt> ab - Ruby is... - A dynamic, open source programming - language with a focus on simplicity - and productivity. It has an elegant - syntax that is natural to read and - easy to write. - EOC + iterate_over_face_configs do |config_name, config_file| + start_terminal(20, 40, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') + write('a') + write('b') + write('c') + write("\C-h") + close + assert_screen(<<~'EOC') + Multiline REPL. + prompt> ab + Ruby is... + A dynamic, open source programming + language with a focus on simplicity + and productivity. It has an elegant + syntax that is natural to read and + easy to write. + EOC + end end def test_dialog_scroll_pushup_condition - start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') - write("\n" * 10) - write("if 1\n sSt\nend") - write("\C-p\C-h\C-e") - close - assert_screen(<<~'EOC') - prompt> - prompt> - prompt> - prompt> - prompt> - prompt> - prompt> if 1 - prompt> St - prompt> enString - Struct - EOC + iterate_over_face_configs do |config_name, config_file| + start_terminal(10, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.') + write("\n" * 10) + write("if 1\n sSt\nend") + write("\C-p\C-h\C-e") + close + assert_screen(<<~'EOC') + prompt> + prompt> + prompt> + prompt> + prompt> + prompt> + prompt> if 1 + prompt> St + prompt> enString + Struct + EOC + end end def test_simple_dialog_with_scroll_screen - start_terminal(5, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') - write("if 1\n 2\n 3\n 4\n 5\n 6") - write("\C-p\C-n\C-p\C-p\C-p#") - close - assert_screen(<<~'EOC') - prompt> 2 - prompt> 3# - prompt> 4 - prompt> 5 - prompt> 6 Ruby is... - EOC + iterate_over_face_configs do |config_name, config_file| + start_terminal(5, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.') + write("if 1\n 2\n 3\n 4\n 5\n 6") + write("\C-p\C-n\C-p\C-p\C-p#") + close + assert_screen(<<~'EOC') + prompt> 2 + prompt> 3# + prompt> 4 + prompt> 5 + prompt> 6 Ruby is... + EOC + end end def test_autocomplete_at_bottom |