describe Timeliness::Definitions do context "add_formats" do before do @default_formats = definitions.time_formats.dup end it "should add format to format array" do definitions.add_formats(:time, "h o'clock") expect(definitions.time_formats).to include("h o'clock") end it "should parse new format after its added" do should_not_parse("12 o'clock", :time) definitions.add_formats(:time, "h o'clock") should_parse("12 o'clock", :time) end it "should raise error if format exists" do expect { definitions.add_formats(:time, "hh:nn:ss") }.to raise_error(Timeliness::Definitions::DuplicateFormat) end context "with :before option" do it "should add new format with higher precedence" do definitions.add_formats(:time, "ss:hh:nn", before: 'hh:nn:ss') time_array = parser._parse('59:23:58', :time) expect(time_array).to eq [nil,nil,nil,23,58,59,nil,nil] end it "should raise error if :before format does not exist" do expect { definitions.add_formats(:time, "ss:hh:nn", before: 'nn:hh:ss') }.to raise_error(Timeliness::Definitions::FormatNotFound) end end after do definitions.time_formats = @default_formats definitions.compile_formats end end context "remove_formats" do before do @default_formats = definitions.time_formats.dup end it "should remove a single format from the formats array for type" do definitions.remove_formats(:time, 'h.nn_ampm') expect(definitions.time_formats).not_to include('h.nn_ampm') end it "should remove multiple formats from formats array for type" do definitions.remove_formats(:time, 'h:nn', 'h.nn_ampm') expect(definitions.time_formats).not_to include('h:nn') expect(definitions.time_formats).not_to include('h.nn_ampm') end it "should prevent parsing of removed format" do should_parse('2.12am', :time) definitions.remove_formats(:time, 'h.nn_ampm') should_not_parse('2.12am', :time) end it "should raise error if format does not exist" do expect { definitions.remove_formats(:time, "ss:hh:nn") }.to raise_error(Timeliness::Definitions::FormatNotFound) end after do definitions.time_formats = @default_formats definitions.compile_formats end end context "use_euro_formats" do it "should allow ambiguous date to be parsed as European format" do expect(parser._parse('01/02/2000', :date)).to eq [2000,1,2,nil,nil,nil,nil,nil] definitions.use_euro_formats expect(parser._parse('01/02/2000', :date)).to eq [2000,2,1,nil,nil,nil,nil,nil] end it "should not parse formats on switch to euro after initial compile" do definitions.compile_formats expect(Timeliness::FormatSet).not_to receive(:compile) definitions.use_euro_formats end end context "use_us_formats" do before do definitions.use_euro_formats end it "should allow ambiguous date to be parsed as European format" do expect(parser._parse('01/02/2000', :date)).to eq [2000,2,1,nil,nil,nil,nil,nil] definitions.use_us_formats expect(parser._parse('01/02/2000', :date)).to eq [2000,1,2,nil,nil,nil,nil,nil] end it "should not parse formats on switch to euro after initial compile" do definitions.compile_formats expect(Timeliness::FormatSet).not_to receive(:compile) definitions.use_us_formats end end context "thread safe ambiguous date format switching" do let(:ambiguous_date) { "01/02/2000" } around do |example| Timeliness::Definitions.compile_formats example.call Timeliness::Definitions.compile_formats end it "should allow independent control in current thread" do threads = { euro: Thread.new { Timeliness.use_euro_formats; sleep(0.005); Timeliness.parse(ambiguous_date) }, us: Thread.new { sleep(0.001); Timeliness.use_us_formats; Timeliness.parse(ambiguous_date) } } threads.values.each { |t| t.join } expect(threads[:euro].value).to eql(Time.new(2000,2,1)) expect(threads[:us].value).to eql(Time.new(2000,1,2)) end it 'should use default format in new threads' do Timeliness.configuration.ambiguous_date_format = :euro thread = Thread.new { sleep(0.001); Timeliness.parse(ambiguous_date) } thread.join expect(thread.value).to eql(Time.new(2000,2,1)) end end end