spec/astrolabe/node_spec.rb in astrolabe-0.4.0 vs spec/astrolabe/node_spec.rb in astrolabe-0.5.0

- old
+ new

@@ -50,10 +50,30 @@ let(:target_node) { root_node.each_child_node.to_a.first } it { is_expected.to be false } end end + shared_examples 'node enumerator' do |method_name| + context 'when no block is given' do + it 'returns an enumerator' do + expect(target_node.send(method_name)).to be_a Enumerator + end + + describe 'the returned enumerator' do + subject(:enumerator) { target_node.send(method_name) } + + it 'enumerates ancestor nodes' do + expected_types.each do |expected_type| + expect(enumerator.next.type).to eq(expected_type) + end + + expect { enumerator.next }.to raise_error(StopIteration) + end + end + end + end + describe '#each_ancestor' do let(:source) { <<-END } class SomeClass attr_reader :some_attr @@ -92,25 +112,45 @@ returned_value = target_node.each_ancestor {} expect(returned_value).to equal(target_node) end end - context 'when no block is given' do - it 'returns an enumerator' do - expect(target_node.each_ancestor).to be_a Enumerator + include_examples 'node enumerator', :each_ancestor + + context 'when a node type symbol is passed' do + it 'scans all the ancestor nodes but yields only nodes matching the type' do + yielded_types = [] + + target_node.each_ancestor(:begin) do |node| + yielded_types << node.type + end + + expect(yielded_types).to eq([:begin]) end + end - describe 'the returned enumerator' do - subject(:enumerator) { target_node.each_ancestor } + context 'when multiple node type symbols are passed' do + it 'scans all the ancestor nodes but yields only nodes matching any of the types' do + yielded_types = [] - it 'enumerates ancestor nodes' do - expected_types.each do |expected_type| - expect(enumerator.next.type).to eq(expected_type) - end + target_node.each_ancestor(:begin, :def) do |node| + yielded_types << node.type + end - expect { enumerator.next }.to raise_error(StopIteration) + expect(yielded_types).to eq([:def, :begin]) + end + end + + context 'when an array including type symbols are passed' do + it 'scans all the ancestor nodes but yields only nodes matching any of the types' do + yielded_types = [] + + target_node.each_ancestor([:begin, :def]) do |node| + yielded_types << node.type end + + expect(yielded_types).to eq([:def, :begin]) end end end describe '#each_child_node' do @@ -144,25 +184,45 @@ returned_value = target_node.each_child_node {} expect(returned_value).to equal(target_node) end end - context 'when no block is given' do - it 'returns an enumerator' do - expect(target_node.each_child_node).to be_a(Enumerator) + include_examples 'node enumerator', :each_child_node + + context 'when a node type symbol is passed' do + it 'scans all the child nodes but yields only nodes matching the type' do + yielded_types = [] + + target_node.each_child_node(:send) do |node| + yielded_types << node.type + end + + expect(yielded_types).to eq([:send]) end + end - describe 'the returned enumerator' do - subject(:enumerator) { target_node.each_child_node } + context 'when multiple node type symbols are passed' do + it 'scans all the child nodes but yields only nodes matching any of the types' do + yielded_types = [] - it 'enumerates the child nodes' do - expected_types.each do |expected_type| - expect(enumerator.next.type).to eq(expected_type) - end + target_node.each_child_node(:send, :args) do |node| + yielded_types << node.type + end - expect { enumerator.next }.to raise_error(StopIteration) + expect(yielded_types).to eq([:args, :send]) + end + end + + context 'when an array including type symbols are passed' do + it 'scans all the child nodes but yields only nodes matching any of the types' do + yielded_types = [] + + target_node.each_child_node([:send, :args]) do |node| + yielded_types << node.type end + + expect(yielded_types).to eq([:args, :send]) end end end describe '#each_descendant' do @@ -205,25 +265,45 @@ returned_value = target_node.each_descendant {} expect(returned_value).to equal(target_node) end end - context 'when no block is given' do - it 'returns an enumerator' do - expect(target_node.each_descendant).to be_a(Enumerator) + include_examples 'node enumerator', :each_descendant + + context 'when a node type symbol is passed' do + it 'scans all the descendant nodes but yields only nodes matching the type' do + yielded_types = [] + + target_node.each_descendant(:send) do |node| + yielded_types << node.type + end + + expect(yielded_types).to eq([:send, :send]) end + end - describe 'the returned enumerator' do - subject(:enumerator) { target_node.each_descendant } + context 'when multiple node type symbols are passed' do + it 'scans all the descendant nodes but yields only nodes matching any of the types' do + yielded_types = [] - it 'enumerates the descendant nodes' do - expected_types.each do |expected_type| - expect(enumerator.next.type).to eq(expected_type) - end + target_node.each_descendant(:send, :def) do |node| + yielded_types << node.type + end - expect { enumerator.next }.to raise_error(StopIteration) + expect(yielded_types).to eq([:send, :def, :send]) + end + end + + context 'when an array including type symbols are passed' do + it 'scans all the descendant nodes but yields only nodes matching any of the types' do + yielded_types = [] + + target_node.each_descendant([:send, :def]) do |node| + yielded_types << node.type end + + expect(yielded_types).to eq([:send, :def, :send]) end end end describe '#each_node' do @@ -250,11 +330,11 @@ let(:target_node) { root_node } let(:expected_types) { [:class, :const, :begin, :send, :sym, :def, :args, :arg, :arg, :send] } context 'when a block is given' do - it 'yields itself and each descendant node with depth first order' do + it 'yields the node itself and each descendant node with depth first order' do yielded_types = [] target_node.each_node do |node| yielded_types << node.type end @@ -266,24 +346,44 @@ returned_value = target_node.each_node {} expect(returned_value).to equal(target_node) end end - context 'when no block is given' do - it 'returns an enumerator' do - expect(target_node.each_node).to be_a(Enumerator) + include_examples 'node enumerator', :each_node + + context 'when a node type symbol is passed' do + it 'scans all the nodes but yields only nodes matching the type' do + yielded_types = [] + + target_node.each_node(:send) do |node| + yielded_types << node.type + end + + expect(yielded_types).to eq([:send, :send]) end + end - describe 'the returned enumerator' do - subject(:enumerator) { target_node.each_node } + context 'when multiple node type symbols are passed' do + it 'scans all the nodes but yields only nodes matching any of the types' do + yielded_types = [] - it 'enumerates the origin and the descendant nodes' do - expected_types.each do |expected_type| - expect(enumerator.next.type).to eq(expected_type) - end + target_node.each_node(:send, :def) do |node| + yielded_types << node.type + end - expect { enumerator.next }.to raise_error(StopIteration) + expect(yielded_types).to eq([:send, :def, :send]) + end + end + + context 'when an array including type symbols are passed' do + it 'scans all the nodes but yields only nodes matching any of the types' do + yielded_types = [] + + target_node.each_node([:send, :def]) do |node| + yielded_types << node.type end + + expect(yielded_types).to eq([:send, :def, :send]) end end end describe '#send_type?' do