require 'spec_helper' require 'flydata-core/table_def' module FlydataCore module TableDef describe RedshiftTableDef do let(:subject_object) { described_class } let(:table_name) { 'test_table' } describe '.from_flydata_tabledef' do subject { subject_object.from_flydata_tabledef(flydata_tabledef, option) } let(:value_column_hash) { { column: "value", type: "text" } } let(:value_column) { value_column_hash } let(:value_type_body) { 'text' } let(:value_type) { value_type_body } let(:flydata_tabledef) { { table_name: "test_table", columns: [ { column: "id", type: "int4(11)", not_null: true, primary_key: true }, { column: "age", type: "int4(11) unsigned" }, value_column, ], default_charset: "UTF_8", src_ddl: "dummy_src_ddl"} } let(:option) { { flydata_ctl_table: false } } let(:schema_prefix) { "" } let(:create_table_queries) { <= 1970' do let(:value){ '2000' } it { is_expected.to eq('2000-01-01') } end context 'with year(4) < 1970' do let(:value){ '1969' } it { is_expected.to eq('1969-01-01') } end context 'with year(2) >= 70' do let(:value){ '07' } it { is_expected.to eq('2007-01-01') } end context 'with year(2) < 70' do let(:value){ '69' } it { is_expected.to eq('2069-01-01') } end context 'with value 259392-00-00' do let(:value) { '259392-00-00' } it { is_expected.to eq('259392-01-01') } end context 'with value 259392-00-04' do let(:value) { '259392-00-04' } it { is_expected.to eq('259392-01-04') } end context 'with value 0000-01-04' do let(:value) { '0000-01-04' } it { is_expected.to eq('0001-01-04') } end context 'with value 259392-40-04' do let(:value) { '259392-40-04' } it { expect{subject}.to raise_error(ArgumentError) } end end context 'with date values' do shared_examples "returning the input value as is" do it { is_expected.to eq(value) } end context 'with valid date' do let(:value){ '1920-01-01' } it_behaves_like "returning the input value as is" end context 'with zero date' do let(:value){ '0000-00-00' } it { is_expected.to eq('0001-01-01') } end end context 'with nil' do it { is_expected.to eq(nil) } end end shared_examples "expecting no underscore in front of numbers" do # Redshift accepts a table/column name starting with numbers (e.g. 20grams) or even a number-only name (e.g. 12345) context "with a key including numbers" do let(:key) { "year2000" } let(:expected_value) { key } it { is_expected.to eq expected_value } end context "with a key only including numbers" do let(:key) { "2000" } let(:expected_value) { key } it { is_expected.to eq expected_value } end context "with a key starting with numbers" do let(:key) { "2000stars" } let(:expected_value) { key } it { is_expected.to eq expected_value } end end describe ".convert_to_valid_name" do subject { subject_object.convert_to_valid_name(key) } it_behaves_like "expecting no underscore in front of numbers" context "with a key that has spaces" do let(:key) { "space test" } let(:expected_value) { key } it { is_expected.to eq expected_value } end context "with a key that has non-ASCII chars" do let(:key) { "行列123" } let(:expected_value) { "__123" } it "Redshift does not support non-ASCII table/column name. Those characters will be replaced with '_'" do is_expected.to eq expected_value end end context "with a key that has special chars" do let(:key) { %q| !"#$%&'()*+,-/:;<=>?@[\\]^_{\|}~`| } let(:expected_value) { %q| !_#$%&'()*+,-/:;<=>?@[\\]^_{\|}~`| } it "Redshift supports all these special characters but double quote (\") which is replaced with underscore (_)" do is_expected.to eq expected_value end end context "with a key that has a period in it" do let(:key) { %q|my.table| } let(:expected_value) { key } it "Redshift supports period (.) in a table/column name" do is_expected.to eq expected_value end end end describe ".convert_to_valid_column_name" do subject { subject_object.convert_to_valid_name(key) } it_behaves_like "expecting no underscore in front of numbers" end describe ".convert_to_valid_table_name" do subject { subject_object.convert_to_valid_name(key) } it_behaves_like "expecting no underscore in front of numbers" end describe ".fq_table_name" do subject { subject_object.fq_table_name(table_name, schema_name) } context "with no schema name" do let(:schema_name) { nil } context "with a table name with no schema prefix" do let(:table_name) { "test_table" } it { is_expected.to eq "test_table" } end context "with a table name with a schema prefix" do let(:table_name) { "some_schema.test_table" } it { is_expected.to eq "test_table" } end context "with a mixed-case table name" do let(:table_name) { "Test_Table" } it { is_expected.to eq "test_table" } end end context "with a schema name" do let(:schema_name) { "test_schema" } context "with a table name with no schema prefix" do let(:table_name) { "test_table" } it { is_expected.to eq "test_schema.test_table" } end context "with a table name with a schema prefix" do let(:table_name) { "some_schema.test_table" } it { is_expected.to eq "test_schema.test_table" } end end context "with a mixed-case schema name" do let(:schema_name) { "Test_Schema" } context "with a table name with no schema prefix" do let(:table_name) { "test_table" } it { is_expected.to eq "test_schema.test_table" } end end end end end end