From 060e5b3c77d3f1958480a35e3eb57f4a041ae9be Mon Sep 17 00:00:00 2001 From: Daniel Vandersluis Date: Sat, 23 Jan 2021 14:25:11 -0500 Subject: [PATCH] Fix `#value` for a `dstr` node. --- changelog/change_fix_value_for_a_dstr_node.md | 1 + lib/rubocop/ast.rb | 1 + lib/rubocop/ast/builder.rb | 2 +- lib/rubocop/ast/node/dstr_node.rb | 16 ++++++++ spec/rubocop/ast/dstr_node_spec.rb | 38 +++++++++++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 changelog/change_fix_value_for_a_dstr_node.md create mode 100644 lib/rubocop/ast/node/dstr_node.rb create mode 100644 spec/rubocop/ast/dstr_node_spec.rb diff --git a/changelog/change_fix_value_for_a_dstr_node.md b/changelog/change_fix_value_for_a_dstr_node.md new file mode 100644 index 000000000..adc818b54 --- /dev/null +++ b/changelog/change_fix_value_for_a_dstr_node.md @@ -0,0 +1 @@ +* [#167](https://github.com/rubocop-hq/rubocop-ast/pull/167): Fix `#value` for `dstr` nodes to return the actual string value. ([@dvandersluis][]) diff --git a/lib/rubocop/ast.rb b/lib/rubocop/ast.rb index 416bd3342..be4be80ac 100644 --- a/lib/rubocop/ast.rb +++ b/lib/rubocop/ast.rb @@ -72,6 +72,7 @@ require_relative 'ast/node/self_class_node' require_relative 'ast/node/send_node' require_relative 'ast/node/str_node' +require_relative 'ast/node/dstr_node' require_relative 'ast/node/super_node' require_relative 'ast/node/symbol_node' require_relative 'ast/node/until_node' diff --git a/lib/rubocop/ast/builder.rb b/lib/rubocop/ast/builder.rb index e875fbd32..51409cbcc 100644 --- a/lib/rubocop/ast/builder.rb +++ b/lib/rubocop/ast/builder.rb @@ -42,6 +42,7 @@ class Builder < Parser::Builders::Default def: DefNode, defined?: DefinedNode, defs: DefNode, + dstr: DstrNode, ensure: EnsureNode, for: ForNode, forward_args: ForwardArgsNode, @@ -68,7 +69,6 @@ class Builder < Parser::Builders::Default csend: SendNode, send: SendNode, str: StrNode, - dstr: StrNode, xstr: StrNode, sclass: SelfClassNode, super: SuperNode, diff --git a/lib/rubocop/ast/node/dstr_node.rb b/lib/rubocop/ast/node/dstr_node.rb new file mode 100644 index 000000000..413569898 --- /dev/null +++ b/lib/rubocop/ast/node/dstr_node.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module RuboCop + module AST + # A node extension for `dstr` nodes. This will be used + # in place of a plain node when the builder constructs the AST, making + # its methods available to all `dstr` nodes within RuboCop. + class DstrNode < StrNode + def value + child_nodes.map do |child| + child.respond_to?(:value) ? child.value : child.source + end.join + end + end + end +end diff --git a/spec/rubocop/ast/dstr_node_spec.rb b/spec/rubocop/ast/dstr_node_spec.rb new file mode 100644 index 000000000..156ced2bc --- /dev/null +++ b/spec/rubocop/ast/dstr_node_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +RSpec.describe RuboCop::AST::DstrNode do + subject(:dstr_node) { parse_source(source).ast } + + describe '#value' do + subject { dstr_node.value } + + context 'with a multiline string' do + let(:source) do + <<~RUBY + 'this is a multiline ' \ + 'string' + RUBY + end + + it { is_expected.to eq('this is a multiline string') } + end + + context 'with interpolation' do + let(:source) do + '"foo #{bar} baz"' + end + + it { is_expected.to eq('foo #{bar} baz') } + end + + context 'with implicit concatenation' do + let(:source) do + <<~RUBY + 'foo ' 'bar ' 'baz' + RUBY + end + + it { is_expected.to eq('foo bar baz') } + end + end +end