Skip to content

Commit

Permalink
Fix frozen string literal issue
Browse files Browse the repository at this point in the history
  • Loading branch information
chaadow committed Jun 16, 2024
1 parent 292cb22 commit 5020475
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 9 deletions.
20 changes: 18 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,21 @@ permissions:
contents: read

jobs:
Shared:
uses: fog/.github/.github/workflows/[email protected]
test:

runs-on: ubuntu-latest

strategy:
matrix:
ruby-version: ['3.0', '3.1', '3.2', '3.3', 'head']
continue-on-error: ${{ matrix.ruby-version == 'head' }}

steps:
- uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Run tests
run: bundle exec rake RUBYOPT="--enable-frozen-string-literal"
2 changes: 1 addition & 1 deletion lib/fog/parsers/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def reset
end

def characters(string)
@value ||= ''
@value ||= +''
@value << string
end

Expand Down
10 changes: 6 additions & 4 deletions lib/fog/to_hash_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@ def initialize
end

def characters(string)
@value ||= ""
@value ||= +""
@value << string.strip
end

def end_element(name)
last = @stack.pop
if last.empty? && @value.empty?
@stack.push({}) if @stack.empty?

if last && last.empty? && @value.empty?
@stack.last[name.to_sym] = ""
elsif last == { :i_nil => "true" }
@stack.last[name.to_sym] = nil
elsif !@value.empty?
@stack.last[name.to_sym] = @value
end
@value = ""
@value = +""
end

def body
Expand All @@ -30,7 +32,7 @@ def response
end

def start_element(name, attributes = [])
@value = ""
@value = +""
parsed_attributes = {}
until attributes.empty?
if attributes.first.is_a?(Array)
Expand Down
4 changes: 2 additions & 2 deletions lib/fog/xml/response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Response
def initialize(parser)
@parser = parser
@data_stream = Nokogiri::XML::SAX::PushParser.new(parser)
@response_string = ""
@response_string = +""
end

def call(chunk, _remaining, _total)
Expand All @@ -14,7 +14,7 @@ def call(chunk, _remaining, _total)

def rewind
@parser.reset
@response_string = ""
@response_string = +""
end

def finish
Expand Down
125 changes: 125 additions & 0 deletions spec/fog/to_hash_document_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
require 'minitest_helper'
require 'fog/xml'

# We expose accessors just for testing purposes
Fog::ToHashDocument.attr_accessor(:value, :stack)

describe Fog::ToHashDocument do
before do
@document = Fog::ToHashDocument.new
end

describe '#characters' do
it 'appends characters to @value' do
@document.characters("some text")
_(@document.value).must_equal "some text"
end

it 'strips whitespace from characters' do
@document.characters(" some text ")
_(@document.value).must_equal "some text"
end
end

describe '#end_element' do
before do
@document.stack << {}
@document.characters("some text")
end

it 'adds element with text content to the stack' do
@document.end_element('element')

_(@document.stack.last).must_equal({ element: "some text" })
end

it 'can mutate the new empty value' do
@document.end_element('element')

_(@document.value).must_equal("")

# Mutate the new empty value even when frozen string literals are enabled
_(@document.characters('one'))
end

it 'adds empty string if element is empty and value is empty' do
@document.value = ""
@document.end_element('element')
_(@document.stack.last).must_equal({ element: "" })
end

it 'adds nil if element has :i_nil attribute' do
@document.stack.last[:i_nil] = "true"
@document.value = ""

@document.end_element('element')

_(@document.stack.last).must_equal({ element: nil })
end
end

describe '#body' do
it 'returns the first element of the stack' do
@document.stack << { key: "value" }

_(@document.body).must_equal({ key: "value" })
end
end

describe '#response' do
it 'returns the body' do
@document.stack << { key: "value" }

_(@document.response).must_equal({ key: "value" })
end
end

describe '#start_element' do
it 'parses attributes correctly' do
@document.start_element('element', [['key', 'value']])

_(@document.stack.last).must_equal({ key: 'value' })
end

it 'handles elements without attributes' do
@document.start_element('element')

_(@document.stack.last).must_equal({})
end

it 'adds nested elements to the stack' do
@document.start_element('parent')
@document.start_element('child')

_(@document.stack).must_equal([{:child=>{}}, {:child=>{}}, {}])
end

it 'adds nested elements with attributes to the stack' do
@document.start_element('parent')
@document.start_element('child', [['key', 'value']])

_(@document.stack).must_equal([{:child=>{:key=>"value"}}, {:child=>{:key=>"value"}}, {:key=>"value"}] )
end

it 'handles multiple children elements correctly' do
@document.start_element('parent')
@document.start_element('child1')
@document.end_element('child1')
@document.start_element('child2', [['key', 'value']])
@document.end_element('child2')

_(@document.stack.first).must_equal({
child1: "",
child2: { key: 'value' }
})
end

it 'handles text content within elements' do
@document.start_element('parent')
@document.characters('some text')
@document.end_element('parent')

_(@document.stack.first).must_equal({ parent: 'some text' })
end
end
end

0 comments on commit 5020475

Please sign in to comment.