require "json"
require "config/helper"
require "fluent/config/error"
require "fluent/config/basic_parser"
require "fluent/config/literal_parser"
require "fluent/config/v1_parser"
describe Fluent::Config::V1Parser do
include_context 'config_helper'
def parse_text(text)
basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
Fluent::Config::V1Parser.parse(text, '(test)', basepath, nil)
end
def root(*elements)
if elements.first.is_a?(Fluent::Config::Element)
attrs = {}
else
attrs = elements.shift || {}
end
Fluent::Config::Element.new('ROOT', '', attrs, elements)
end
def e(name, arg='', attrs={}, elements=[])
Fluent::Config::Element.new(name, arg, attrs, elements)
end
describe 'attribute parsing' do
it "parses attributes" do
%[
k1 v1
k2 v2
].should be_parsed_as("k1"=>"v1", "k2"=>"v2")
end
it "allows attribute without value" do
%[
k1
k2 v2
].should be_parsed_as("k1"=>"", "k2"=>"v2")
end
it "parses attribute key always string" do
"1 1".should be_parsed_as("1" => "1")
end
[
"_.%$!,",
"/=~-~@`:?",
"()*{}.[]",
].each do |v|
it "parses a value with symbol #{v.inspect}" do
"k #{v}".should be_parsed_as("k" => v)
end
end
it "ignores spacing around value" do
" k1 a ".should be_parsed_as("k1" => "a")
end
it "allows spaces in value" do
"k1 a b c".should be_parsed_as("k1" => "a b c")
end
it "ignores comments after value" do
" k1 a#comment".should be_parsed_as("k1" => "a")
end
it "allows # in value if quoted" do
' k1 "a#comment"'.should be_parsed_as("k1" => "a#comment")
end
it "rejects characters after quoted string" do
' k1 "a" 1'.should be_parse_error
end
end
describe 'element parsing' do
it do
"".should be_parsed_as(root)
end
it "accepts empty element" do
%[
].should be_parsed_as(
root(
e("test")
)
)
end
it "accepts argument and attributes" do
%[
key val
].should be_parsed_as(root(
e("test", 'var', {'key'=>"val"})
))
end
it "accepts nested elements" do
%[
key 1
].should be_parsed_as(root(
e("test", 'var', {'key'=>'val'}, [
e('nested1'),
e('nested2')
])
))
end
[
"**",
"*.*",
"1",
"_.%$!",
"/",
"()*{}.[]",
].each do |arg|
it "parses element argument #{arg.inspect}" do
%[
].should be_parsed_as(root(
e("test", arg)
))
end
end
it "parses empty element argument to nil" do
%[
].should be_parsed_as(root(
e("test", nil)
))
end
it "ignores spacing around element argument" do
%[
].should be_parsed_as(root(
e("test", "a")
))
end
it "considers comments in element argument" do
%[
].should be_parse_error
end
it "requires line_end after begin tag" do
%[
].should be_parse_error
end
it "requires line_end after end tag" do
%[
].should be_parse_error
end
end
# port from test_config.rb
describe '@include parsing' do
TMP_DIR = File.dirname(__FILE__) + "/tmp/v1_config#{ENV['TEST_ENV_NUMBER']}"
def write_config(path, data)
FileUtils.mkdir_p(File.dirname(path))
File.open(path, "w") { |f| f.write data }
end
def prepare_config
write_config "#{TMP_DIR}/config_test_1.conf", %[
k1 root_config
include dir/config_test_2.conf #
@include #{TMP_DIR}/config_test_4.conf
include file://#{TMP_DIR}/config_test_5.conf
@include config.d/*.conf
]
write_config "#{TMP_DIR}/dir/config_test_2.conf", %[
k2 relative_path_include
@include ../config_test_3.conf
]
write_config "#{TMP_DIR}/config_test_3.conf", %[
k3 relative_include_in_included_file
]
write_config "#{TMP_DIR}/config_test_4.conf", %[
k4 absolute_path_include
]
write_config "#{TMP_DIR}/config_test_5.conf", %[
k5 uri_include
]
write_config "#{TMP_DIR}/config.d/config_test_6.conf", %[
k6 wildcard_include_1
include normal_parameter
]
write_config "#{TMP_DIR}/config.d/config_test_7.conf", %[
k7 wildcard_include_2
]
write_config "#{TMP_DIR}/config.d/config_test_8.conf", %[
@include ../dir/config_test_9.conf
]
write_config "#{TMP_DIR}/dir/config_test_9.conf", %[
k9 embeded
nested nested_value
include hoge
]
write_config "#{TMP_DIR}/config.d/00_config_test_8.conf", %[
k8 wildcard_include_3
include normal_parameter
]
end
it 'parses @include / include correctly' do
prepare_config
c = Fluent::Config.read("#{TMP_DIR}/config_test_1.conf", true)
expect(c['k1']).to eq('root_config')
expect(c['k2']).to eq('relative_path_include')
expect(c['k3']).to eq('relative_include_in_included_file')
expect(c['k4']).to eq('absolute_path_include')
expect(c['k5']).to eq('uri_include')
expect(c['k6']).to eq('wildcard_include_1')
expect(c['k7']).to eq('wildcard_include_2')
expect(c['k8']).to eq('wildcard_include_3')
expect(c.keys).to eq([
'k1',
'k2',
'k3',
'k4',
'k5',
'k8', # Because of the file name this comes first.
'k6',
'k7',
])
elem1 = c.elements.find { |e| e.name == 'elem1' }
expect(elem1).to be
expect(elem1.arg).to eq('name')
expect(elem1['include']).to eq('normal_parameter')
elem2 = c.elements.find { |e| e.name == 'elem2' }
expect(elem2).to be
expect(elem2.arg).to eq('name')
expect(elem2['k9']).to eq('embeded')
expect(elem2.has_key?('include')).to be(false)
elem3 = elem2.elements.find { |e| e.name == 'elem3' }
expect(elem3).to be
expect(elem3['nested']).to eq('nested_value')
expect(elem3['include']).to eq('hoge')
end
# TODO: Add uri based include spec
end
end