describe Timeliness::Format do describe "#compile!" do it 'should compile valid string format' do expect { Timeliness::Format.new('yyyy-mm-dd hh:nn:ss.u zo').compile! }.to_not raise_error end it 'should return self' do format = Timeliness::Format.new('yyyy-mm-dd hh:nn:ss.u zo') expect(format.compile!).to eq format end it 'should raise compilation error for bad format' do expect { Timeliness::Format.new('|--[)').compile! }.to raise_error(Timeliness::Format::CompilationFailed) end it 'should raise compilation error if token with captured arg is present more than once' do expect { Timeliness::Format.new('dd-mm-yyyy-dd').compile! }.to raise_error(Timeliness::Format::CompilationFailed) end end describe "#process" do it "should define method which outputs date array with values in correct order" do expect(format_for('yyyy-mm-dd').process('2000', '1', '2')).to eq [2000,1,2,nil,nil,nil,nil,nil] end it "should define method which outputs date array from format with different order" do expect(format_for('dd/mm/yyyy').process('2', '1', '2000')).to eq [2000,1,2,nil,nil,nil,nil,nil] end it "should define method which outputs date array with zeros when month and day are '0'" do expect(format_for('m/d/yy').process('0', '0', '0000')).to eq [0,0,0,nil,nil,nil,nil,nil] end it "should define method which outputs date array with zeros when month and day are '00'" do expect(format_for('m/d/yy').process('00', '00', '0000')).to eq [0,0,0,nil,nil,nil,nil,nil] end it "should define method which outputs time array" do expect(format_for('hh:nn:ss').process('01', '02', '03')).to eq [nil,nil,nil,1,2,3,nil,nil] end it "should define method which outputs time array with meridian 'pm' adjusted hour" do expect(format_for('hh:nn:ss ampm').process('01', '02', '03', 'pm')).to eq [nil,nil,nil,13,2,3,nil,nil] end it "should define method which outputs time array with meridian 'am' unadjusted hour" do expect(format_for('hh:nn:ss ampm').process('01', '02', '03', 'am')).to eq [nil,nil,nil,1,2,3,nil,nil] end it "should define method which outputs time array with microseconds" do expect(format_for('hh:nn:ss.u').process('01', '02', '03', '99')).to eq [nil,nil,nil,1,2,3,990000,nil] end it "should define method which outputs datetime array with zone offset" do expect(format_for('yyyy-mm-dd hh:nn:ss.u zo').process('2001', '02', '03', '04', '05', '06', '99', '+10:00')).to eq [2001,2,3,4,5,6,990000,36000] end it "should define method which outputs datetime array with zone offset" do expect(format_for('yyyy-mm-dd hh:nn:ss.u zo').process('2001', '02', '03', '04', '05', '06', '99', '+10:00')).to eq [2001,2,3,4,5,6,990000,36000] end it "should define method which outputs datetime array with timezone string" do expect(format_for('yyyy-mm-dd hh:nn:ss.u tz').process('2001', '02', '03', '04', '05', '06', '99', 'EST')).to eq [2001,2,3,4,5,6,990000,'EST'] end it "should define method which outputs datetime array with 0 offset for zulu time ('Z')" do expect(format_for('yyyy-mm-dd hh:nn:ss.uzt').process('2001', '02', '03', '04', '05', '06', '99', 'Z')).to eq [2001,2,3,4,5,6,990000,0] end context "with long month" do let(:format) { format_for('dd mmm yyyy') } context "with I18n loaded" do before(:all) do I18n.locale = :es I18n.backend.store_translations :es, date: { month_names: %w{ ~ Enero Febrero Marzo } } I18n.backend.store_translations :es, date: { abbr_month_names: %w{ ~ Ene Feb Mar } } end it 'should parse abbreviated month for current locale to correct value' do expect(format.process('2', 'Ene', '2000')).to eq [2000,1,2,nil,nil,nil,nil,nil] end it 'should parse full month for current locale to correct value' do expect(format.process('2', 'Enero', '2000')).to eq [2000,1,2,nil,nil,nil,nil,nil] end context "with upper case month abbreviations" do before(:all) do I18n.backend.store_translations :es, date: { abbr_month_names: %w{ ~ ENE FEB MAR } } end it 'should parse abbreviated month for current locale case insensitively' do expect(format_for('d-mmm-yyyy').process('01', 'mar', '2023')).to eq [2023,3,1,nil,nil,nil,nil,nil] end end context "with upper case month names" do before(:all) do I18n.backend.store_translations :es, date: { month_names: %w{ ~ ENERO FEBRERO MARZO } } end it 'should parse full month for current locale case insensitively' do expect(format_for('d-mmm-yyyy').process('01', 'mArZo', '2023')).to eq [2023,3,1,nil,nil,nil,nil,nil] end end after(:all) do I18n.locale = :en end end context "without I18n loaded" do before do allow(format).to receive(:i18n_loaded?).and_return(false) expect(I18n).not_to receive(:t) end it 'should parse abbreviated month to correct value' do expect(format.process('2', 'Jan', '2000')).to eq [2000,1,2,nil,nil,nil,nil,nil] end it 'should parse full month to correct value' do expect(format.process('2', 'January', '2000')).to eq [2000,1,2,nil,nil,nil,nil,nil] end end end end def format_for(format) Timeliness::Format.new(format).compile! end end