spec/lib/rambling/trie/compressor_spec.rb
# frozen_string_literal: true
require 'spec_helper'
describe Rambling::Trie::Compressor do
let(:compressor) { described_class.new }
describe '#compress' do
let(:node) { Rambling::Trie::Nodes::Raw.new }
it 'compresses the node' do
add_words node, %w(a few words hello hell)
compressed = compressor.compress node
expect(compressed.children_tree.keys).to eq %i(a f w h)
end
context 'with at least one word' do
before { add_words node, %w(all the words) }
it 'keeps the node letter nil' do
compressed = compressor.compress node
expect(compressed.letter).to be_nil
end
end
context 'with a single word' do
before { add_word node, 'all' }
# rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
it 'compresses into a single node without children' do
compressed = compressor.compress node
compressed_node_a = compressed[:a]
expect(compressed_node_a.letter).to eq :all
expect(compressed_node_a.children.size).to eq 0
expect(compressed_node_a).to be_terminal
expect(compressed_node_a).to be_compressed
end
# rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
end
context 'with two words' do
before { add_words node, %w(all ask) }
# rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
it 'compresses into corresponding three nodes' do
compressed = compressor.compress node
expect(compressed[:a].letter).to eq :a
expect(compressed[:a].children.size).to eq 2
expect(compressed[:a][:l].letter).to eq :ll
expect(compressed[:a][:s].letter).to eq :sk
expect(compressed[:a][:l].children.size).to eq 0
expect(compressed[:a][:s].children.size).to eq 0
expect(compressed[:a][:l]).to be_terminal
expect(compressed[:a][:s]).to be_terminal
expect(compressed[:a][:l]).to be_compressed
expect(compressed[:a][:s]).to be_compressed
end
# rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
end
# rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
it 'reassigns the parent nodes correctly' do
add_words node, %w(repay rest repaint)
compressed = compressor.compress node
expect(compressed[:r].letter).to eq :re
expect(compressed[:r].parent).to eq compressed
expect(compressed[:r].children.size).to eq 2
expect(compressed[:r][:p].letter).to eq :pa
expect(compressed[:r][:p].parent).to eq compressed[:r]
expect(compressed[:r][:p].children.size).to eq 2
expect(compressed[:r][:s].letter).to eq :st
expect(compressed[:r][:s].parent).to eq compressed[:r]
expect(compressed[:r][:s].children.size).to eq 0
expect(compressed[:r][:p][:y].letter).to eq :y
expect(compressed[:r][:p][:y].parent).to eq compressed[:r][:p]
expect(compressed[:r][:p][:y].children.size).to eq 0
expect(compressed[:r][:p][:i].letter).to eq :int
expect(compressed[:r][:p][:i].parent).to eq compressed[:r][:p]
expect(compressed[:r][:p][:i].children.size).to eq 0
end
# rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
# rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
it 'does not compress terminal nodes' do
add_words node, %w(you your yours)
compressed = compressor.compress node
expect(compressed[:y].letter).to eq :you
expect(compressed[:y][:r].letter).to eq :r
expect(compressed[:y][:r]).to be_compressed
expect(compressed[:y][:r][:s].letter).to eq :s
expect(compressed[:y][:r][:s]).to be_compressed
end
# rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
end
end