From 3702aae17decd1a08213b8a0b8be2da841c9c33a Mon Sep 17 00:00:00 2001 From: John Mettraux Date: Mon, 5 Dec 2022 11:35:10 +0900 Subject: [PATCH] Bring in Fugit.parse_cronish and .do_parse_cronish gh-70 --- CHANGELOG.md | 2 ++ README.md | 17 ++++++++++++++ lib/fugit/parse.rb | 13 +++++++++++ spec/parse_spec.rb | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d5e981..207af05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ## fugit 1.8.0 not yet released +* Introduce Fugit.parse_cronish and .do_parse_cronish, gh-70 + ## fugit 1.7.2 released 2022-11-03 diff --git a/README.md b/README.md index d8c39e5..86fde65 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,23 @@ Fugit.parse_nat('every day at noon').class # ==> ::Fugit::Cron As `Fugit.parse(s)` returns nil when it doesn't grok its input, and `Fugit.do_parse(s)` fails when it doesn't grok, each of the `parse_` methods has its partner `do_parse_` method. +## parse_cronish and do_parse_cronish + +Sometimes you know a cron expression or an "every" natural expression will come in and you want to discard the rest. + +``` +require 'fugit' + +Fugit.parse_cronish('0 0 1 jan *').class # ==> ::Fugit::Cron +Fugit.parse_cronish('every saturday at noon').class # ==> ::Fugit::Cron + +Fugit.parse_cronish('12y12M') # ==> nil +``` + +`.parse_cronish(s)` will return a `Fugit::Cron` instance or else nil. + +`.do_parse_cronish(s)` will return a `Fugit::Cron` instance or else fail with an `ArgumentError`. + ## `Fugit::Cron` A class `Fugit::Cron` to parse cron strings and then `#next_time` and `#previous_time` to compute the next or the previous occurrence respectively. diff --git a/lib/fugit/parse.rb b/lib/fugit/parse.rb index 8cb1d9f..2304bf8 100644 --- a/lib/fugit/parse.rb +++ b/lib/fugit/parse.rb @@ -33,6 +33,19 @@ def do_parse(s, opts={}) fail(ArgumentError.new("found no time information in #{s.inspect}")) end + def parse_cronish(s, opts={}) + + r = parse_cron(s) || parse_nat(s, opts) + + r.is_a?(::Fugit::Cron) ? r : nil + end + + def do_parse_cronish(s, opts={}) + + parse_cronish(s) || + fail(ArgumentError.new("not cron or 'natural' cron string: #{s.inspect}")) + end + def determine_type(s) case self.parse(s) diff --git a/spec/parse_spec.rb b/spec/parse_spec.rb index 2d0cc79..13e7fea 100644 --- a/spec/parse_spec.rb +++ b/spec/parse_spec.rb @@ -137,6 +137,62 @@ end end + CRONISHES = { + + '* * * * *' => '* * * * *', + 'every day' => '0 0 * * *', + + '2022-12-5 11:32' => ArgumentError, + 'nada' => ArgumentError, + '100 * * * *' => ArgumentError, + } + + describe '.parse_cronish' do + + CRONISHES.each do |k, v| + + if v.is_a?(String) + + it "parses #{k.inspect} to #{v.inspect}" do + + r = Fugit.parse_cronish(k) + + expect(r.class).to eq(Fugit::Cron) + expect(r.original).to eq(v) + end + else + + it "returns nil for #{k.inspect}" do + + expect(Fugit.parse_cronish(k)).to eq(nil) + end + end + end + end + + describe '.do_parse_cronish' do + + CRONISHES.each do |k, v| + + if v.is_a?(String) + + it "parses #{k.inspect} to #{v.inspect}" do + + r = Fugit.do_parse_cronish(k) + + expect(r.class).to eq(Fugit::Cron) + expect(r.original).to eq(v) + end + else + + it "fails on #{k.inspect}" do + + expect { Fugit.do_parse_cronish(k) }.to raise_error(v) + end + end + end + end + describe '.determine_type' do it 'returns nil if it cannot determine' do