Commit efb1ff6a7e6b04351a870e98b7577675b157972b

Authored by 李虹霖
0 parents
Exists in master and in 1 other branch main

first commit

.github/workflows/test.yml 0 → 100644
  1 +++ a/.github/workflows/test.yml
... ... @@ -0,0 +1,20 @@
  1 +---
  2 +name: Test
  3 +
  4 +on: [push, pull_request]
  5 +
  6 +jobs:
  7 + build:
  8 + runs-on: ubuntu-latest
  9 + strategy:
  10 + matrix:
  11 + ruby-version: [2.5, 2.6, 2.7, '3.0', 3.1, 3.2]
  12 + name: Ruby ${{ matrix.ruby-version }}
  13 + steps:
  14 + - uses: actions/checkout@v3
  15 + - name: Setup Ruby
  16 + uses: ruby/setup-ruby@v1
  17 + with:
  18 + ruby-version: ${{ matrix.ruby-version }}
  19 + - run: bundle install
  20 + - run: bundle exec rake
... ...
.gitignore 0 → 100644
  1 +++ a/.gitignore
... ... @@ -0,0 +1,20 @@
  1 +*.gem
  2 +*.log
  3 +*.rbc
  4 +.bundle
  5 +.config
  6 +.rvmrc
  7 +.yardoc
  8 +Gemfile.lock
  9 +_yardoc
  10 +coverage
  11 +doc/
  12 +lib/bundler/man
  13 +pkg
  14 +rdoc
  15 +spec/reports
  16 +test/tmp
  17 +test/version_tmp
  18 +temp
  19 +tmp
  20 +vendor
... ...
.rspec 0 → 100644
  1 +++ a/.rspec
... ... @@ -0,0 +1 @@
  1 +--require spec_helper
0 2 \ No newline at end of file
... ...
.rubocop.yml 0 → 100644
  1 +++ a/.rubocop.yml
... ... @@ -0,0 +1,56 @@
  1 +Style/Encoding:
  2 + Enabled: false
  3 +
  4 +Lint/AmbiguousOperator:
  5 + Enabled: false
  6 +
  7 +Layout/CaseIndentation:
  8 + Enabled: false
  9 +
  10 +Metrics/CyclomaticComplexity:
  11 + Enabled: false
  12 + Max: 10
  13 +
  14 +Metrics/PerceivedComplexity:
  15 + Enabled: false
  16 + Max: 10
  17 +
  18 +Style/Documentation:
  19 + Enabled: false
  20 +
  21 +Layout/EmptyLinesAroundBlockBody:
  22 + Enabled: false
  23 +
  24 +Layout/EmptyLinesAroundClassBody:
  25 + Enabled: false
  26 +
  27 +Layout/EmptyLinesAroundModuleBody:
  28 + Enabled: false
  29 +
  30 +Metrics/ClassLength:
  31 + Enabled: false
  32 +
  33 +Style/FrozenStringLiteralComment:
  34 + Enabled: false
  35 +
  36 +Layout/LineLength:
  37 + Enabled: true
  38 + Max: 160
  39 +
  40 +Metrics/MethodLength:
  41 + Enabled: false
  42 +
  43 +Style/ModuleFunction:
  44 + Enabled: false
  45 +
  46 +Style/NestedTernaryOperator:
  47 + Enabled: false
  48 +
  49 +Style/RaiseArgs:
  50 + Enabled: false
  51 +
  52 +Style/RescueModifier:
  53 + Enabled: false
  54 +
  55 +Lint/UnusedMethodArgument:
  56 + Enabled: false
... ...
.travis.yml 0 → 100644
  1 +++ a/.travis.yml
... ... @@ -0,0 +1,8 @@
  1 +language: ruby
  2 +
  3 +cache: bundler
  4 +
  5 +rvm:
  6 + - 2.5
  7 + - 2.6
  8 + - 2.7
... ...
CHANGELOG.md 0 → 100644
  1 +++ a/CHANGELOG.md
... ... @@ -0,0 +1,48 @@
  1 +### [0.13.0] - 2023-11-04
  2 +* Fix zero hour
  3 +
  4 +### [0.12.0] - 2023-04-16
  5 +* Add "strict_quartz" option for Java Quartz implementation (quartz-scheduler)
  6 +
  7 +### [0.11.1] - 2020-10-21
  8 +* Fix two consecutive commas in interval expressions
  9 +
  10 +### [0.11.0] - 2020-10-05
  11 +* Fix handling L in day of month expressions
  12 +
  13 +### [0.10.0] - 2020-05-26
  14 +* Move locale and timezone arguments to options
  15 +
  16 +### [0.9.2] - 2020-04-24
  17 +* Add italian locale
  18 +
  19 +### [0.9.1] - 2019-11-26
  20 +* Update tzinfo dependency
  21 +
  22 +### [0.9.0] - 2019-04-21
  23 +* Add german locale
  24 +
  25 +### [0.8.0] - 2019-04-18
  26 +* Add support for timezones
  27 +
  28 +### [0.7.0] - 2018-11-22
  29 +* Include day of week when day of month is specified
  30 +
  31 +### [0.6.1] - 2017-11-17
  32 +* Fix 4th day spelling
  33 +
  34 +### [0.6.0] - 2017-02-17
  35 +* Add romanian and russian locales
  36 +* Minor fixes to the french locale
  37 +
  38 +### [0.5.0] - 2017-02-15
  39 +* Add french locale
  40 +
  41 +### [0.4.0] - 2016-11-28
  42 +* Fix handling leading zeros in numbers
  43 +
  44 +### [0.3.0] - 2016-03-02
  45 +* Add pt_BR locale
  46 +
  47 +### [0.2.0] - 2015-10-25
  48 +* Initial public version
... ...
Gemfile 0 → 100644
  1 +++ a/Gemfile
... ... @@ -0,0 +1,2 @@
  1 +source 'https://rubygems.org'
  2 +gemspec
... ...
LICENSE.md 0 → 100644
  1 +++ a/LICENSE.md
... ... @@ -0,0 +1,13 @@
  1 +Copyright 2015, Opower
  2 +
  3 +Licensed under the Apache License, Version 2.0 (the "License");
  4 +you may not use this file except in compliance with the License.
  5 +You may obtain a copy of the License at
  6 +
  7 + http://www.apache.org/licenses/LICENSE-2.0
  8 +
  9 +Unless required by applicable law or agreed to in writing, software
  10 +distributed under the License is distributed on an "AS IS" BASIS,
  11 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 +See the License for the specific language governing permissions and
  13 +limitations under the License.
... ...
README.md 0 → 100644
  1 +++ a/README.md
... ... @@ -0,0 +1,86 @@
  1 +# Cronex
  2 +
  3 +[![Gem Version](https://badge.fury.io/rb/cronex.svg)](https://badge.fury.io/rb/cronex)
  4 +[![Build Status](https://github.com/alpinweis/cronex/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/alpinweis/cronex/actions/workflows/test.yml?query=branch%3Amaster)
  5 +
  6 +A Ruby library that converts cron expressions into human readable strings.
  7 +Translated to Ruby from [cron-expression-descriptor](https://github.com/bradyholt/cron-expression-descriptor) (C#) via
  8 +[cron-parser](https://github.com/RedHogs/cron-parser) (Java).
  9 +
  10 +Original Author & Credit: Brady Holt (http://www.geekytidbits.com).
  11 +
  12 +## Features
  13 +
  14 + * Supports all cron expression special characters including: `*` `/` `,` `-` `?` `L` `W` `#`
  15 + * Supports 5, 6 (w/ seconds or year), or 7 (w/ seconds and year) part cron expressions
  16 + * Provides casing options (sentence, title, lower)
  17 + * Support for non-standard non-zero-based week day numbers
  18 + * Supports printing to locale specific human readable format
  19 + * Supports displaying times in specific timezones
  20 +
  21 +For a quick intro to cron see Quartz [Cron Tutorial](http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html).
  22 +
  23 +## Available Locales
  24 +
  25 +* English
  26 +* Brazilian
  27 +* French
  28 +* German
  29 +* Italian
  30 +* Romanian
  31 +* Russian
  32 +
  33 +## Installation
  34 +
  35 +Add this line to your application's Gemfile:
  36 +
  37 + gem 'cronex'
  38 +
  39 +And then execute:
  40 +
  41 + $ bundle install
  42 +
  43 +Or install it yourself as:
  44 +
  45 + $ gem install cronex
  46 +
  47 +## Usage
  48 +
  49 +#### Zero based day of week
  50 +
  51 + Cronex::ExpressionDescriptor.new('*/5 15 * * 1-5').description
  52 + => Every 5 minutes, at 3:00 PM, Monday through Friday
  53 +
  54 + Cronex::ExpressionDescriptor.new('0 0/30 8-9 5,20 * ?').description
  55 + => Every 30 minutes, between 8:00 AM and 9:59 AM, on day 5 and 20 of the month
  56 +
  57 +#### Non-zero based day of week
  58 +
  59 + Cronex::ExpressionDescriptor.new('*/5 15 * * 1-5', zero_based_dow: false).description
  60 + => Every 5 minutes, at 3:00 PM, Sunday through Thursday
  61 +
  62 +#### Localization
  63 +
  64 + Cronex::ExpressionDescriptor.new('30 2 * 2 1-5', locale: 'fr').description
  65 + => À 2:30 AM, lundi à vendredi, seulement en février
  66 +
  67 +#### Timezones
  68 +
  69 + Cronex::ExpressionDescriptor.new('0-10 11 * * *', timezone: 'America/Los_Angeles').description
  70 + => Every minute between 4:00 AM and 4:10 AM # PDT or
  71 + => Every minute between 3:00 AM and 3:10 AM # PST
  72 +
  73 +### Strict quartz-scheduler implementation support
  74 +
  75 + Cronex::ExpressionDescriptor.new('* * * * *', strict_quartz: true).description
  76 + => Cronex::ExpressionError (Error: Expression only has 5 parts. For 'strict_quartz' option, at least 6 parts are required)
  77 +
  78 +See spec tests for more examples.
  79 +
  80 +### Contributing
  81 +
  82 +1. Fork it
  83 +2. Create your feature branch (`git checkout -b my-new-feature`)
  84 +3. Commit your changes (`git commit -am 'Add some feature'`)
  85 +4. Push to the branch (`git push origin my-new-feature`)
  86 +5. Create new Pull Request
... ...
Rakefile 0 → 100644
  1 +++ a/Rakefile
... ... @@ -0,0 +1,8 @@
  1 +require 'bundler/gem_tasks'
  2 +require 'rspec/core/rake_task'
  3 +
  4 +RSpec::Core::RakeTask.new do |t|
  5 + t.pattern = 'spec/*_spec.rb'
  6 +end
  7 +
  8 +task :default => :spec
... ...
cronex.gemspec 0 → 100644
  1 +++ a/cronex.gemspec
... ... @@ -0,0 +1,28 @@
  1 +# -*- encoding: utf-8 -*-
  2 +require File.expand_path('../lib/cronex/version', __FILE__)
  3 +
  4 +Gem::Specification.new do |spec|
  5 + spec.name = 'cronex'
  6 + spec.version = Cronex::VERSION
  7 + spec.summary = 'Ruby library that converts cron expressions into human readable strings'
  8 + spec.description = spec.summary
  9 + spec.homepage = 'https://github.com/alpinweis/cronex'
  10 +
  11 + spec.authors = ['Adrian Kazaku']
  12 + spec.email = ['alpinweis@gmail.com']
  13 +
  14 + spec.required_ruby_version = '>= 1.9.3'
  15 +
  16 + spec.license = 'Apache-2.0'
  17 +
  18 + spec.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
  19 + spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
  20 + spec.test_files = spec.files.grep(/^(test|spec|features)\//)
  21 + spec.require_paths = ['lib']
  22 +
  23 + spec.add_runtime_dependency 'tzinfo'
  24 + spec.add_runtime_dependency 'unicode'
  25 + spec.add_development_dependency 'pry', '~> 0.10'
  26 + spec.add_development_dependency 'rake', '>= 12.3.3'
  27 + spec.add_development_dependency 'rspec', '~> 3.1'
  28 +end
... ...
lib/cronex.rb 0 → 100644
  1 +++ a/lib/cronex.rb
... ... @@ -0,0 +1,10 @@
  1 +require 'date'
  2 +require 'time'
  3 +require 'yaml'
  4 +require_relative 'cronex/version'
  5 +require_relative 'cronex/errors'
  6 +require_relative 'cronex/resource'
  7 +require_relative 'cronex/utils'
  8 +require_relative 'cronex/parser'
  9 +require_relative 'cronex/exp_descriptor'
  10 +require_relative 'cronex/description'
... ...
lib/cronex/description.rb 0 → 100644
  1 +++ a/lib/cronex/description.rb
... ... @@ -0,0 +1,8 @@
  1 +require_relative 'description/base'
  2 +require_relative 'description/seconds'
  3 +require_relative 'description/minutes'
  4 +require_relative 'description/hours'
  5 +require_relative 'description/day_of_week'
  6 +require_relative 'description/day_of_month'
  7 +require_relative 'description/month'
  8 +require_relative 'description/year'
... ...
lib/cronex/description/base.rb 0 → 100644
  1 +++ a/lib/cronex/description/base.rb
... ... @@ -0,0 +1,61 @@
  1 +module Cronex
  2 + class Description
  3 +
  4 + attr_accessor :resources, :options
  5 +
  6 + def initialize(resources, options = {})
  7 + @resources = resources
  8 + @options = options || {}
  9 + end
  10 +
  11 + def special_chars
  12 + ['/', '-', ',']
  13 + end
  14 +
  15 + def segment_description(expression, all_values_description)
  16 + if expression.empty? || (expression == '0' && self.class != Cronex::HoursDescription)
  17 + desc = ''
  18 + elsif expression == '*'
  19 + desc = all_values_description
  20 + elsif !Cronex::Utils.include_any?(expression, special_chars)
  21 + desc = format(description_format(expression), single_item_description(expression))
  22 + elsif expression.include?('/')
  23 + segments = expression.split('/')
  24 + desc = format(interval_description_format(segments[1]), single_item_description(segments[1]))
  25 + # interval contains 'between' piece (e.g. 2-59/3)
  26 + if segments[0].include?('-')
  27 + between_segment_of_interval = segments[0]
  28 + between_segments = between_segment_of_interval.split('-')
  29 + between = format(
  30 + between_description_format(between_segment_of_interval),
  31 + single_item_description(between_segments[0]),
  32 + single_item_description(between_segments[1]).gsub(':00', ':59'))
  33 + desc += ', ' if !between.start_with?(', ')
  34 + desc += between
  35 + elsif !Cronex::Utils.include_any?(segments[0], special_chars + ['*'])
  36 + desc += ', ' + format(starting_description_format(segments[0]), single_item_description(segments[0]))
  37 + end
  38 + elsif expression.include?('-')
  39 + segments = expression.split('-')
  40 + desc = format(
  41 + between_description_format(expression),
  42 + single_item_description(segments[0]),
  43 + single_item_description(segments[1]).gsub(':00', ':59'))
  44 + elsif expression.include?(',')
  45 + segments = expression.split(',')
  46 + segments = segments.map { |s| single_item_description(s) }
  47 + desc_content = segments[0...-1].join(', ') + ' ' + resources.get('and') + ' ' + segments.last
  48 + desc = format(description_format(expression), desc_content)
  49 + end
  50 +
  51 + desc
  52 + end
  53 +
  54 + def plural(expression, singular, plural)
  55 + number = Cronex::Utils.number?(expression)
  56 + return plural if number && number > 1
  57 + return plural if expression.include?(',')
  58 + singular
  59 + end
  60 + end
  61 +end
... ...
lib/cronex/description/day_of_month.rb 0 → 100644
  1 +++ a/lib/cronex/description/day_of_month.rb
... ... @@ -0,0 +1,23 @@
  1 +module Cronex
  2 + class DayOfMonthDescription < Description
  3 + def single_item_description(expression)
  4 + expression == 'L' ? resources.get('last_day') : expression
  5 + end
  6 +
  7 + def interval_description_format(expression)
  8 + ', ' + resources.get('every_x') + ' ' + plural(expression, resources.get('day'), resources.get('days'))
  9 + end
  10 +
  11 + def between_description_format(expression)
  12 + ', ' + resources.get('between_days_of_the_month')
  13 + end
  14 +
  15 + def description_format(expression)
  16 + ', ' + resources.get('on_day_of_the_month')
  17 + end
  18 +
  19 + def starting_description_format(expression)
  20 + resources.get('starting') + ' ' + resources.get('on_day_of_the_month')
  21 + end
  22 + end
  23 +end
... ...
lib/cronex/description/day_of_week.rb 0 → 100644
  1 +++ a/lib/cronex/description/day_of_week.rb
... ... @@ -0,0 +1,52 @@
  1 +module Cronex
  2 + class DayOfWeekDescription < Description
  3 + def single_item_description(expression)
  4 + exp = expression
  5 + if expression.include?('#')
  6 + exp = expression.partition('#').first
  7 + elsif expression.include?('L')
  8 + exp = exp.gsub('L', '')
  9 + end
  10 +
  11 + if Cronex::Utils.number?(exp)
  12 + dow_num = Cronex::Utils.integer(exp)
  13 + zero_based_dow = options[:zero_based_dow]
  14 + invalid_dow = !zero_based_dow && dow_num <= 1
  15 + if invalid_dow || (zero_based_dow && dow_num == 0)
  16 + return resources.get(Cronex::Utils.day_of_week_name(0).downcase) # or 7 as in java DateTime().withDayOfWeek(7) for Sunday
  17 + elsif !zero_based_dow
  18 + dow_num -= 1
  19 + end
  20 + return resources.get(Cronex::Utils.day_of_week_name(dow_num).downcase)
  21 + else
  22 + return Date.parse(exp.capitalize).strftime('%A')
  23 + end
  24 + end
  25 +
  26 + def interval_description_format(expression)
  27 + format(', ' + resources.get('interval_description_format'), expression)
  28 + end
  29 +
  30 + def between_description_format(expression)
  31 + ', ' + resources.get('between_weekday_description_format')
  32 + end
  33 +
  34 + def description_format(expression)
  35 + if expression.include?('#')
  36 + dow_num = expression.split('#').last
  37 + days = Hash[%w(1 2 3 4 5).zip(%w(first second third fourth fifth))]
  38 + dow_desc = days[dow_num]
  39 + dow_desc = dow_desc ? resources.get(dow_desc) : ''
  40 + ', ' + resources.get('on_the_day_of_the_month').gsub(/{{.*}}/, dow_desc)
  41 + elsif expression.include?('L')
  42 + ', ' + resources.get('on_the_last_of_the_month')
  43 + else
  44 + ', ' + resources.get('only_on')
  45 + end
  46 + end
  47 +
  48 + def starting_description_format(expression)
  49 + resources.get('starting') + ' ' + resources.get('on_x')
  50 + end
  51 + end
  52 +end
... ...
lib/cronex/description/hours.rb 0 → 100644
  1 +++ a/lib/cronex/description/hours.rb
... ... @@ -0,0 +1,23 @@
  1 +module Cronex
  2 + class HoursDescription < Description
  3 + def single_item_description(expression, timezone = 'UTC')
  4 + Cronex::Utils.format_time(expression, '0', '', timezone)
  5 + end
  6 +
  7 + def interval_description_format(expression)
  8 + format(resources.get('every_x') + ' ' + plural(expression, resources.get('hour'), resources.get('hours')), expression)
  9 + end
  10 +
  11 + def between_description_format(expression)
  12 + resources.get('between_x_and_y')
  13 + end
  14 +
  15 + def description_format(expression)
  16 + resources.get('at_x')
  17 + end
  18 +
  19 + def starting_description_format(expression)
  20 + resources.get('starting') + ' ' + description_format(expression)
  21 + end
  22 + end
  23 +end
... ...
lib/cronex/description/minutes.rb 0 → 100644
  1 +++ a/lib/cronex/description/minutes.rb
... ... @@ -0,0 +1,27 @@
  1 +module Cronex
  2 + class MinutesDescription < Description
  3 + def single_item_description(expression)
  4 + Cronex::Utils.format_minutes(expression)
  5 + end
  6 +
  7 + def interval_description_format(expression)
  8 + format(resources.get('every_x') + ' ' + min_plural(expression), expression)
  9 + end
  10 +
  11 + def between_description_format(expression)
  12 + resources.get('minutes_through_past_the_hour')
  13 + end
  14 +
  15 + def description_format(expression)
  16 + expression == '0' ? '' : [resources.get('at_x'), min_plural(expression), resources.get('past_the_hour')].join(' ')
  17 + end
  18 +
  19 + def starting_description_format(expression)
  20 + resources.get('starting') + ' ' + description_format(expression)
  21 + end
  22 +
  23 + def min_plural(expression)
  24 + plural(expression, resources.get('minute'), resources.get('minutes'))
  25 + end
  26 + end
  27 +end
... ...
lib/cronex/description/month.rb 0 → 100644
  1 +++ a/lib/cronex/description/month.rb
... ... @@ -0,0 +1,23 @@
  1 +module Cronex
  2 + class MonthDescription < Description
  3 + def single_item_description(expression)
  4 + resources.get(DateTime.new(Time.now.year, Cronex::Utils.integer(expression), 1).strftime('%B').downcase)
  5 + end
  6 +
  7 + def interval_description_format(expression)
  8 + format(', ' + resources.get('every_x') + ' ' + plural(expression, resources.get('month'), resources.get('months')), expression)
  9 + end
  10 +
  11 + def between_description_format(expression)
  12 + ', ' + resources.get('between_description_format')
  13 + end
  14 +
  15 + def description_format(expression)
  16 + ', ' + resources.get('only_in')
  17 + end
  18 +
  19 + def starting_description_format(expression)
  20 + resources.get('starting') + ' ' + resources.get('in_x')
  21 + end
  22 + end
  23 +end
... ...
lib/cronex/description/seconds.rb 0 → 100644
  1 +++ a/lib/cronex/description/seconds.rb
... ... @@ -0,0 +1,23 @@
  1 +module Cronex
  2 + class SecondsDescription < Description
  3 + def single_item_description(expression)
  4 + expression
  5 + end
  6 +
  7 + def interval_description_format(expression)
  8 + format(resources.get('every_x_seconds'), expression)
  9 + end
  10 +
  11 + def between_description_format(expression)
  12 + resources.get('seconds_through_past_the_minute')
  13 + end
  14 +
  15 + def description_format(expression)
  16 + resources.get('at_x_seconds_past_the_minute')
  17 + end
  18 +
  19 + def starting_description_format(expression)
  20 + resources.get('starting') + ' ' + description_format(expression)
  21 + end
  22 + end
  23 +end
... ...
lib/cronex/description/year.rb 0 → 100644
  1 +++ a/lib/cronex/description/year.rb
... ... @@ -0,0 +1,23 @@
  1 +module Cronex
  2 + class YearDescription < Description
  3 + def single_item_description(expression)
  4 + DateTime.new(Cronex::Utils.integer(expression)).strftime('%Y')
  5 + end
  6 +
  7 + def interval_description_format(expression)
  8 + format(', ' + resources.get('every_x') + ' ' + plural(expression, resources.get('year'), resources.get('years')), expression)
  9 + end
  10 +
  11 + def between_description_format(expression)
  12 + ', ' + resources.get('between_description_format')
  13 + end
  14 +
  15 + def description_format(expression)
  16 + ', ' + resources.get('only_in')
  17 + end
  18 +
  19 + def starting_description_format(expression)
  20 + resources.get('starting') + ' ' + resources.get('in_x')
  21 + end
  22 + end
  23 +end
... ...
lib/cronex/errors.rb 0 → 100644
  1 +++ a/lib/cronex/errors.rb
... ... @@ -0,0 +1,4 @@
  1 +module Cronex
  2 + ExpressionError = Class.new(StandardError)
  3 + ResourceError = Class.new(StandardError)
  4 +end
... ...
lib/cronex/exp_descriptor.rb 0 → 100644
  1 +++ a/lib/cronex/exp_descriptor.rb
... ... @@ -0,0 +1,194 @@
  1 +require 'unicode'
  2 +
  3 +module Cronex
  4 +
  5 + CASINGS = [:title, :sentence, :lower]
  6 + SEGMENTS = [:seconds, :minutes, :hours, :dayofmonth, :month, :dayofweek, :year, :timeofday, :full]
  7 +
  8 + SPECIAL_CHARS = ['/', '-', ',', '*']
  9 +
  10 + CRONEX_OPTS = {
  11 + casing: :sentence,
  12 + verbose: false,
  13 + zero_based_dow: true,
  14 + use_24_hour_time_format: false,
  15 + throw_exception_on_parse_error: true,
  16 + strict_quartz: false,
  17 + locale: nil,
  18 + timezone: nil
  19 + }
  20 +
  21 + class ExpressionDescriptor
  22 + attr_accessor :expression, :expression_parts, :options, :parsed, :resources, :timezone
  23 +
  24 + def initialize(expression, options = {})
  25 + @expression = expression
  26 + @options = CRONEX_OPTS.merge(options)
  27 + @expression_parts = []
  28 + @parsed = false
  29 + @resources = Cronex::Resource.new(@options[:locale])
  30 + @timezone = @options[:timezone] || 'UTC'
  31 + end
  32 +
  33 + def to_hash
  34 + Hash[SEGMENTS.take(7).zip(expression_parts)]
  35 + end
  36 +
  37 + def description(type = :full)
  38 + desc = ''
  39 +
  40 + begin
  41 + unless parsed
  42 + parser = Parser.new(expression, options)
  43 + @expression_parts = parser.parse
  44 + @parsed = true
  45 + end
  46 +
  47 + desc = case type
  48 + when :full
  49 + full_description(expression_parts)
  50 + when :timeofday
  51 + time_of_day_description(expression_parts)
  52 + when :hours
  53 + hours_description(expression_parts)
  54 + when :minutes
  55 + minutes_description(expression_parts)
  56 + when :seconds
  57 + seconds_description(expression_parts)
  58 + when :dayofmonth
  59 + day_of_month_description(expression_parts)
  60 + when :month
  61 + month_description(expression_parts)
  62 + when :dayofweek
  63 + day_of_week_description(expression_parts)
  64 + when :year
  65 + year_description(expression_parts)
  66 + else
  67 + seconds_description(expression_parts)
  68 + end
  69 + rescue StandardError => e
  70 + if options[:throw_exception_on_parse_error]
  71 + raise e
  72 + else
  73 + desc = e.message
  74 + puts "Exception parsing expression: #{e}"
  75 + end
  76 + end
  77 +
  78 + desc
  79 + end
  80 +
  81 + def seconds_description(expression_parts)
  82 + desc = SecondsDescription.new(resources)
  83 + desc.segment_description(expression_parts[0], resources.get('every_second'))
  84 + end
  85 +
  86 + def minutes_description(expression_parts)
  87 + desc = MinutesDescription.new(resources)
  88 + desc.segment_description(expression_parts[1], resources.get('every_minute'))
  89 + end
  90 +
  91 + def hours_description(expression_parts)
  92 + desc = HoursDescription.new(resources)
  93 + desc.segment_description(expression_parts[2], resources.get('every_hour'))
  94 + end
  95 +
  96 + def year_description(expression_parts)
  97 + desc = YearDescription.new(resources, options)
  98 + desc.segment_description(expression_parts[6], ', ' + resources.get('every_year'))
  99 + end
  100 +
  101 + def day_of_week_description(expression_parts)
  102 + desc = DayOfWeekDescription.new(resources, options)
  103 + desc.segment_description(expression_parts[5], ', ' + resources.get('every_day'))
  104 + end
  105 +
  106 + def month_description(expression_parts)
  107 + desc = MonthDescription.new(resources)
  108 + desc.segment_description(expression_parts[4], '')
  109 + end
  110 +
  111 + def day_of_month_description(expression_parts)
  112 + exp = expression_parts[3].gsub('?', '*')
  113 + if exp == 'L'
  114 + description = ', ' + resources.get('on_the_last_day_of_the_month')
  115 + elsif exp == 'LW' || exp == 'WL'
  116 + description = ', ' + resources.get('on_the_last_weekday_of_the_month')
  117 + else
  118 + match = exp.match(/(\d{1,2}W)|(W\d{1,2})/)
  119 + if match
  120 + day_num = Cronex::Utils.integer(match[0].gsub('W', ''))
  121 + day_str = day_num == 1 ? resources.get('first_weekday') : format(resources.get('weekday_nearest_day'), day_num)
  122 + description = format(', ' + resources.get('on_the_of_the_month'), day_str)
  123 + else
  124 + desc = DayOfMonthDescription.new(resources)
  125 + description = desc.segment_description(exp, ', ' + resources.get('every_day'))
  126 + end
  127 + end
  128 + description
  129 + end
  130 +
  131 + def time_of_day_description(expression_parts)
  132 + sec_exp, min_exp, hour_exp = expression_parts
  133 + description = ''
  134 + if [sec_exp, min_exp, hour_exp].all? { |exp| !Cronex::Utils.include_any?(exp, SPECIAL_CHARS) }
  135 + # specific time of day (i.e. 10 14)
  136 + description += resources.get('at') + ' ' + Cronex::Utils.format_time(hour_exp, min_exp, sec_exp, timezone)
  137 + elsif min_exp.include?('-') && !min_exp.include?('/') && !min_exp.include?(',') && !Cronex::Utils.include_any?(hour_exp, SPECIAL_CHARS)
  138 + # Minute range in single hour (e.g. 0-10 11)
  139 + min_parts = min_exp.split('-')
  140 + description += format(
  141 + resources.get('every_minute_between'),
  142 + Cronex::Utils.format_time(hour_exp, min_parts[0], '', timezone),
  143 + Cronex::Utils.format_time(hour_exp, min_parts[1], '', timezone))
  144 + elsif hour_exp.include?(',') && !Cronex::Utils.include_any?(min_exp, SPECIAL_CHARS)
  145 + # Hours list with single minute (e.g. 30 6,14,16)
  146 + hour_parts = hour_exp.split(',')
  147 + description += resources.get('at')
  148 + h_parts = hour_parts.map { |part| ' ' + Cronex::Utils.format_time(part, min_exp, '', timezone) }
  149 + description += h_parts[0...-1].join(',') + ' ' + resources.get('and') + h_parts.last
  150 + else
  151 + sec_desc = seconds_description(expression_parts)
  152 + min_desc = minutes_description(expression_parts)
  153 + hour_desc = hours_description(expression_parts)
  154 + description += sec_desc
  155 + description += ', ' if description.size > 0 && !min_desc.empty?
  156 + description += min_desc
  157 + description += ', ' if description.size > 0 && !hour_desc.empty?
  158 + description += hour_desc
  159 + end
  160 + description
  161 + end
  162 +
  163 + def full_description(expression_parts)
  164 + time_segment = time_of_day_description(expression_parts)
  165 + dom_desc = day_of_month_description(expression_parts)
  166 + month_desc = month_description(expression_parts)
  167 + dow_desc = day_of_week_description(expression_parts)
  168 + year_desc = year_description(expression_parts)
  169 + description = format('%s%s%s%s%s', time_segment, dom_desc, dow_desc, month_desc, year_desc)
  170 + description = transform_verbosity(description, options[:verbose])
  171 + description = transform_case(description, options[:casing])
  172 + description
  173 + end
  174 +
  175 + def transform_case(desc, case_type = :lower)
  176 + case case_type
  177 + when :sentence
  178 + desc.sub(/\b[[:word:]]/u) { |s| Unicode.upcase(s) }
  179 + when :title
  180 + desc.gsub(/\b[[:word:]]/u) { |s| Unicode.upcase(s) }
  181 + else
  182 + Unicode.downcase(desc)
  183 + end
  184 + end
  185 +
  186 + def transform_verbosity(desc, verbose = false)
  187 + return desc if verbose
  188 + parts = %w(every_minute every_hour every_day)
  189 + parts.each { |part| desc.gsub!(resources.get(part.gsub('_', '_1_')), resources.get(part)) }
  190 + parts.each { |part| desc.gsub!(', ' + resources.get(part), '') }
  191 + desc
  192 + end
  193 + end
  194 +end
... ...
lib/cronex/parser.rb 0 → 100644
  1 +++ a/lib/cronex/parser.rb
... ... @@ -0,0 +1,93 @@
  1 +module Cronex
  2 +
  3 + DAYS = Date::ABBR_DAYNAMES.map(&:upcase)
  4 + MONTHS = Date::ABBR_MONTHNAMES[1..-1].map(&:upcase)
  5 +
  6 + DAY_NUM = Hash[DAYS.zip(0..(DAYS.size - 1))]
  7 + MONTH_NUM = Hash[MONTHS.zip(1..MONTHS.size)]
  8 +
  9 + # abbr dayname => long dayname
  10 + DAY_DAY = Hash[DAYS.zip(Date::DAYNAMES.map(&:upcase))]
  11 +
  12 + class Parser
  13 + attr_accessor :expression, :options
  14 +
  15 + def initialize(expression, options = {})
  16 + @expression = expression
  17 + @options = options
  18 + end
  19 +
  20 + def parse(exp = expression)
  21 + parsed_parts = Array.new(7, '')
  22 +
  23 + fail ExpressionError, 'Error: Expression null or empty' unless Cronex::Utils.present?(exp)
  24 + parts = sanitize(exp).split(' ')
  25 + len = parts.size
  26 +
  27 + if len < 5
  28 + fail ExpressionError, "Error: Expression only has #{len} parts. At least 5 parts are required"
  29 + elsif len == 5
  30 + fail ExpressionError, "Error: Expression only has 5 parts. For 'strict_quartz' option, at least 6 parts are required" if options[:strict_quartz]
  31 + # 5 part CRON so shift array past seconds element
  32 + parsed_parts.insert(1, *parts)
  33 + elsif len == 6
  34 + # if last element ends with 4 digits, a year element has been supplied and no seconds element
  35 + if parts.last.match(/\d{4}$/)
  36 + parsed_parts.insert(1, *parts)
  37 + else
  38 + parsed_parts.insert(0, *parts)
  39 + end
  40 + elsif len == 7
  41 + parsed_parts = parts
  42 + else
  43 + fail ExpressionError, "Error: Expression has too many parts (#{len}). Expression must not have more than 7 parts"
  44 + end
  45 +
  46 + parsed_parts = parsed_parts.take(7) # ; p parsed_parts
  47 + normalize(parsed_parts, options)
  48 + end
  49 +
  50 + def sanitize(exp = expression)
  51 + # remove extra spaces
  52 + exp = exp.strip.gsub(/\s+/, ' ').upcase
  53 + # convert non-standard day names (e.g. THURS, TUES) to 3-letter names
  54 + DAY_DAY.each do |day, longname|
  55 + matched = exp.scan(/\W*(#{day}\w*)/).flatten.uniq
  56 + matched.each { |m| exp.gsub!(m, day) if longname.include?(m) }
  57 + end
  58 + exp
  59 + end
  60 +
  61 + def normalize(expression_parts, options = {})
  62 + parts = expression_parts.dup
  63 +
  64 + # convert ? to * only for DOM and DOW
  65 + parts[3].gsub!('?', '*')
  66 + parts[5].gsub!('?', '*')
  67 +
  68 + # Convert 0/, 1/ to */
  69 + parts[0].gsub!('0/', '*/') if parts[0].start_with?('0/') # seconds
  70 + parts[1].gsub!('0/', '*/') if parts[1].start_with?('0/') # minutes
  71 + parts[2].gsub!('0/', '*/') if parts[2].start_with?('0/') # hours
  72 + parts[3].gsub!('1/', '*/') if parts[3].start_with?('1/') # day of month
  73 + parts[4].gsub!('1/', '*/') if parts[4].start_with?('1/') # month
  74 + parts[5].gsub!('1/', '*/') if parts[5].start_with?('1/') # day of week
  75 +
  76 + # convert */1 to *
  77 + parts = parts.map { |part| part == '*/1' ? '*' : part }
  78 +
  79 + # convert SUN-SAT format to 0-6 format
  80 + DAY_NUM.each { |day, i| i += 1 if !options[:zero_based_dow]; parts[5].gsub!(day, i.to_s) }
  81 +
  82 + # convert JAN-DEC format to 1-12 format
  83 + MONTH_NUM.each { |month, i| parts[4].gsub!(month, i.to_s) }
  84 +
  85 + # convert 0 second to (empty)
  86 + parts[0] = '' if parts[0] == '0'
  87 +
  88 + # convert 0 DOW to 7 so that 0 for Sunday in zeroBasedDayOfWeek is valid
  89 + parts[5] = '7' if (!options || options[:zero_based_dow]) && parts[5] == '0' # ; p parts
  90 + parts
  91 + end
  92 + end
  93 +end
... ...
lib/cronex/resource.rb 0 → 100644
  1 +++ a/lib/cronex/resource.rb
... ... @@ -0,0 +1,33 @@
  1 +module Cronex
  2 +
  3 + RESOURCES_DIR = File.expand_path('../../../resources', __FILE__)
  4 +
  5 + class Resource
  6 + attr_reader :locale, :messages
  7 +
  8 + def initialize(loc = :en)
  9 + self.locale = loc || :en
  10 + end
  11 +
  12 + def locale=(loc)
  13 + result = load(loc)
  14 + if result.nil? || result.empty?
  15 + fail ResourceError, "Error: Invalid resource file for '#{loc}' locale"
  16 + else
  17 + @locale = loc
  18 + @messages = result
  19 + end
  20 + end
  21 +
  22 + def load(loc)
  23 + file = File.join(RESOURCES_DIR, "resources_#{loc}.yml")
  24 + fail ResourceError, "Resource file #{file} for '#{loc}' locale not found" unless File.exist?(file)
  25 + YAML.load_file(file)
  26 + end
  27 +
  28 + def [](key)
  29 + @messages[key]
  30 + end
  31 + alias_method :get, :[]
  32 + end
  33 +end
... ...
lib/cronex/utils.rb 0 → 100644
  1 +++ a/lib/cronex/utils.rb
... ... @@ -0,0 +1,47 @@
  1 +require 'tzinfo'
  2 +
  3 +module Cronex
  4 + module Utils
  5 + extend self
  6 +
  7 + def present?(str)
  8 + !str.to_s.strip.empty?
  9 + end
  10 +
  11 + def include_any?(str, chars)
  12 + chars.any? { |char| str.include?(char) }
  13 + end
  14 +
  15 + def number?(str)
  16 + integer(str) rescue nil
  17 + end
  18 +
  19 + def integer(str)
  20 + # strip leading zeros in numbers to prevent '08', '09'
  21 + # from being treated as invalid octals
  22 + Integer(str.sub(/^0*(\d+)/, '\1'))
  23 + end
  24 +
  25 + def day_of_week_name(number)
  26 + Date::DAYNAMES[number.to_i % 7]
  27 + end
  28 +
  29 + def format_minutes(minute_expression)
  30 + if minute_expression.include?(',')
  31 + minute_expression.split(',').map { |m| format('%02d', integer(m)) }.join(',')
  32 + else
  33 + format('%02d', integer(minute_expression))
  34 + end
  35 + end
  36 +
  37 + def format_time(hour_expression, minute_expression, second_expression = '', timezone = 'UTC')
  38 + hour = integer(hour_expression)
  39 + minute = integer(minute_expression)
  40 + second = second_expression.to_s.empty? ? 0 : integer(second_expression)
  41 + tz = TZInfo::Timezone.get(timezone)
  42 + time = tz.utc_to_local(Date.today.to_time + hour * 60 * 60 + minute * 60 + second)
  43 + format = present?(second_expression) ? '%l:%M:%S %p' : '%l:%M %p'
  44 + time.strftime(format).lstrip
  45 + end
  46 + end
  47 +end
... ...
lib/cronex/version.rb 0 → 100644
  1 +++ a/lib/cronex/version.rb
... ... @@ -0,0 +1,3 @@
  1 +module Cronex
  2 + VERSION = '0.13.0'
  3 +end
... ...
resources/resources_de.yml 0 → 100644
  1 +++ a/resources/resources_de.yml
... ... @@ -0,0 +1,76 @@
  1 +# resources_de.yml
  2 +---
  3 +expression_empty_exception: 'Ausdruck darf nicht null oder leer sein'
  4 +interval_description_format: 'jeden %s Tag der Woche'
  5 +between_description_format: '%s bis %s'
  6 +between_weekday_description_format: '%s bis %s'
  7 +on_the_day_of_the_month: 'am {{nth}} %s des Monats'
  8 +on_the_of_the_month: 'am %s des Monats'
  9 +on_the_last_of_the_month: 'am letzten %s des Monats'
  10 +on_the_last_day_of_the_month: 'am letzten Tag des Monats'
  11 +on_the_last_weekday_of_the_month: 'am letzen Werktag des Monats'
  12 +between_days_of_the_month: 'zwischen Tag %s und %s des Monats'
  13 +seconds_through_past_the_minute: 'Sekunden %s bis %s vergangene Minute'
  14 +between_x_and_y: 'zwischen %s und %s'
  15 +past_the_hour: 'vergangene Stunde'
  16 +at_x_seconds_past_the_minute: 'am %s Sekunden nach der vergangenen Minute'
  17 +minutes_through_past_the_hour: 'Minuten %s bis %s nach der vergangenen Stunde'
  18 +on_day_of_the_month: 'am %s Tag des Monats'
  19 +last_day: 'der letzte Tag'
  20 +first_weekday: 'Erster Wochentag'
  21 +weekday_nearest_day: 'Wochentag zum nächsten Tag %s'
  22 +starting: 'beginnend'
  23 +only_on: 'nur an %s'
  24 +only_in: 'nur in %s'
  25 +every_x_seconds: 'Alle %s Sekunden'
  26 +every_minute_between: 'Jede Minute zwischen %s und %s'
  27 +every_second: 'Jede Sekunde'
  28 +every_minute: 'Jede Minute'
  29 +every_1_minute: 'Jede 1. Minute'
  30 +every_hour: 'Jede Stunde'
  31 +every_1_hour: 'Jede 1. Stunde'
  32 +every_day: 'Jeden Tag'
  33 +every_1_day: 'Jeden 1. Tag'
  34 +every_year: 'Jedes Jahr'
  35 +every_x: 'Alle %s'
  36 +at_x: 'um %s'
  37 +on_x: 'an %s'
  38 +in_x: 'in %s'
  39 +first: ersten
  40 +second: zweiten
  41 +third: dritten
  42 +fourth: vierten
  43 +fifth: fünften
  44 +time_pm: PM
  45 +time_am: AM
  46 +and: und
  47 +at: Um
  48 +day: Tag
  49 +days: Tagen
  50 +hour: Stunde
  51 +hours: Stunden
  52 +minute: Minute
  53 +minutes: Minuten
  54 +month: Monat
  55 +months: Monaten
  56 +year: Jahr
  57 +years: Jahren
  58 +monday: Montag
  59 +tuesday: Dienstag
  60 +wednesday: Mittwoch
  61 +thursday: Donnerstag
  62 +friday: Freitag
  63 +saturday: Samstag
  64 +sunday: Sonntag
  65 +january: Januar
  66 +february: Februar
  67 +march: März
  68 +april: April
  69 +may: Mai
  70 +june: Juni
  71 +july: Juli
  72 +august: August
  73 +september: September
  74 +october: Oktober
  75 +november: November
  76 +december: Dezember
... ...
resources/resources_en.yml 0 → 100644
  1 +++ a/resources/resources_en.yml
... ... @@ -0,0 +1,76 @@
  1 +# resources_en.yml
  2 +---
  3 +expression_empty_exception: 'Expression cannot be null or empty'
  4 +interval_description_format: 'every %s days of the week'
  5 +between_description_format: '%s through %s'
  6 +between_weekday_description_format: '%s through %s'
  7 +on_the_day_of_the_month: 'on the {{nth}} %s of the month'
  8 +on_the_of_the_month: 'on the %s of the month'
  9 +on_the_last_of_the_month: 'on the last %s of the month'
  10 +on_the_last_day_of_the_month: 'on the last day of the month'
  11 +on_the_last_weekday_of_the_month: 'on the last weekday of the month'
  12 +between_days_of_the_month: 'between day %s and %s of the month'
  13 +seconds_through_past_the_minute: 'seconds %s through %s past the minute'
  14 +between_x_and_y: 'between %s and %s'
  15 +past_the_hour: 'past the hour'
  16 +at_x_seconds_past_the_minute: 'at %s seconds past the minute'
  17 +minutes_through_past_the_hour: 'minutes %s through %s past the hour'
  18 +on_day_of_the_month: 'on day %s of the month'
  19 +last_day: 'the last day'
  20 +first_weekday: 'first weekday'
  21 +weekday_nearest_day: 'weekday nearest day %s'
  22 +starting: 'starting'
  23 +only_on: 'only on %s'
  24 +only_in: 'only in %s'
  25 +every_x_seconds: 'every %s seconds'
  26 +every_minute_between: 'Every minute between %s and %s'
  27 +every_second: 'every second'
  28 +every_minute: 'every minute'
  29 +every_1_minute: 'every 1 minute'
  30 +every_hour: 'every hour'
  31 +every_1_hour: 'every 1 hour'
  32 +every_day: 'every day'
  33 +every_1_day: 'every 1 day'
  34 +every_year: 'every year'
  35 +every_x: 'every %s'
  36 +at_x: 'at %s'
  37 +on_x: 'on %s'
  38 +in_x: 'in %s'
  39 +first: first
  40 +second: second
  41 +third: third
  42 +fourth: fourth
  43 +fifth: fifth
  44 +time_pm: PM
  45 +time_am: AM
  46 +and: and
  47 +at: At
  48 +day: day
  49 +days: days
  50 +hour: hour
  51 +hours: hours
  52 +minute: minute
  53 +minutes: minutes
  54 +month: month
  55 +months: months
  56 +year: year
  57 +years: years
  58 +monday: Monday
  59 +tuesday: Tuesday
  60 +wednesday: Wednesday
  61 +thursday: Thursday
  62 +friday: Friday
  63 +saturday: Saturday
  64 +sunday: Sunday
  65 +january: January
  66 +february: February
  67 +march: March
  68 +april: April
  69 +may: May
  70 +june: June
  71 +july: July
  72 +august: August
  73 +september: September
  74 +october: October
  75 +november: November
  76 +december: December
... ...
resources/resources_fr.yml 0 → 100644
  1 +++ a/resources/resources_fr.yml
... ... @@ -0,0 +1,76 @@
  1 +# resources_fr.yml
  2 +---
  3 +expression_empty_exception: "L'expression ne peut pas être nulle ou vide"
  4 +interval_description_format: 'tous les %s jours de la semaine'
  5 +between_description_format: '%s à %s'
  6 +between_weekday_description_format: '%s à %s'
  7 +on_the_day_of_the_month: 'le {{nth}} %s du mois'
  8 +on_the_of_the_month: 'le %s du mois'
  9 +on_the_last_of_the_month: 'le dernier %s du mois'
  10 +on_the_last_day_of_the_month: 'le dernier jour du mois'
  11 +on_the_last_weekday_of_the_month: 'le dernier jour en semaine du mois'
  12 +between_days_of_the_month: 'entre le jour %s et le %s du mois'
  13 +seconds_through_past_the_minute: 'secondes %s à %s après la minute'
  14 +between_x_and_y: 'entre %s et %s'
  15 +past_the_hour: "après l'heure"
  16 +at_x_seconds_past_the_minute: 'à %s secondes après la minute'
  17 +minutes_through_past_the_hour: "minutes %s à %s après l'heure"
  18 +on_day_of_the_month: 'le %s de chaque mois'
  19 +last_day: 'dernier jour'
  20 +first_weekday: 'premier jour de la semaine'
  21 +weekday_nearest_day: 'jour de semaine le plus proche du %s'
  22 +starting: 'commence' # départ
  23 +only_on: 'seulement le %s' # uniquement le
  24 +only_in: 'seulement en %s'
  25 +every_x_seconds: 'toutes les %s secondes'
  26 +every_minute_between: 'chaque minute entre %s et %s'
  27 +every_second: 'chaque seconde'
  28 +every_minute: 'chaque minute'
  29 +every_1_minute: 'toutes les 1 minutes'
  30 +every_hour: 'chaque heure'
  31 +every_1_hour: 'toutes les 1 heures'
  32 +every_day: 'chaque jour'
  33 +every_1_day: 'tous les 1 jours'
  34 +every_year: 'chaque année'
  35 +every_x: 'tous les %s'
  36 +at_x: 'à %s'
  37 +on_x: 'le %s'
  38 +in_x: 'en %s'
  39 +first: premier
  40 +second: second
  41 +third: troisième
  42 +fourth: quatrième
  43 +fifth: cinquième
  44 +time_pm: PM
  45 +time_am: AM
  46 +and: et
  47 +at: À
  48 +day: jour
  49 +days: jours
  50 +hour: heure
  51 +hours: heures
  52 +minute: minute
  53 +minutes: minutes
  54 +month: mois
  55 +months: mois
  56 +year: an
  57 +years: ans
  58 +monday: lundi
  59 +tuesday: mardi
  60 +wednesday: mercredi
  61 +thursday: jeudi
  62 +friday: vendredi
  63 +saturday: samedi
  64 +sunday: dimanche
  65 +january: janvier
  66 +february: février
  67 +march: mars
  68 +april: avril
  69 +may: mai
  70 +june: juin
  71 +july: juillet
  72 +august: août
  73 +september: septembre
  74 +october: octobre
  75 +november: novembre
  76 +december: décembre
... ...
resources/resources_it.yml 0 → 100644
  1 +++ a/resources/resources_it.yml
... ... @@ -0,0 +1,76 @@
  1 +# resources_it.yml
  2 +---
  3 +expression_empty_exception: "L'espressione non puó essere null o vuota"
  4 +interval_description_format: '%s giorni alla settimana'
  5 +between_description_format: 'da %s a %s'
  6 +between_weekday_description_format: 'da %s a %s'
  7 +on_the_day_of_the_month: 'il(la) {{nth}}(a) %s del mese'
  8 +on_the_of_the_month: 'il %s del mese'
  9 +on_the_last_of_the_month: "l'ultimo(a) %s del mese"
  10 +on_the_last_day_of_the_month: "l'ultimo giorno del mese"
  11 +on_the_last_weekday_of_the_month: "l'ultimo giorno lavorativo del mese"
  12 +between_days_of_the_month: 'tra il giorno %s e il %s del mese'
  13 +seconds_through_past_the_minute: 'dal secondo %s al %s dopo il minuto'
  14 +between_x_and_y: 'tra le %s e le %s'
  15 +past_the_hour: "dopo l'ora"
  16 +at_x_seconds_past_the_minute: 'a %s secondi dopo il minuto'
  17 +minutes_through_past_the_hour: "dal minuto %s al %s dopo l'ora"
  18 +on_day_of_the_month: 'il giorno %s del mese'
  19 +last_day: 'ultimo giorno'
  20 +first_weekday: 'il primo giorno della settimana lavorativa'
  21 +weekday_nearest_day: 'il prossimo giorno %s della settimana lavorativa'
  22 +starting: 'a partire da'
  23 +only_on: 'solo di %s'
  24 +only_in: 'solo a(nel) %s'
  25 +every_x_seconds: 'ogni %s secondi'
  26 +every_minute_between: 'ogni minuto tra le %s e le %s'
  27 +every_second: 'ogni secondo'
  28 +every_minute: 'ogni minuto'
  29 +every_1_minute: 'ogni minuto'
  30 +every_hour: 'ogni ora'
  31 +every_1_hour: 'ogni ora'
  32 +every_day: 'ogni giorno'
  33 +every_1_day: 'ogni giorno'
  34 +every_year: 'ogni anno'
  35 +every_x: 'ogni %s'
  36 +at_x: 'alle(ai) %s'
  37 +on_x: 'il %s'
  38 +in_x: '%s'
  39 +first: primo
  40 +second: secondo
  41 +third: terzo
  42 +fourth: quarto
  43 +fifth: quinto
  44 +time_pm: pomeriggio
  45 +time_am: mattino
  46 +and: e
  47 +at: alle(ai)
  48 +day: giorno
  49 +days: giorni
  50 +hour: ora
  51 +hours: ore
  52 +minute: minuto
  53 +minutes: minuti
  54 +month: mese
  55 +months: mesi
  56 +year: anno
  57 +years: anni
  58 +monday: lunedì
  59 +tuesday: martedì
  60 +wednesday: mercoledì
  61 +thursday: giovedì
  62 +friday: venerdì
  63 +saturday: sabato
  64 +sunday: domenica
  65 +january: gennaio
  66 +february: febbraio
  67 +march: marzo
  68 +april: aprile
  69 +may: maggio
  70 +june: giugno
  71 +july: luglio
  72 +august: agosto
  73 +september: settembre
  74 +october: ottobre
  75 +november: novembre
  76 +december: dicembre
... ...
resources/resources_pt_BR.yml 0 → 100644
  1 +++ a/resources/resources_pt_BR.yml
... ... @@ -0,0 +1,76 @@
  1 +# resources_pt_BR.yml
  2 +---
  3 +expression_empty_exception: 'A expressão não pode ser nula ou vazia'
  4 +interval_description_format: 'a cada %s dias da semana'
  5 +between_description_format: 'de %s a %s'
  6 +between_weekday_description_format: 'de %s a %s'
  7 +on_the_day_of_the_month: 'no(a) {{nth}} %s do mês'
  8 +on_the_of_the_month: 'no %s do mês'
  9 +on_the_last_of_the_month: 'no(a) último(a) %s do mês'
  10 +on_the_last_day_of_the_month: 'no último dia do mês'
  11 +on_the_last_weekday_of_the_month: 'no último dia útil do mês'
  12 +between_days_of_the_month: 'entre os dias %s e %s do mês'
  13 +seconds_through_past_the_minute: 'entre %s e %s segundos após o minuto'
  14 +between_x_and_y: 'entre %s e %s'
  15 +past_the_hour: 'após a hora'
  16 +at_x_seconds_past_the_minute: '%s segundos após o minuto'
  17 +minutes_through_past_the_hour: 'entre %s e %s minutos após a hora'
  18 +on_day_of_the_month: 'no dia %s do mês'
  19 +last_day: 'último dia'
  20 +first_weekday: 'primeiro dia útil'
  21 +weekday_nearest_day: 'dia útil mais próximo a %s'
  22 +starting: 'iniciando'
  23 +only_on: 'todo(a) %s'
  24 +only_in: 'em %s'
  25 +every_x_seconds: 'a cada %s segundos'
  26 +every_minute_between: 'A cada minuto entre %s e %s'
  27 +every_second: 'a cada segundo'
  28 +every_minute: 'a cada minuto'
  29 +every_1_minute: 'a cada 1 minuto'
  30 +every_hour: 'a cada hora'
  31 +every_1_hour: 'a cada 1 hora'
  32 +every_day: 'todo dia'
  33 +every_1_day: 'a cada 1 dia'
  34 +every_year: 'a cada ano'
  35 +every_x: 'a cada %s'
  36 +at_x: '%s'
  37 +on_x: '%s'
  38 +in_x: 'em %s'
  39 +first: primeiro(a)
  40 +second: segundo(a)
  41 +third: terceiro(a)
  42 +fourth: quarto(a)
  43 +fifth: quinto(a)
  44 +time_pm: após meio-dia
  45 +time_am: antes do meio-dia
  46 +and: e
  47 +at: às
  48 +day: dia
  49 +days: dias
  50 +hour: hora
  51 +hours: horas
  52 +minute: minuto
  53 +minutes: minutos
  54 +month: mês
  55 +months: mêses
  56 +year: ano
  57 +years: anos
  58 +monday: segunda-feira
  59 +tuesday: terça-feira
  60 +wednesday: quarta-feira
  61 +thursday: quinta-feira
  62 +friday: sexta-feira
  63 +saturday: sábado
  64 +sunday: domingo
  65 +january: janeiro
  66 +february: fevereiro
  67 +march: março
  68 +april: abril
  69 +may: maio
  70 +june: junho
  71 +july: julho
  72 +august: agosto
  73 +september: setembro
  74 +october: outubro
  75 +november: novembro
  76 +december: dezembro
... ...
resources/resources_ro.yml 0 → 100644
  1 +++ a/resources/resources_ro.yml
... ... @@ -0,0 +1,76 @@
  1 +# resources_ro.yml
  2 +---
  3 +expression_empty_exception: 'Expresia nu poate fi vidă sau nulă'
  4 +interval_description_format: 'în fiecare %s zile din săptămână'
  5 +between_description_format: 'din %s până în %s'
  6 +between_weekday_description_format: 'de %s până %s'
  7 +on_the_day_of_the_month: 'în {{nth}} %s a lunii'
  8 +on_the_of_the_month: 'în %s ale lunii'
  9 +on_the_last_of_the_month: 'în ultima %s din lună'
  10 +on_the_last_day_of_the_month: 'în ultima zi a lunii'
  11 +on_the_last_weekday_of_the_month: 'în ultima zi din săptămână a lunii'
  12 +between_days_of_the_month: 'între zilele %s și %s a lunii'
  13 +seconds_through_past_the_minute: 'între secundele %s și %s'
  14 +between_x_and_y: 'între %s și %s'
  15 +past_the_hour: 'în fiecare oră'
  16 +at_x_seconds_past_the_minute: 'la secunda %s'
  17 +minutes_through_past_the_hour: 'între minutele %s și %s'
  18 +on_day_of_the_month: 'în a %s-a zi a lunii'
  19 +last_day: 'ultima zi'
  20 +first_weekday: 'prima zi din săptămână'
  21 +weekday_nearest_day: 'cea mai apropiată %s din săptămână'
  22 +starting: pornire
  23 +only_on: 'numai %s'
  24 +only_in: 'numai în %s'
  25 +every_x_seconds: 'la fiecare %s secunde'
  26 +every_minute_between: 'în fiecare minut între %s și %s'
  27 +every_second: 'în fiecare secundă'
  28 +every_minute: 'în fiecare minut'
  29 +every_1_minute: 'din minut în minut'
  30 +every_hour: 'în fiecare oră'
  31 +every_1_hour: 'din oră în oră'
  32 +every_day: 'în fiecare zi'
  33 +every_1_day: 'în fiecare zi'
  34 +every_year: 'în fiecare an'
  35 +every_x: 'la fiecare %s'
  36 +at_x: 'la %s'
  37 +on_x: 'de %s'
  38 +in_x: 'în %s'
  39 +first: prima
  40 +second: 'a doua'
  41 +third: 'a treia'
  42 +fourth: 'a patra'
  43 +fifth: 'a cincea'
  44 +time_pm: PM
  45 +time_am: AM
  46 +and: și
  47 +at: la
  48 +day: zi
  49 +days: zile
  50 +hour: oră
  51 +hours: ore
  52 +minute: minut
  53 +minutes: minute
  54 +month: lună
  55 +months: luni
  56 +year: an
  57 +years: ani
  58 +monday: luni
  59 +tuesday: marți
  60 +wednesday: miercuri
  61 +thursday: joi
  62 +friday: vineri
  63 +saturday: sâmbătă
  64 +sunday: duminică
  65 +january: ianuarie
  66 +february: februarie
  67 +march: martie
  68 +april: aprilie
  69 +may: mai
  70 +june: iunie
  71 +july: iulie
  72 +august: august
  73 +september: septembrie
  74 +october: octombrie
  75 +november: noiembrie
  76 +december: decembrie
... ...
resources/resources_ru.yml 0 → 100644
  1 +++ a/resources/resources_ru.yml
... ... @@ -0,0 +1,76 @@
  1 +# resources_ru.yml
  2 +---
  3 +expression_empty_exception: 'Выражение не может быть нулевым или пустым'
  4 +interval_description_format: 'каждые %s дня(ей) недели'
  5 +between_description_format: '%s - %s'
  6 +between_weekday_description_format: '%s - %s'
  7 +on_the_day_of_the_month: 'в {{nth}} %s месяца'
  8 +on_the_of_the_month: 'в %s месяца'
  9 +on_the_last_of_the_month: 'в последний %s месяца'
  10 +on_the_last_day_of_the_month: 'в последний день месяца'
  11 +on_the_last_weekday_of_the_month: 'в последний будний день месяца'
  12 +between_days_of_the_month: 'между %s днем и %s днем месяца'
  13 +seconds_through_past_the_minute: 'секунды с %s по %s'
  14 +between_x_and_y: 'между %s и %s'
  15 +past_the_hour: 'часа'
  16 +at_x_seconds_past_the_minute: 'в %s секунд'
  17 +minutes_through_past_the_hour: 'минуты с %s по %s'
  18 +on_day_of_the_month: '%s день месяца'
  19 +last_day: 'последним'
  20 +first_weekday: 'первый будний день'
  21 +weekday_nearest_day: 'ближайший будний день к %s'
  22 +starting: начало
  23 +only_on: 'только %s'
  24 +only_in: 'только %s'
  25 +every_x_seconds: 'каждые %s секунд'
  26 +every_minute_between: 'каждую минуту с %s по %s'
  27 +every_second: 'каждую секунду'
  28 +every_minute: 'каждую минуту'
  29 +every_1_minute: 'каждую минуту'
  30 +every_hour: 'каждый час'
  31 +every_1_hour: 'каждый час'
  32 +every_day: 'каждый день'
  33 +every_1_day: 'каждый день'
  34 +every_year: 'каждый год'
  35 +every_x: 'каждые %s'
  36 +at_x: 'в %s'
  37 +on_x: 'в %s'
  38 +in_x: 'в %s'
  39 +first: первый
  40 +second: второй
  41 +third: третий
  42 +fourth: четвертый
  43 +fifth: пятый
  44 +time_pm: PM
  45 +time_am: AM
  46 +and: и
  47 +at: В
  48 +day: день
  49 +days: дня(ей)
  50 +hour: час
  51 +hours: часов
  52 +minute: минута
  53 +minutes: минут
  54 +month: месяц
  55 +months: месяцев
  56 +year: год
  57 +years: лет
  58 +monday: понедельник
  59 +tuesday: вторник
  60 +wednesday: среда
  61 +thursday: четверг
  62 +friday: пятница
  63 +saturday: суббота
  64 +sunday: воскресенье
  65 +january: январь
  66 +february: февраль
  67 +march: март
  68 +april: апрель
  69 +may: май
  70 +june: июнь
  71 +july: июль
  72 +august: август
  73 +september: сентябрь
  74 +october: октябрь
  75 +november: ноябрь
  76 +december: декабрь
... ...
resources/resources_zh-CN.yml 0 → 100644
  1 +++ a/resources/resources_zh-CN.yml
... ... @@ -0,0 +1,76 @@
  1 +# resources_zh_CN.yml
  2 +---
  3 +expression_empty_exception: '表达式不能为空'
  4 +interval_description_format: '每隔%s天'
  5 +between_description_format: '%s至%s'
  6 +between_weekday_description_format: '%s至%s'
  7 +on_the_day_of_the_month: '在月份的第{{nth}}个%s'
  8 +on_the_of_the_month: '在月份的%s'
  9 +on_the_last_of_the_month: '在月份的最后一个%s'
  10 +on_the_last_day_of_the_month: '在月份的最后一天'
  11 +on_the_last_weekday_of_the_month: '在月份的最后一个工作日'
  12 +between_days_of_the_month: '在月份的%s至%s号之间'
  13 +seconds_through_past_the_minute: '在分钟之后的%s至%s秒'
  14 +between_x_and_y: '在%s至%s之间'
  15 +past_the_hour: '小时过后'
  16 +at_x_seconds_past_the_minute: '在分钟过后的%s秒'
  17 +minutes_through_past_the_hour: '在小时之后的%s至%s分钟'
  18 +on_day_of_the_month: '在月份的第%s号'
  19 +last_day: '最后一天'
  20 +first_weekday: '第一个工作日'
  21 +weekday_nearest_day: '最接近工作日%s'
  22 +starting: '开始'
  23 +only_on: '仅在%s'
  24 +only_in: '仅在%s'
  25 +every_x_seconds: '每隔%s秒'
  26 +every_minute_between: '每分钟%d至%d之间'
  27 +every_second: '每秒'
  28 +every_minute: '每分钟'
  29 +every_1_minute: '每1分钟'
  30 +every_hour: '每小时'
  31 +every_1_hour: '每1小时'
  32 +every_day: '每天'
  33 +every_1_day: '每1天'
  34 +every_year: '每年'
  35 +every_x: '每隔%s'
  36 +at_x: '在%s'
  37 +on_x: '在%s'
  38 +in_x: '在%s'
  39 +first: '第一'
  40 +second: '第二'
  41 +third: '第三'
  42 +fourth: '第四'
  43 +fifth: '第五'
  44 +time_pm: '下午'
  45 +time_am: '上午'
  46 +and: '和'
  47 +at: '在'
  48 +day: '天'
  49 +days: '天'
  50 +hour: '小时'
  51 +hours: '小时'
  52 +minute: '分钟'
  53 +minutes: '分钟'
  54 +month: '月'
  55 +months: '月'
  56 +year: '年'
  57 +years: '年'
  58 +monday: '星期一'
  59 +tuesday: '星期二'
  60 +wednesday: '星期三'
  61 +thursday: '星期四'
  62 +friday: '星期五'
  63 +saturday: '星期六'
  64 +sunday: '星期日'
  65 +january: '一月'
  66 +february: '二月'
  67 +march: '三月'
  68 +april: '四月'
  69 +may: '五月'
  70 +june: '六月'
  71 +july: '七月'
  72 +august: '八月'
  73 +september: '九月'
  74 +october: '十月'
  75 +november: '十一月'
  76 +december: '十二月'
0 77 \ No newline at end of file
... ...
resources/resources_zh-TW.yml 0 → 100644
  1 +++ a/resources/resources_zh-TW.yml
... ... @@ -0,0 +1,76 @@
  1 +# resources_zh_TW.yml
  2 +---
  3 +expression_empty_exception: '表達式不能為空'
  4 +interval_description_format: '每隔%s天'
  5 +between_description_format: '%s至%s'
  6 +between_weekday_description_format: '%s至%s'
  7 +on_the_day_of_the_month: '在月份的第{{nth}}個%s'
  8 +on_the_of_the_month: '在月份的%s'
  9 +on_the_last_of_the_month: '在月份的最後一個%s'
  10 +on_the_last_day_of_the_month: '在月份的最後一天'
  11 +on_the_last_weekday_of_the_month: '在月份的最後一個工作日'
  12 +between_days_of_the_month: '在月份的%s至%s號之間'
  13 +seconds_through_past_the_minute: '在分鐘之後的%s至%s秒'
  14 +between_x_and_y: '在%s至%s之間'
  15 +past_the_hour: '小時過後'
  16 +at_x_seconds_past_the_minute: '在分鐘過後的%s秒'
  17 +minutes_through_past_the_hour: '在小時之後的%s至%s分鐘'
  18 +on_day_of_the_month: '在月份的第%s號'
  19 +last_day: '最後一天'
  20 +first_weekday: '第一個工作日'
  21 +weekday_nearest_day: '最接近工作日%s'
  22 +starting: '開始'
  23 +only_on: '僅在%s'
  24 +only_in: '僅在%s'
  25 +every_x_seconds: '每隔%s秒'
  26 +every_minute_between: '每分鐘%d至%d之間'
  27 +every_second: '每秒'
  28 +every_minute: '每分鐘'
  29 +every_1_minute: '每1分鐘'
  30 +every_hour: '每小時'
  31 +every_1_hour: '每1小時'
  32 +every_day: '每天'
  33 +every_1_day: '每1天'
  34 +every_year: '每年'
  35 +every_x: '每隔%s'
  36 +at_x: '在%s'
  37 +on_x: '在%s'
  38 +in_x: '在%s'
  39 +first: '第一'
  40 +second: '第二'
  41 +third: '第三'
  42 +fourth: '第四'
  43 +fifth: '第五'
  44 +time_pm: '下午'
  45 +time_am: '上午'
  46 +and: '和'
  47 +at: '在'
  48 +day: '天'
  49 +days: '天'
  50 +hour: '小時'
  51 +hours: '小時'
  52 +minute: '分鐘'
  53 +minutes: '分鐘'
  54 +month: '月'
  55 +months: '月'
  56 +year: '年'
  57 +years: '年'
  58 +monday: '星期一'
  59 +tuesday: '星期二'
  60 +wednesday: '星期三'
  61 +thursday: '星期四'
  62 +friday: '星期五'
  63 +saturday: '星期六'
  64 +sunday: '星期日'
  65 +january: '一月'
  66 +february: '二月'
  67 +march: '三月'
  68 +april: '四月'
  69 +may: '五月'
  70 +june: '六月'
  71 +july: '七月'
  72 +august: '八月'
  73 +september: '九月'
  74 +october: '十月'
  75 +november: '十一月'
  76 +december: '十二月'
0 77 \ No newline at end of file
... ...
spec/casing_spec.rb 0 → 100644
  1 +++ a/spec/casing_spec.rb
... ... @@ -0,0 +1,22 @@
  1 +require 'cronex'
  2 +
  3 +module Cronex
  4 + describe ExpressionDescriptor do
  5 +
  6 + subject(:expression) { '* * * * *' }
  7 +
  8 + context 'casing:' do
  9 + it 'sentence' do
  10 + expect(desc(expression, casing: :sentence)).to eq('Every minute')
  11 + end
  12 +
  13 + it 'title' do
  14 + expect(desc(expression, casing: :title)).to eq('Every Minute')
  15 + end
  16 +
  17 + it 'lower' do
  18 + expect(desc(expression, casing: :lower)).to eq('every minute')
  19 + end
  20 + end
  21 + end
  22 +end
... ...
spec/exp_descriptor_de_spec.rb 0 → 100644
  1 +++ a/spec/exp_descriptor_de_spec.rb
... ... @@ -0,0 +1,405 @@
  1 +# encoding: utf-8
  2 +require 'cronex'
  3 +
  4 +module Cronex
  5 + describe ExpressionDescriptor do
  6 +
  7 + def desc(expression, opts = {})
  8 + opts[:locale] = 'de'
  9 + Cronex::ExpressionDescriptor.new(expression, opts).description
  10 + end
  11 +
  12 + let(:opts) { { zero_based_dow: false } }
  13 +
  14 + it 'every second' do
  15 + expect(desc('* * * * * *')).to eq('Jede Sekunde')
  16 + end
  17 +
  18 + it 'every 45 seconds' do
  19 + expect(desc('*/45 * * * * *')).to eq('Alle 45 Sekunden')
  20 + end
  21 +
  22 + it 'minute span' do
  23 + expect(desc('0-10 11 * * *')).to eq('Jede Minute zwischen 11:00 AM und 11:10 AM')
  24 + end
  25 +
  26 + context 'every minute' do
  27 + it 'every minute' do
  28 + expect(desc('* * * * *')).to eq('Jede Minute')
  29 + end
  30 +
  31 + it 'every minute */1' do
  32 + expect(desc('*/1 * * * *')).to eq('Jede Minute')
  33 + end
  34 +
  35 + it 'every minute 0 0/1' do
  36 + expect(desc('0 0/1 * * * ?')).to eq('Jede Minute')
  37 + end
  38 + end
  39 +
  40 + context 'every X minutes:' do
  41 + it 'every 5 minutes' do
  42 + expect(desc('*/5 * * * *')).to eq('Alle 5 Minuten')
  43 + end
  44 +
  45 + it 'every 5 minutes at Midnight' do
  46 + expect(desc('*/5 0 * * *')).to eq('Alle 5 Minuten, um 12:00 AM')
  47 + end
  48 +
  49 + it 'every 5 minutes 0 */5' do
  50 + expect(desc('0 */5 * * * *')).to eq('Alle 5 Minuten')
  51 + end
  52 +
  53 + it 'every 10 minutes 0 0/10' do
  54 + expect(desc('0 0/10 * * * ?')).to eq('Alle 10 Minuten')
  55 + end
  56 + end
  57 +
  58 + context 'every hour:' do
  59 + it 'every hour 0 0' do
  60 + expect(desc('0 0 * * * ?')).to eq('Jede Stunde')
  61 + end
  62 +
  63 + it 'every hour 0 0 0/1' do
  64 + expect(desc('0 0 0/1 * * ?')).to eq('Jede Stunde')
  65 + end
  66 + end
  67 +
  68 + context 'daily:' do
  69 + it 'daily at /\d\d/:/\d\d/' do
  70 + expect(desc('30 11 * * *')).to eq('Um 11:30 AM')
  71 + end
  72 +
  73 + it 'daily at /\d/:/\d/' do
  74 + expect(desc('9 8 * * *')).to eq('Um 8:09 AM')
  75 + end
  76 +
  77 + it 'daily at /0[89]/:/0[89]/' do
  78 + expect(desc('09 08 * * *')).to eq('Um 8:09 AM')
  79 + end
  80 +
  81 + it 'daily at /0[1-7]/ /0[1-7/' do
  82 + expect(desc('02 01 * * *')).to eq('Um 1:02 AM')
  83 + end
  84 + end
  85 +
  86 + context 'time of day certain days of week:' do
  87 + it 'time of day on MON-FRI' do
  88 + expect(desc('0 23 ? * MON-FRI')).to eq('Um 11:00 PM, Montag bis Freitag')
  89 + end
  90 +
  91 + it 'time of day on 1-5' do
  92 + expect(desc('30 11 * * 1-5')).to eq('Um 11:30 AM, Montag bis Freitag')
  93 + end
  94 + end
  95 +
  96 + it 'one month only' do
  97 + expect(desc('* * * 3 *')).to eq('Jede Minute, nur in März')
  98 + end
  99 +
  100 + it 'two months only' do
  101 + expect(desc('* * * 3,6 *')).to eq('Jede Minute, nur in März und Juni')
  102 + end
  103 +
  104 + it 'two times each afternoon' do
  105 + expect(desc('30 14,16 * * *')).to eq('Um 2:30 PM und 4:30 PM')
  106 + end
  107 +
  108 + it 'three times daily' do
  109 + expect(desc('30 6,14,16 * * *')).to eq('Um 6:30 AM, 2:30 PM und 4:30 PM')
  110 + end
  111 +
  112 + context 'once a week:' do
  113 + it 'once a week 0' do
  114 + expect(desc('46 9 * * 0')).to eq('Um 9:46 AM, nur an Sonntag')
  115 + end
  116 +
  117 + it 'once a week SUN' do
  118 + expect(desc('46 9 * * SUN')).to eq('Um 9:46 AM, nur an Sonntag')
  119 + end
  120 +
  121 + it 'once a week 7' do
  122 + expect(desc('46 9 * * 7')).to eq('Um 9:46 AM, nur an Sonntag')
  123 + end
  124 +
  125 + it 'once a week 1' do
  126 + expect(desc('46 9 * * 1')).to eq('Um 9:46 AM, nur an Montag')
  127 + end
  128 +
  129 + it 'once a week 6' do
  130 + expect(desc('46 9 * * 6')).to eq('Um 9:46 AM, nur an Samstag')
  131 + end
  132 + end
  133 +
  134 + context 'once a week non zero based:' do
  135 + it 'once a week 1' do
  136 + expect(desc('46 9 * * 1', opts)).to eq('Um 9:46 AM, nur an Sonntag')
  137 + end
  138 +
  139 + it 'once a week SUN' do
  140 + expect(desc('46 9 * * SUN', opts)).to eq('Um 9:46 AM, nur an Sonntag')
  141 + end
  142 +
  143 + it 'once a week 2' do
  144 + expect(desc('46 9 * * 2', opts)).to eq('Um 9:46 AM, nur an Montag')
  145 + end
  146 +
  147 + it 'once a week 7' do
  148 + expect(desc('46 9 * * 7', opts)).to eq('Um 9:46 AM, nur an Samstag')
  149 + end
  150 + end
  151 +
  152 + context 'twice a week:' do
  153 + it 'twice a week 1,2' do
  154 + expect(desc('46 9 * * 1,2')).to eq('Um 9:46 AM, nur an Montag und Dienstag')
  155 + end
  156 +
  157 + it 'twice a week MON,TUE' do
  158 + expect(desc('46 9 * * MON,TUE')).to eq('Um 9:46 AM, nur an Montag und Dienstag')
  159 + end
  160 +
  161 + it 'twice a week 0,6' do
  162 + expect(desc('46 9 * * 0,6')).to eq('Um 9:46 AM, nur an Sonntag und Samstag')
  163 + end
  164 +
  165 + it 'twice a week 6,7' do
  166 + expect(desc('46 9 * * 6,7')).to eq('Um 9:46 AM, nur an Samstag und Sonntag')
  167 + end
  168 + end
  169 +
  170 + context 'twice a week non zero based:' do
  171 + it 'twice a week 1,2' do
  172 + expect(desc('46 9 * * 1,2', opts)).to eq('Um 9:46 AM, nur an Sonntag und Montag')
  173 + end
  174 +
  175 + it 'twice a week SUN,MON' do
  176 + expect(desc('46 9 * * SUN,MON', opts)).to eq('Um 9:46 AM, nur an Sonntag und Montag')
  177 + end
  178 +
  179 + it 'twice a week 6,7' do
  180 + expect(desc('46 9 * * 6,7', opts)).to eq('Um 9:46 AM, nur an Freitag und Samstag')
  181 + end
  182 + end
  183 +
  184 + it 'day of month' do
  185 + expect(desc('23 12 15 * *')).to eq('Um 12:23 PM, am 15 Tag des Monats')
  186 + end
  187 +
  188 + it 'day of month with day of week' do
  189 + expect(desc('23 12 15 * SUN')).to eq('Um 12:23 PM, am 15 Tag des Monats, nur an Sonntag')
  190 + end
  191 +
  192 + it 'month name' do
  193 + expect(desc('23 12 * JAN *')).to eq('Um 12:23 PM, nur in Januar')
  194 + end
  195 +
  196 + it 'day of month with question mark' do
  197 + expect(desc('23 12 ? JAN *')).to eq('Um 12:23 PM, nur in Januar')
  198 + end
  199 +
  200 + it 'month name range 2' do
  201 + expect(desc('23 12 * JAN-FEB *')).to eq('Um 12:23 PM, Januar bis Februar')
  202 + end
  203 +
  204 + it 'month name range 3' do
  205 + expect(desc('23 12 * JAN-MAR *')).to eq('Um 12:23 PM, Januar bis März')
  206 + end
  207 +
  208 + it 'day of week name' do
  209 + expect(desc('23 12 * * SUN')).to eq('Um 12:23 PM, nur an Sonntag')
  210 + end
  211 +
  212 + context 'day of week range:' do
  213 + it 'day of week range MON-FRI' do
  214 + expect(desc('*/5 15 * * MON-FRI')).to eq('Alle 5 Minuten, um 3:00 PM, Montag bis Freitag')
  215 + end
  216 +
  217 + it 'day of week range 0-6' do
  218 + expect(desc('*/5 15 * * 0-6')).to eq('Alle 5 Minuten, um 3:00 PM, Sonntag bis Samstag')
  219 + end
  220 +
  221 + it 'day of week range 6-7' do
  222 + expect(desc('*/5 15 * * 6-7')).to eq('Alle 5 Minuten, um 3:00 PM, Samstag bis Sonntag')
  223 + end
  224 + end
  225 +
  226 + context 'day of week once in month:' do
  227 + it 'day of week once MON#3' do
  228 + expect(desc('* * * * MON#3')).to eq('Jede Minute, am dritten Montag des Monats')
  229 + end
  230 +
  231 + it 'day of week once 0#3' do
  232 + expect(desc('* * * * 0#3')).to eq('Jede Minute, am dritten Sonntag des Monats')
  233 + end
  234 + end
  235 +
  236 + context 'last day of week of the month:' do
  237 + it 'last day of week 4L' do
  238 + expect(desc('* * * * 4L')).to eq('Jede Minute, am letzten Donnerstag des Monats')
  239 + end
  240 +
  241 + it 'last day of week 0L' do
  242 + expect(desc('* * * * 0L')).to eq('Jede Minute, am letzten Sonntag des Monats')
  243 + end
  244 + end
  245 +
  246 + context 'last day of the month:' do
  247 + it 'on the last day of the month' do
  248 + expect(desc('*/5 * L JAN *')).to eq('Alle 5 Minuten, am letzten Tag des Monats, nur in Januar')
  249 + end
  250 +
  251 + it 'between a day and last day of the month' do
  252 + expect(desc('*/5 * 23-L JAN *')).to eq('Alle 5 Minuten, zwischen Tag 23 und der letzte Tag des Monats, nur in Januar')
  253 + end
  254 + end
  255 +
  256 + it 'time of day with seconds' do
  257 + expect(desc('30 02 14 * * *')).to eq('Um 2:02:30 PM')
  258 + end
  259 +
  260 + it 'second intervals' do
  261 + expect(desc('5-10 * * * * *')).to eq('Sekunden 5 bis 10 vergangene Minute')
  262 + end
  263 +
  264 + it 'second minutes hours intervals' do
  265 + expect(desc('5-10 30-35 10-12 * * *')).to eq(
  266 + 'Sekunden 5 bis 10 vergangene Minute, Minuten 30 bis 35 nach der vergangenen Stunde, zwischen 10:00 AM und 12:59 PM')
  267 + end
  268 +
  269 + it 'every 5 minutes at 30 seconds' do
  270 + expect(desc('30 */5 * * * *')).to eq('Am 30 Sekunden nach der vergangenen Minute, Alle 5 Minuten')
  271 + end
  272 +
  273 + it 'minutes past the hour range' do
  274 + expect(desc('0 30 10-13 ? * WED,FRI')).to eq(
  275 + 'Um 30 Minuten vergangene Stunde, zwischen 10:00 AM und 1:59 PM, nur an Mittwoch und Freitag')
  276 + end
  277 +
  278 + it 'seconds past the minute interval' do
  279 + expect(desc('10 0/5 * * * ?')).to eq('Am 10 Sekunden nach der vergangenen Minute, Alle 5 Minuten')
  280 + end
  281 +
  282 + it 'between with interval' do
  283 + expect(desc('2-59/3 1,9,22 11-26 1-6 ?')).to eq(
  284 + 'Alle 3 Minuten, Minuten 02 bis 59 nach der vergangenen Stunde, um 1:00 AM, 9:00 AM und 10:00 PM, zwischen Tag 11 und 26 des Monats, Januar bis Juni')
  285 + end
  286 +
  287 + it 'recurring first of month' do
  288 + expect(desc('0 0 6 1/1 * ?')).to eq('Um 6:00 AM')
  289 + end
  290 +
  291 + it 'minutes past the hour' do
  292 + expect(desc('0 5 0/1 * * ?')).to eq('Um 05 Minuten vergangene Stunde')
  293 + end
  294 +
  295 + it 'every past the hour' do
  296 + expect(desc('0 0,5,10,15,20,25,30,35,40,45,50,55 * ? * *')).to eq(
  297 + 'Um 00, 05, 10, 15, 20, 25, 30, 35, 40, 45, 50 und 55 Minuten vergangene Stunde')
  298 + end
  299 +
  300 + it 'every X minutes past the hour with interval' do
  301 + expect(desc('0 0-30/2 17 ? * MON-FRI')).to eq(
  302 + 'Alle 2 Minuten, Minuten 00 bis 30 nach der vergangenen Stunde, um 5:00 PM, Montag bis Freitag')
  303 + end
  304 +
  305 + it 'every X days with interval' do
  306 + expect(desc('30 7 1-L/2 * *')).to eq('Um 7:30 AM, Alle 2 Tagen, zwischen Tag 1 und der letzte Tag des Monats')
  307 + end
  308 +
  309 + it 'one year only with seconds' do
  310 + expect(desc('* * * * * * 2013')).to eq('Jede Sekunde, nur in 2013')
  311 + end
  312 +
  313 + it 'one year only without seconds' do
  314 + expect(desc('* * * * * 2013')).to eq('Jede Minute, nur in 2013')
  315 + end
  316 +
  317 + it 'two years only' do
  318 + expect(desc('* * * * * 2013,2014')).to eq('Jede Minute, nur in 2013 und 2014')
  319 + end
  320 +
  321 + it 'year range 2' do
  322 + expect(desc('23 12 * JAN-FEB * 2013-2014')).to eq('Um 12:23 PM, Januar bis Februar, 2013 bis 2014')
  323 + end
  324 +
  325 + it 'year range 3' do
  326 + expect(desc('23 12 * JAN-MAR * 2013-2015')).to eq('Um 12:23 PM, Januar bis März, 2013 bis 2015')
  327 + end
  328 +
  329 + context 'multi part range seconds:' do
  330 + it 'multi part range seconds 2,4-5' do
  331 + expect(desc('2,4-5 1 * * *')).to eq('Minuten 02,04 bis 05 nach der vergangenen Stunde, um 1:00 AM')
  332 + end
  333 +
  334 + it 'multi part range seconds 2,26-28' do
  335 + expect(desc('2,26-28 18 * * *')).to eq('Minuten 02,26 bis 28 nach der vergangenen Stunde, um 6:00 PM')
  336 + end
  337 + end
  338 +
  339 + context 'minutes past the hour:' do
  340 + it 'minutes past the hour 5,10, midnight hour' do
  341 + expect(desc('5,10 0 * * *')).to eq('Um 05 und 10 Minuten vergangene Stunde, um 12:00 AM')
  342 + end
  343 +
  344 + it 'minutes past the hour 5,10' do
  345 + expect(desc('5,10 * * * *')).to eq('Um 05 und 10 Minuten vergangene Stunde')
  346 + end
  347 +
  348 + it 'minutes past the hour 5,10 day 2' do
  349 + expect(desc('5,10 * 2 * *')).to eq('Um 05 und 10 Minuten vergangene Stunde, am 2 Tag des Monats')
  350 + end
  351 +
  352 + it 'minutes past the hour 5/10 day 2' do
  353 + expect(desc('5/10 * 2 * *')).to eq('Alle 10 Minuten, beginnend um 05 Minuten vergangene Stunde, am 2 Tag des Monats')
  354 + end
  355 + end
  356 +
  357 + context 'seconds past the minute:' do
  358 + it 'seconds past the minute 5,6, midnight hour' do
  359 + expect(desc('5,6 0 0 * * *')).to eq('Am 5 und 6 Sekunden nach der vergangenen Minute, um 12:00 AM')
  360 + end
  361 +
  362 + it 'seconds past the minute 5,6' do
  363 + expect(desc('5,6 0 * * * *')).to eq('Am 5 und 6 Sekunden nach der vergangenen Minute')
  364 + end
  365 +
  366 + it 'seconds past the minute 5,6 at 1' do
  367 + expect(desc('5,6 0 1 * * *')).to eq('Am 5 und 6 Sekunden nach der vergangenen Minute, um 1:00 AM')
  368 + end
  369 +
  370 + it 'seconds past the minute 5,6 day 2' do
  371 + expect(desc('5,6 0 * 2 * *')).to eq('Am 5 und 6 Sekunden nach der vergangenen Minute, am 2 Tag des Monats')
  372 + end
  373 + end
  374 +
  375 + context 'increments starting at X > 1:' do
  376 + it 'second increments' do
  377 + expect(desc('5/15 0 * * * *')).to eq('Alle 15 Sekunden, beginnend am 5 Sekunden nach der vergangenen Minute')
  378 + end
  379 +
  380 + it 'minute increments' do
  381 + expect(desc('30/10 * * * *')).to eq('Alle 10 Minuten, beginnend um 30 Minuten vergangene Stunde')
  382 + end
  383 +
  384 + it 'hour increments' do
  385 + expect(desc('0 30 2/6 * * ?')).to eq('Um 30 Minuten vergangene Stunde, Alle 6 Stunden, beginnend um 2:00 AM')
  386 + end
  387 +
  388 + it 'day of month increments' do
  389 + expect(desc('0 30 8 2/7 * *')).to eq('Um 8:30 AM, Alle 7 Tagen, beginnend am 2 Tag des Monats')
  390 + end
  391 +
  392 + it 'day of week increments' do
  393 + expect(desc('0 30 11 * * 2/2')).to eq('Um 11:30 AM, jeden 2 Tag der Woche, beginnend an Dienstag')
  394 + end
  395 +
  396 + it 'month increments' do
  397 + expect(desc('0 20 10 * 2/3 THU')).to eq('Um 10:20 AM, nur an Donnerstag, Alle 3 Monaten, beginnend in Februar')
  398 + end
  399 +
  400 + it 'year increments' do
  401 + expect(desc('0 0 0 1 MAR * 2010/5')).to eq('Um 12:00 AM, am 1 Tag des Monats, nur in März, Alle 5 Jahren, beginnend in 2010')
  402 + end
  403 + end
  404 + end
  405 +end
... ...
spec/exp_descriptor_en_spec.rb 0 → 100644
  1 +++ a/spec/exp_descriptor_en_spec.rb
... ... @@ -0,0 +1,431 @@
  1 +# encoding: utf-8
  2 +require 'cronex'
  3 +
  4 +module Cronex
  5 + describe ExpressionDescriptor do
  6 +
  7 + def desc(expression, opts = {})
  8 + opts[:locale] = 'en'
  9 + Cronex::ExpressionDescriptor.new(expression, opts).description
  10 + end
  11 +
  12 + let(:opts) { { zero_based_dow: false } }
  13 +
  14 + it 'every second' do
  15 + expect(desc('* * * * * *')).to eq('Every second')
  16 + end
  17 +
  18 + it 'every 45 seconds' do
  19 + expect(desc('*/45 * * * * *')).to eq('Every 45 seconds')
  20 + end
  21 +
  22 + it 'minute span' do
  23 + expect(desc('0-10 11 * * *')).to eq('Every minute between 11:00 AM and 11:10 AM')
  24 + end
  25 +
  26 + context 'every minute' do
  27 + it 'every minute' do
  28 + expect(desc('* * * * *')).to eq('Every minute')
  29 + end
  30 +
  31 + it 'every minute */1' do
  32 + expect(desc('*/1 * * * *')).to eq('Every minute')
  33 + end
  34 +
  35 + it 'every minute 0 0/1' do
  36 + expect(desc('0 0/1 * * * ?')).to eq('Every minute')
  37 + end
  38 + end
  39 +
  40 + context 'every X minutes:' do
  41 + it 'every 5 minutes' do
  42 + expect(desc('*/5 * * * *')).to eq('Every 5 minutes')
  43 + end
  44 +
  45 + it 'every 5 minutes at Midnight' do
  46 + expect(desc('*/5 0 * * *')).to eq('Every 5 minutes, at 12:00 AM')
  47 + end
  48 +
  49 + it 'every 5 minutes 0 */5' do
  50 + expect(desc('0 */5 * * * *')).to eq('Every 5 minutes')
  51 + end
  52 +
  53 + it 'every 10 minutes 0 0/10' do
  54 + expect(desc('0 0/10 * * * ?')).to eq('Every 10 minutes')
  55 + end
  56 + end
  57 +
  58 + context 'every hour:' do
  59 + it 'every hour 0 0' do
  60 + expect(desc('0 0 * * * ?')).to eq('Every hour')
  61 + end
  62 +
  63 + it 'every hour 0 0 0/1' do
  64 + expect(desc('0 0 0/1 * * ?')).to eq('Every hour')
  65 + end
  66 + end
  67 +
  68 + context 'daily:' do
  69 + it 'daily at /\d\d/:/\d\d/' do
  70 + expect(desc('30 11 * * *')).to eq('At 11:30 AM')
  71 + end
  72 +
  73 + it 'daily at /\d/:/\d/' do
  74 + expect(desc('9 8 * * *')).to eq('At 8:09 AM')
  75 + end
  76 +
  77 + it 'daily at /0[89]/:/0[89]/' do
  78 + expect(desc('09 08 * * *')).to eq('At 8:09 AM')
  79 + end
  80 +
  81 + it 'daily at /0[1-7]/ /0[1-7/' do
  82 + expect(desc('02 01 * * *')).to eq('At 1:02 AM')
  83 + end
  84 + end
  85 +
  86 + context 'time of day certain days of week:' do
  87 + it 'time of day on MON-FRI' do
  88 + expect(desc('0 23 ? * MON-FRI')).to eq('At 11:00 PM, Monday through Friday')
  89 + end
  90 +
  91 + it 'time of day on 1-5' do
  92 + expect(desc('30 11 * * 1-5')).to eq('At 11:30 AM, Monday through Friday')
  93 + end
  94 + end
  95 +
  96 + it 'one month only' do
  97 + expect(desc('* * * 3 *')).to eq('Every minute, only in March')
  98 + end
  99 +
  100 + it 'two months only' do
  101 + expect(desc('* * * 3,6 *')).to eq('Every minute, only in March and June')
  102 + end
  103 +
  104 + it 'two times each afternoon' do
  105 + expect(desc('30 14,16 * * *')).to eq('At 2:30 PM and 4:30 PM')
  106 + end
  107 +
  108 + it 'three times daily' do
  109 + expect(desc('30 6,14,16 * * *')).to eq('At 6:30 AM, 2:30 PM and 4:30 PM')
  110 + end
  111 +
  112 + context 'once a week:' do
  113 + it 'once a week 0' do
  114 + expect(desc('46 9 * * 0')).to eq('At 9:46 AM, only on Sunday')
  115 + end
  116 +
  117 + it 'once a week SUN' do
  118 + expect(desc('46 9 * * SUN')).to eq('At 9:46 AM, only on Sunday')
  119 + end
  120 +
  121 + it 'once a week 7' do
  122 + expect(desc('46 9 * * 7')).to eq('At 9:46 AM, only on Sunday')
  123 + end
  124 +
  125 + it 'once a week 1' do
  126 + expect(desc('46 9 * * 1')).to eq('At 9:46 AM, only on Monday')
  127 + end
  128 +
  129 + it 'once a week 6' do
  130 + expect(desc('46 9 * * 6')).to eq('At 9:46 AM, only on Saturday')
  131 + end
  132 + end
  133 +
  134 + context 'once a week non zero based:' do
  135 + it 'once a week 1' do
  136 + expect(desc('46 9 * * 1', opts)).to eq('At 9:46 AM, only on Sunday')
  137 + end
  138 +
  139 + it 'once a week SUN' do
  140 + expect(desc('46 9 * * SUN', opts)).to eq('At 9:46 AM, only on Sunday')
  141 + end
  142 +
  143 + it 'once a week 2' do
  144 + expect(desc('46 9 * * 2', opts)).to eq('At 9:46 AM, only on Monday')
  145 + end
  146 +
  147 + it 'once a week 7' do
  148 + expect(desc('46 9 * * 7', opts)).to eq('At 9:46 AM, only on Saturday')
  149 + end
  150 + end
  151 +
  152 + context 'twice a week:' do
  153 + it 'twice a week 1,2' do
  154 + expect(desc('46 9 * * 1,2')).to eq('At 9:46 AM, only on Monday and Tuesday')
  155 + end
  156 +
  157 + it 'twice a week MON,TUE' do
  158 + expect(desc('46 9 * * MON,TUE')).to eq('At 9:46 AM, only on Monday and Tuesday')
  159 + end
  160 +
  161 + it 'twice a week 0,6' do
  162 + expect(desc('46 9 * * 0,6')).to eq('At 9:46 AM, only on Sunday and Saturday')
  163 + end
  164 +
  165 + it 'twice a week 6,7' do
  166 + expect(desc('46 9 * * 6,7')).to eq('At 9:46 AM, only on Saturday and Sunday')
  167 + end
  168 + end
  169 +
  170 + context 'twice a week non zero based:' do
  171 + it 'twice a week 1,2' do
  172 + expect(desc('46 9 * * 1,2', opts)).to eq('At 9:46 AM, only on Sunday and Monday')
  173 + end
  174 +
  175 + it 'twice a week SUN,MON' do
  176 + expect(desc('46 9 * * SUN,MON', opts)).to eq('At 9:46 AM, only on Sunday and Monday')
  177 + end
  178 +
  179 + it 'twice a week 6,7' do
  180 + expect(desc('46 9 * * 6,7', opts)).to eq('At 9:46 AM, only on Friday and Saturday')
  181 + end
  182 + end
  183 +
  184 + it 'day of month' do
  185 + expect(desc('23 12 15 * *')).to eq('At 12:23 PM, on day 15 of the month')
  186 + end
  187 +
  188 + it 'day of month with day of week' do
  189 + expect(desc('23 12 15 * SUN')).to eq('At 12:23 PM, on day 15 of the month, only on Sunday')
  190 + end
  191 +
  192 + it 'month name' do
  193 + expect(desc('23 12 * JAN *')).to eq('At 12:23 PM, only in January')
  194 + end
  195 +
  196 + it 'day of month with question mark' do
  197 + expect(desc('23 12 ? JAN *')).to eq('At 12:23 PM, only in January')
  198 + end
  199 +
  200 + it 'month name range 2' do
  201 + expect(desc('23 12 * JAN-FEB *')).to eq('At 12:23 PM, January through February')
  202 + end
  203 +
  204 + it 'month name range 3' do
  205 + expect(desc('23 12 * JAN-MAR *')).to eq('At 12:23 PM, January through March')
  206 + end
  207 +
  208 + it 'day of week name' do
  209 + expect(desc('23 12 * * SUN')).to eq('At 12:23 PM, only on Sunday')
  210 + end
  211 +
  212 + context 'day of week range:' do
  213 + it 'day of week range MON-FRI' do
  214 + expect(desc('*/5 15 * * MON-FRI')).to eq('Every 5 minutes, at 3:00 PM, Monday through Friday')
  215 + end
  216 +
  217 + it 'day of week range 0-6' do
  218 + expect(desc('*/5 15 * * 0-6')).to eq('Every 5 minutes, at 3:00 PM, Sunday through Saturday')
  219 + end
  220 +
  221 + it 'day of week range 6-7' do
  222 + expect(desc('*/5 15 * * 6-7')).to eq('Every 5 minutes, at 3:00 PM, Saturday through Sunday')
  223 + end
  224 + end
  225 +
  226 + context 'day of week once in month:' do
  227 + it 'day of week once MON#3' do
  228 + expect(desc('* * * * MON#3')).to eq('Every minute, on the third Monday of the month')
  229 + end
  230 +
  231 + it 'day of week once 0#3' do
  232 + expect(desc('* * * * 0#3')).to eq('Every minute, on the third Sunday of the month')
  233 + end
  234 + end
  235 +
  236 + context 'last day of week of the month:' do
  237 + it 'last day of week 4L' do
  238 + expect(desc('* * * * 4L')).to eq('Every minute, on the last Thursday of the month')
  239 + end
  240 +
  241 + it 'last day of week 0L' do
  242 + expect(desc('* * * * 0L')).to eq('Every minute, on the last Sunday of the month')
  243 + end
  244 + end
  245 +
  246 + context 'last day of the month:' do
  247 + it 'on the last day of the month' do
  248 + expect(desc('*/5 * L JAN *')).to eq('Every 5 minutes, on the last day of the month, only in January')
  249 + end
  250 +
  251 + it 'between a day and last day of the month' do
  252 + expect(desc('*/5 * 23-L JAN *')).to eq('Every 5 minutes, between day 23 and the last day of the month, only in January')
  253 + end
  254 + end
  255 +
  256 + it 'time of day with seconds' do
  257 + expect(desc('30 02 14 * * *')).to eq('At 2:02:30 PM')
  258 + end
  259 +
  260 + it 'second intervals' do
  261 + expect(desc('5-10 * * * * *')).to eq('Seconds 5 through 10 past the minute')
  262 + end
  263 +
  264 + it 'second minutes hours intervals' do
  265 + expect(desc('5-10 30-35 10-12 * * *')).to eq(
  266 + 'Seconds 5 through 10 past the minute, minutes 30 through 35 past the hour, between 10:00 AM and 12:59 PM')
  267 + end
  268 +
  269 + it 'every 5 minutes at 30 seconds' do
  270 + expect(desc('30 */5 * * * *')).to eq('At 30 seconds past the minute, every 5 minutes')
  271 + end
  272 +
  273 + it 'minutes past the hour range' do
  274 + expect(desc('0 30 10-13 ? * WED,FRI')).to eq(
  275 + 'At 30 minutes past the hour, between 10:00 AM and 1:59 PM, only on Wednesday and Friday')
  276 + end
  277 +
  278 + it 'seconds past the minute interval' do
  279 + expect(desc('10 0/5 * * * ?')).to eq('At 10 seconds past the minute, every 5 minutes')
  280 + end
  281 +
  282 + it 'between with interval' do
  283 + expect(desc('2-59/3 1,9,22 11-26 1-6 ?')).to eq(
  284 + 'Every 3 minutes, minutes 02 through 59 past the hour, at 1:00 AM, 9:00 AM and 10:00 PM, between day 11 and 26 of the month, January through June')
  285 + end
  286 +
  287 + it 'recurring first of month' do
  288 + expect(desc('0 0 6 1/1 * ?')).to eq('At 6:00 AM')
  289 + end
  290 +
  291 + it 'minutes past the hour' do
  292 + expect(desc('0 5 0/1 * * ?')).to eq('At 05 minutes past the hour')
  293 + end
  294 +
  295 + it 'every past the hour' do
  296 + expect(desc('0 0,5,10,15,20,25,30,35,40,45,50,55 * ? * *')).to eq(
  297 + 'At 00, 05, 10, 15, 20, 25, 30, 35, 40, 45, 50 and 55 minutes past the hour')
  298 + end
  299 +
  300 + it 'every X minutes past the hour with interval' do
  301 + expect(desc('0 0-30/2 17 ? * MON-FRI')).to eq(
  302 + 'Every 2 minutes, minutes 00 through 30 past the hour, at 5:00 PM, Monday through Friday')
  303 + end
  304 +
  305 + it 'every X days with interval' do
  306 + expect(desc('30 7 1-L/2 * *')).to eq('At 7:30 AM, every 2 days, between day 1 and the last day of the month')
  307 + end
  308 +
  309 + it 'one year only with seconds' do
  310 + expect(desc('* * * * * * 2013')).to eq('Every second, only in 2013')
  311 + end
  312 +
  313 + it 'one year only without seconds' do
  314 + expect(desc('* * * * * 2013')).to eq('Every minute, only in 2013')
  315 + end
  316 +
  317 + it 'two years only' do
  318 + expect(desc('* * * * * 2013,2014')).to eq('Every minute, only in 2013 and 2014')
  319 + end
  320 +
  321 + it 'year range 2' do
  322 + expect(desc('23 12 * JAN-FEB * 2013-2014')).to eq('At 12:23 PM, January through February, 2013 through 2014')
  323 + end
  324 +
  325 + it 'year range 3' do
  326 + expect(desc('23 12 * JAN-MAR * 2013-2015')).to eq('At 12:23 PM, January through March, 2013 through 2015')
  327 + end
  328 +
  329 + context 'multi part range seconds:' do
  330 + it 'multi part range seconds 2,4-5' do
  331 + expect(desc('2,4-5 1 * * *')).to eq('Minutes 02,04 through 05 past the hour, at 1:00 AM')
  332 + end
  333 +
  334 + it 'multi part range seconds 2,26-28' do
  335 + expect(desc('2,26-28 18 * * *')).to eq('Minutes 02,26 through 28 past the hour, at 6:00 PM')
  336 + end
  337 + end
  338 +
  339 + context 'minutes past the hour:' do
  340 + it 'minutes past the hour 5,10, midnight hour' do
  341 + expect(desc('5,10 0 * * *')).to eq('At 05 and 10 minutes past the hour, at 12:00 AM')
  342 + end
  343 +
  344 + it 'minutes past the hour 5,10' do
  345 + expect(desc('5,10 * * * *')).to eq('At 05 and 10 minutes past the hour')
  346 + end
  347 +
  348 + it 'minutes past the hour 5,10 day 2' do
  349 + expect(desc('5,10 * 2 * *')).to eq('At 05 and 10 minutes past the hour, on day 2 of the month')
  350 + end
  351 +
  352 + it 'minutes past the hour 5/10 day 2' do
  353 + expect(desc('5/10 * 2 * *')).to eq('Every 10 minutes, starting at 05 minutes past the hour, on day 2 of the month')
  354 + end
  355 + end
  356 +
  357 + context 'seconds past the minute:' do
  358 + it 'seconds past the minute 5,6, midnight hour' do
  359 + expect(desc('5,6 0 0 * * *')).to eq('At 5 and 6 seconds past the minute, at 12:00 AM')
  360 + end
  361 +
  362 + it 'seconds past the minute 5,6' do
  363 + expect(desc('5,6 0 * * * *')).to eq('At 5 and 6 seconds past the minute')
  364 + end
  365 +
  366 + it 'seconds past the minute 5,6 at 1' do
  367 + expect(desc('5,6 0 1 * * *')).to eq('At 5 and 6 seconds past the minute, at 1:00 AM')
  368 + end
  369 +
  370 + it 'seconds past the minute 5,6 day 2' do
  371 + expect(desc('5,6 0 * 2 * *')).to eq('At 5 and 6 seconds past the minute, on day 2 of the month')
  372 + end
  373 + end
  374 +
  375 + context 'increments starting at X > 1:' do
  376 + it 'second increments' do
  377 + expect(desc('5/15 0 * * * *')).to eq('Every 15 seconds, starting at 5 seconds past the minute')
  378 + end
  379 +
  380 + it 'minute increments' do
  381 + expect(desc('30/10 * * * *')).to eq('Every 10 minutes, starting at 30 minutes past the hour')
  382 + end
  383 +
  384 + it 'hour increments' do
  385 + expect(desc('0 30 2/6 * * ?')).to eq('At 30 minutes past the hour, every 6 hours, starting at 2:00 AM')
  386 + end
  387 +
  388 + it 'day of month increments' do
  389 + expect(desc('0 30 8 2/7 * *')).to eq('At 8:30 AM, every 7 days, starting on day 2 of the month')
  390 + end
  391 +
  392 + it 'day of week increments' do
  393 + expect(desc('0 30 11 * * 2/2')).to eq('At 11:30 AM, every 2 days of the week, starting on Tuesday')
  394 + end
  395 +
  396 + it 'month increments' do
  397 + expect(desc('0 20 10 * 2/3 THU')).to eq('At 10:20 AM, only on Thursday, every 3 months, starting in February')
  398 + end
  399 +
  400 + it 'year increments' do
  401 + expect(desc('0 0 0 1 MAR * 2010/5')).to eq('At 12:00 AM, on day 1 of the month, only in March, every 5 years, starting in 2010')
  402 + end
  403 + end
  404 +
  405 + context 'strict_quartz' do
  406 + it '5 part cron fails' do
  407 + expect { desc('* * * * *', strict_quartz: true) }.to raise_error(Cronex::ExpressionError)
  408 + end
  409 + end
  410 +
  411 + context 'timezone' do
  412 + it 'minute span' do
  413 + tz = TZInfo::Timezone.get('America/Los_Angeles')
  414 + hour = tz.period_for_local(Time.now).zone_identifier.to_s == 'PDT' ? 4 : 3
  415 + expect(desc('0-10 11 * * *', timezone: 'America/Los_Angeles')).to eq("Every minute between #{hour}:00 AM and #{hour}:10 AM")
  416 + end
  417 +
  418 + it 'twice a day' do
  419 + tz = TZInfo::Timezone.get('America/Los_Angeles')
  420 + hour = tz.period_for_local(Time.now).zone_identifier.to_s == 'PDT' ? 5 : 4
  421 + expect(desc('0 0,12 * * *', timezone: 'America/Los_Angeles')).to eq("At #{hour}:00 PM and #{hour}:00 AM")
  422 + end
  423 +
  424 + it 'ahead of GMT' do
  425 + tz = TZInfo::Timezone.get('Europe/Vienna')
  426 + hour = tz.period_for_local(Time.now).zone_identifier.to_s == 'CEST' ? 1 : 12
  427 + expect(desc('0-10 11 * * *', timezone: 'Europe/Vienna')).to eq("Every minute between #{hour}:00 PM and #{hour}:10 PM")
  428 + end
  429 + end
  430 + end
  431 +end
... ...
spec/exp_descriptor_fr_spec.rb 0 → 100644
  1 +++ a/spec/exp_descriptor_fr_spec.rb
... ... @@ -0,0 +1,405 @@
  1 +# encoding: utf-8
  2 +require 'cronex'
  3 +
  4 +module Cronex
  5 + describe ExpressionDescriptor do
  6 +
  7 + def desc(expression, opts = {})
  8 + opts[:locale] = 'fr'
  9 + Cronex::ExpressionDescriptor.new(expression, opts).description
  10 + end
  11 +
  12 + let(:opts) { { zero_based_dow: false } }
  13 +
  14 + it 'every second' do
  15 + expect(desc('* * * * * *')).to eq('Chaque seconde')
  16 + end
  17 +
  18 + it 'every 45 seconds' do
  19 + expect(desc('*/45 * * * * *')).to eq('Toutes les 45 secondes')
  20 + end
  21 +
  22 + it 'minute span' do
  23 + expect(desc('0-10 11 * * *')).to eq('Chaque minute entre 11:00 AM et 11:10 AM')
  24 + end
  25 +
  26 + context 'every minute' do
  27 + it 'every minute' do
  28 + expect(desc('* * * * *')).to eq('Chaque minute')
  29 + end
  30 +
  31 + it 'every minute */1' do
  32 + expect(desc('*/1 * * * *')).to eq('Chaque minute')
  33 + end
  34 +
  35 + it 'every minute 0 0/1' do
  36 + expect(desc('0 0/1 * * * ?')).to eq('Chaque minute')
  37 + end
  38 + end
  39 +
  40 + context 'every X minutes:' do
  41 + it 'every 5 minutes' do
  42 + expect(desc('*/5 * * * *')).to eq('Tous les 5 minutes')
  43 + end
  44 +
  45 + it 'every 5 minutes at Midnight' do
  46 + expect(desc('*/5 0 * * *')).to eq('Tous les 5 minutes, à 12:00 AM')
  47 + end
  48 +
  49 + it 'every 5 minutes 0 */5' do
  50 + expect(desc('0 */5 * * * *')).to eq('Tous les 5 minutes')
  51 + end
  52 +
  53 + it 'every 10 minutes 0 0/10' do
  54 + expect(desc('0 0/10 * * * ?')).to eq('Tous les 10 minutes')
  55 + end
  56 + end
  57 +
  58 + context 'every hour:' do
  59 + it 'every hour 0 0' do
  60 + expect(desc('0 0 * * * ?')).to eq('Chaque heure')
  61 + end
  62 +
  63 + it 'every hour 0 0 0/1' do
  64 + expect(desc('0 0 0/1 * * ?')).to eq('Chaque heure')
  65 + end
  66 + end
  67 +
  68 + context 'daily:' do
  69 + it 'daily at /\d\d/:/\d\d/' do
  70 + expect(desc('30 11 * * *')).to eq('À 11:30 AM')
  71 + end
  72 +
  73 + it 'daily at /\d/:/\d/' do
  74 + expect(desc('9 8 * * *')).to eq('À 8:09 AM')
  75 + end
  76 +
  77 + it 'daily at /0[89]/:/0[89]/' do
  78 + expect(desc('09 08 * * *')).to eq('À 8:09 AM')
  79 + end
  80 +
  81 + it 'daily at /0[1-7]/ /0[1-7/' do
  82 + expect(desc('02 01 * * *')).to eq('À 1:02 AM')
  83 + end
  84 + end
  85 +
  86 + context 'time of day certain days of week:' do
  87 + it 'time of day on MON-FRI' do
  88 + expect(desc('0 23 ? * MON-FRI')).to eq('À 11:00 PM, lundi à vendredi')
  89 + end
  90 +
  91 + it 'time of day on 1-5' do
  92 + expect(desc('30 11 * * 1-5')).to eq('À 11:30 AM, lundi à vendredi')
  93 + end
  94 + end
  95 +
  96 + it 'one month only' do
  97 + expect(desc('* * * 3 *')).to eq('Chaque minute, seulement en mars')
  98 + end
  99 +
  100 + it 'two months only' do
  101 + expect(desc('* * * 3,6 *')).to eq("Chaque minute, seulement en mars et juin")
  102 + end
  103 +
  104 + it 'two times each afternoon' do
  105 + expect(desc('30 14,16 * * *')).to eq("À 2:30 PM et 4:30 PM")
  106 + end
  107 +
  108 + it 'three times daily' do
  109 + expect(desc('30 6,14,16 * * *')).to eq('À 6:30 AM, 2:30 PM et 4:30 PM')
  110 + end
  111 +
  112 + context 'once a week:' do
  113 + it 'once a week 0' do
  114 + expect(desc('46 9 * * 0')).to eq('À 9:46 AM, seulement le dimanche')
  115 + end
  116 +
  117 + it 'once a week SUN' do
  118 + expect(desc('46 9 * * SUN')).to eq('À 9:46 AM, seulement le dimanche')
  119 + end
  120 +
  121 + it 'once a week 7' do
  122 + expect(desc('46 9 * * 7')).to eq('À 9:46 AM, seulement le dimanche')
  123 + end
  124 +
  125 + it 'once a week 1' do
  126 + expect(desc('46 9 * * 1')).to eq('À 9:46 AM, seulement le lundi')
  127 + end
  128 +
  129 + it 'once a week 6' do
  130 + expect(desc('46 9 * * 6')).to eq('À 9:46 AM, seulement le samedi')
  131 + end
  132 + end
  133 +
  134 + context 'once a week non zero based:' do
  135 + it 'once a week 1' do
  136 + expect(desc('46 9 * * 1', opts)).to eq('À 9:46 AM, seulement le dimanche')
  137 + end
  138 +
  139 + it 'once a week SUN' do
  140 + expect(desc('46 9 * * SUN', opts)).to eq('À 9:46 AM, seulement le dimanche')
  141 + end
  142 +
  143 + it 'once a week 2' do
  144 + expect(desc('46 9 * * 2', opts)).to eq('À 9:46 AM, seulement le lundi')
  145 + end
  146 +
  147 + it 'once a week 7' do
  148 + expect(desc('46 9 * * 7', opts)).to eq('À 9:46 AM, seulement le samedi')
  149 + end
  150 + end
  151 +
  152 + context 'twice a week:' do
  153 + it 'twice a week 1,2' do
  154 + expect(desc('46 9 * * 1,2')).to eq('À 9:46 AM, seulement le lundi et mardi')
  155 + end
  156 +
  157 + it 'twice a week MON,TUE' do
  158 + expect(desc('46 9 * * MON,TUE')).to eq('À 9:46 AM, seulement le lundi et mardi')
  159 + end
  160 +
  161 + it 'twice a week 0,6' do
  162 + expect(desc('46 9 * * 0,6')).to eq('À 9:46 AM, seulement le dimanche et samedi')
  163 + end
  164 +
  165 + it 'twice a week 6,7' do
  166 + expect(desc('46 9 * * 6,7')).to eq('À 9:46 AM, seulement le samedi et dimanche')
  167 + end
  168 + end
  169 +
  170 + context 'twice a week non zero based:' do
  171 + it 'twice a week 1,2' do
  172 + expect(desc('46 9 * * 1,2', opts)).to eq('À 9:46 AM, seulement le dimanche et lundi')
  173 + end
  174 +
  175 + it 'twice a week SUN,MON' do
  176 + expect(desc('46 9 * * SUN,MON', opts)).to eq('À 9:46 AM, seulement le dimanche et lundi')
  177 + end
  178 +
  179 + it 'twice a week 6,7' do
  180 + expect(desc('46 9 * * 6,7', opts)).to eq('À 9:46 AM, seulement le vendredi et samedi')
  181 + end
  182 + end
  183 +
  184 + it 'day of month' do
  185 + expect(desc('23 12 15 * *')).to eq('À 12:23 PM, le 15 de chaque mois')
  186 + end
  187 +
  188 + it 'day of month with day of week' do
  189 + expect(desc('23 12 15 * SUN')).to eq('À 12:23 PM, le 15 de chaque mois, seulement le dimanche')
  190 + end
  191 +
  192 + it 'month name' do
  193 + expect(desc('23 12 * JAN *')).to eq('À 12:23 PM, seulement en janvier')
  194 + end
  195 +
  196 + it 'day of month with question mark' do
  197 + expect(desc('23 12 ? JAN *')).to eq('À 12:23 PM, seulement en janvier')
  198 + end
  199 +
  200 + it 'month name range 2' do
  201 + expect(desc('23 12 * JAN-FEB *')).to eq('À 12:23 PM, janvier à février')
  202 + end
  203 +
  204 + it 'month name range 3' do
  205 + expect(desc('23 12 * JAN-MAR *')).to eq('À 12:23 PM, janvier à mars')
  206 + end
  207 +
  208 + it 'day of week name' do
  209 + expect(desc('23 12 * * SUN')).to eq('À 12:23 PM, seulement le dimanche')
  210 + end
  211 +
  212 + context 'day of week range:' do
  213 + it 'day of week range MON-FRI' do
  214 + expect(desc('*/5 15 * * MON-FRI')).to eq('Tous les 5 minutes, à 3:00 PM, lundi à vendredi')
  215 + end
  216 +
  217 + it 'day of week range 0-6' do
  218 + expect(desc('*/5 15 * * 0-6')).to eq('Tous les 5 minutes, à 3:00 PM, dimanche à samedi')
  219 + end
  220 +
  221 + it 'day of week range 6-7' do
  222 + expect(desc('*/5 15 * * 6-7')).to eq('Tous les 5 minutes, à 3:00 PM, samedi à dimanche')
  223 + end
  224 + end
  225 +
  226 + context 'day of week once in month:' do
  227 + it 'day of week once MON#3' do
  228 + expect(desc('* * * * MON#3')).to eq('Chaque minute, le troisième lundi du mois')
  229 + end
  230 +
  231 + it 'day of week once 0#3' do
  232 + expect(desc('* * * * 0#3')).to eq('Chaque minute, le troisième dimanche du mois')
  233 + end
  234 + end
  235 +
  236 + context 'last day of week of the month:' do
  237 + it 'last day of week 4L' do
  238 + expect(desc('* * * * 4L')).to eq('Chaque minute, le dernier jeudi du mois')
  239 + end
  240 +
  241 + it 'last day of week 0L' do
  242 + expect(desc('* * * * 0L')).to eq('Chaque minute, le dernier dimanche du mois')
  243 + end
  244 + end
  245 +
  246 + context 'last day of the month:' do
  247 + it 'on the last day of the month' do
  248 + expect(desc('*/5 * L JAN *')).to eq('Tous les 5 minutes, le dernier jour du mois, seulement en janvier')
  249 + end
  250 +
  251 + it 'between a day and last day of the month' do
  252 + expect(desc('*/5 * 23-L JAN *')).to eq('Tous les 5 minutes, entre le jour 23 et le dernier jour du mois, seulement en janvier')
  253 + end
  254 + end
  255 +
  256 + it 'time of day with seconds' do
  257 + expect(desc('30 02 14 * * *')).to eq('À 2:02:30 PM')
  258 + end
  259 +
  260 + it 'second intervals' do
  261 + expect(desc('5-10 * * * * *')).to eq('Secondes 5 à 10 après la minute')
  262 + end
  263 +
  264 + it 'second minutes hours intervals' do
  265 + expect(desc('5-10 30-35 10-12 * * *')).to eq(
  266 + "Secondes 5 à 10 après la minute, minutes 30 à 35 après l'heure, entre 10:00 AM et 12:59 PM")
  267 + end
  268 +
  269 + it 'every 5 minutes at 30 seconds' do
  270 + expect(desc('30 */5 * * * *')).to eq('À 30 secondes après la minute, tous les 5 minutes')
  271 + end
  272 +
  273 + it 'minutes past the hour range' do
  274 + expect(desc('0 30 10-13 ? * WED,FRI')).to eq(
  275 + "À 30 minutes après l'heure, entre 10:00 AM et 1:59 PM, seulement le mercredi et vendredi")
  276 + end
  277 +
  278 + it 'seconds past the minute interval' do
  279 + expect(desc('10 0/5 * * * ?')).to eq('À 10 secondes après la minute, tous les 5 minutes')
  280 + end
  281 +
  282 + it 'between with interval' do
  283 + expect(desc('2-59/3 1,9,22 11-26 1-6 ?')).to eq(
  284 + "Tous les 3 minutes, minutes 02 à 59 après l'heure, à 1:00 AM, 9:00 AM et 10:00 PM, entre le jour 11 et le 26 du mois, janvier à juin")
  285 + end
  286 +
  287 + it 'recurring first of month' do
  288 + expect(desc('0 0 6 1/1 * ?')).to eq('À 6:00 AM')
  289 + end
  290 +
  291 + it 'minutes past the hour' do
  292 + expect(desc('0 5 0/1 * * ?')).to eq("À 05 minutes après l'heure")
  293 + end
  294 +
  295 + it 'every past the hour' do
  296 + expect(desc('0 0,5,10,15,20,25,30,35,40,45,50,55 * ? * *')).to eq(
  297 + "À 00, 05, 10, 15, 20, 25, 30, 35, 40, 45, 50 et 55 minutes après l'heure")
  298 + end
  299 +
  300 + it 'every X minutes past the hour with interval' do
  301 + expect(desc('0 0-30/2 17 ? * MON-FRI')).to eq(
  302 + "Tous les 2 minutes, minutes 00 à 30 après l'heure, à 5:00 PM, lundi à vendredi")
  303 + end
  304 +
  305 + it 'every X days with interval' do
  306 + expect(desc('30 7 1-L/2 * *')).to eq('À 7:30 AM, tous les 2 jours, entre le jour 1 et le dernier jour du mois')
  307 + end
  308 +
  309 + it 'one year only with seconds' do
  310 + expect(desc('* * * * * * 2013')).to eq('Chaque seconde, seulement en 2013')
  311 + end
  312 +
  313 + it 'one year only without seconds' do
  314 + expect(desc('* * * * * 2013')).to eq('Chaque minute, seulement en 2013')
  315 + end
  316 +
  317 + it 'two years only' do
  318 + expect(desc('* * * * * 2013,2014')).to eq('Chaque minute, seulement en 2013 et 2014')
  319 + end
  320 +
  321 + it 'year range 2' do
  322 + expect(desc('23 12 * JAN-FEB * 2013-2014')).to eq('À 12:23 PM, janvier à février, 2013 à 2014')
  323 + end
  324 +
  325 + it 'year range 3' do
  326 + expect(desc('23 12 * JAN-MAR * 2013-2015')).to eq('À 12:23 PM, janvier à mars, 2013 à 2015')
  327 + end
  328 +
  329 + context 'multi part range seconds:' do
  330 + it 'multi part range seconds 2,4-5' do
  331 + expect(desc('2,4-5 1 * * *')).to eq("Minutes 02,04 à 05 après l'heure, à 1:00 AM")
  332 + end
  333 +
  334 + it 'multi part range seconds 2,26-28' do
  335 + expect(desc('2,26-28 18 * * *')).to eq("Minutes 02,26 à 28 après l'heure, à 6:00 PM")
  336 + end
  337 + end
  338 +
  339 + context 'minutes past the hour:' do
  340 + it 'minutes past the hour 5,10, midnight hour' do
  341 + expect(desc('5,10 0 * * *')).to eq("À 05 et 10 minutes après l'heure, à 12:00 AM")
  342 + end
  343 +
  344 + it 'minutes past the hour 5,10' do
  345 + expect(desc('5,10 * * * *')).to eq("À 05 et 10 minutes après l'heure")
  346 + end
  347 +
  348 + it 'minutes past the hour 5,10 day 2' do
  349 + expect(desc('5,10 * 2 * *')).to eq("À 05 et 10 minutes après l'heure, le 2 de chaque mois")
  350 + end
  351 +
  352 + it 'minutes past the hour 5/10 day 2' do
  353 + expect(desc('5/10 * 2 * *')).to eq("Tous les 10 minutes, commence à 05 minutes après l'heure, le 2 de chaque mois")
  354 + end
  355 + end
  356 +
  357 + context 'seconds past the minute:' do
  358 + it 'seconds past the minute 5,6, midnight hour' do
  359 + expect(desc('5,6 0 0 * * *')).to eq('À 5 et 6 secondes après la minute, à 12:00 AM')
  360 + end
  361 +
  362 + it 'seconds past the minute 5,6' do
  363 + expect(desc('5,6 0 * * * *')).to eq('À 5 et 6 secondes après la minute')
  364 + end
  365 +
  366 + it 'seconds past the minute 5,6 at 1' do
  367 + expect(desc('5,6 0 1 * * *')).to eq('À 5 et 6 secondes après la minute, à 1:00 AM')
  368 + end
  369 +
  370 + it 'seconds past the minute 5,6 day 2' do
  371 + expect(desc('5,6 0 * 2 * *')).to eq('À 5 et 6 secondes après la minute, le 2 de chaque mois')
  372 + end
  373 + end
  374 +
  375 + context 'increments starting at X > 1:' do
  376 + it 'second increments' do
  377 + expect(desc('5/15 0 * * * *')).to eq("Toutes les 15 secondes, commence à 5 secondes après la minute")
  378 + end
  379 +
  380 + it 'minute increments' do
  381 + expect(desc('30/10 * * * *')).to eq("Tous les 10 minutes, commence à 30 minutes après l'heure")
  382 + end
  383 +
  384 + it 'hour increments' do
  385 + expect(desc('0 30 2/6 * * ?')).to eq("À 30 minutes après l'heure, tous les 6 heures, commence à 2:00 AM")
  386 + end
  387 +
  388 + it 'day of month increments' do
  389 + expect(desc('0 30 8 2/7 * *')).to eq('À 8:30 AM, tous les 7 jours, commence le 2 de chaque mois')
  390 + end
  391 +
  392 + it 'day of week increments' do
  393 + expect(desc('0 30 11 * * 2/2')).to eq('À 11:30 AM, tous les 2 jours de la semaine, commence le mardi')
  394 + end
  395 +
  396 + it 'month increments' do
  397 + expect(desc('0 20 10 * 2/3 THU')).to eq('À 10:20 AM, seulement le jeudi, tous les 3 mois, commence en février')
  398 + end
  399 +
  400 + it 'year increments' do
  401 + expect(desc('0 0 0 1 MAR * 2010/5')).to eq('À 12:00 AM, le 1 de chaque mois, seulement en mars, tous les 5 ans, commence en 2010')
  402 + end
  403 + end
  404 + end
  405 +end
... ...
spec/exp_descriptor_it_spec.rb 0 → 100644
  1 +++ a/spec/exp_descriptor_it_spec.rb
... ... @@ -0,0 +1,405 @@
  1 +# encoding: utf-8
  2 +require 'cronex'
  3 +
  4 +module Cronex
  5 + describe ExpressionDescriptor do
  6 +
  7 + def desc(expression, opts = {})
  8 + opts[:locale] = 'it'
  9 + Cronex::ExpressionDescriptor.new(expression, opts).description
  10 + end
  11 +
  12 + let(:opts) { { zero_based_dow: false } }
  13 +
  14 + it 'every second' do
  15 + expect(desc('* * * * * *')).to eq('Ogni secondo')
  16 + end
  17 +
  18 + it 'every 45 seconds' do
  19 + expect(desc('*/45 * * * * *')).to eq('Ogni 45 secondi')
  20 + end
  21 +
  22 + it 'minute span' do
  23 + expect(desc('0-10 11 * * *')).to eq('Ogni minuto tra le 11:00 AM e le 11:10 AM')
  24 + end
  25 +
  26 + context 'every minute' do
  27 + it 'every minute' do
  28 + expect(desc('* * * * *')).to eq('Ogni minuto')
  29 + end
  30 +
  31 + it 'every minute */1' do
  32 + expect(desc('*/1 * * * *')).to eq('Ogni minuto')
  33 + end
  34 +
  35 + it 'every minute 0 0/1' do
  36 + expect(desc('0 0/1 * * * ?')).to eq('Ogni minuto')
  37 + end
  38 + end
  39 +
  40 + context 'every X minutes:' do
  41 + it 'every 5 minuti' do
  42 + expect(desc('*/5 * * * *')).to eq('Ogni 5 minuti')
  43 + end
  44 +
  45 + it 'every 5 minutes at Midnight' do
  46 + expect(desc('*/5 0 * * *')).to eq('Ogni 5 minuti, alle(ai) 12:00 AM')
  47 + end
  48 +
  49 + it 'every 5 minutes 0 */5' do
  50 + expect(desc('0 */5 * * * *')).to eq('Ogni 5 minuti')
  51 + end
  52 +
  53 + it 'every 10 minutes 0 0/10' do
  54 + expect(desc('0 0/10 * * * ?')).to eq('Ogni 10 minuti')
  55 + end
  56 + end
  57 +
  58 + context 'every hour:' do
  59 + it 'every hour 0 0' do
  60 + expect(desc('0 0 * * * ?')).to eq('Ogni ora')
  61 + end
  62 +
  63 + it 'every hour 0 0 0/1' do
  64 + expect(desc('0 0 0/1 * * ?')).to eq('Ogni ora')
  65 + end
  66 + end
  67 +
  68 + context 'daily:' do
  69 + it 'daily at /\d\d/:/\d\d/' do
  70 + expect(desc('30 11 * * *')).to eq('Alle(ai) 11:30 AM')
  71 + end
  72 +
  73 + it 'daily at /\d/:/\d/' do
  74 + expect(desc('9 8 * * *')).to eq('Alle(ai) 8:09 AM')
  75 + end
  76 +
  77 + it 'daily at /0[89]/:/0[89]/' do
  78 + expect(desc('09 08 * * *')).to eq('Alle(ai) 8:09 AM')
  79 + end
  80 +
  81 + it 'daily at /0[1-7]/ /0[1-7/' do
  82 + expect(desc('02 01 * * *')).to eq('Alle(ai) 1:02 AM')
  83 + end
  84 + end
  85 +
  86 + context 'time of day certain days of week:' do
  87 + it 'time of day on MON-FRI' do
  88 + expect(desc('0 23 ? * MON-FRI')).to eq('Alle(ai) 11:00 PM, da lunedì a venerdì')
  89 + end
  90 +
  91 + it 'time of day on 1-5' do
  92 + expect(desc('30 11 * * 1-5')).to eq('Alle(ai) 11:30 AM, da lunedì a venerdì')
  93 + end
  94 + end
  95 +
  96 + it 'one month only' do
  97 + expect(desc('* * * 3 *')).to eq('Ogni minuto, solo a(nel) marzo')
  98 + end
  99 +
  100 + it 'two months only' do
  101 + expect(desc('* * * 3,6 *')).to eq('Ogni minuto, solo a(nel) marzo e giugno')
  102 + end
  103 +
  104 + it 'two times each afternoon' do
  105 + expect(desc('30 14,16 * * *')).to eq('Alle(ai) 2:30 PM e 4:30 PM')
  106 + end
  107 +
  108 + it 'three times daily' do
  109 + expect(desc('30 6,14,16 * * *')).to eq('Alle(ai) 6:30 AM, 2:30 PM e 4:30 PM')
  110 + end
  111 +
  112 + context 'once a week:' do
  113 + it 'once a week 0' do
  114 + expect(desc('46 9 * * 0')).to eq('Alle(ai) 9:46 AM, solo di domenica')
  115 + end
  116 +
  117 + it 'once a week SUN' do
  118 + expect(desc('46 9 * * SUN')).to eq('Alle(ai) 9:46 AM, solo di domenica')
  119 + end
  120 +
  121 + it 'once a week 7' do
  122 + expect(desc('46 9 * * 7')).to eq('Alle(ai) 9:46 AM, solo di domenica')
  123 + end
  124 +
  125 + it 'once a week 1' do
  126 + expect(desc('46 9 * * 1')).to eq('Alle(ai) 9:46 AM, solo di lunedì')
  127 + end
  128 +
  129 + it 'once a week 6' do
  130 + expect(desc('46 9 * * 6')).to eq('Alle(ai) 9:46 AM, solo di sabato')
  131 + end
  132 + end
  133 +
  134 + context 'once a week non zero based:' do
  135 + it 'once a week 1' do
  136 + expect(desc('46 9 * * 1', opts)).to eq('Alle(ai) 9:46 AM, solo di domenica')
  137 + end
  138 +
  139 + it 'once a week SUN' do
  140 + expect(desc('46 9 * * SUN', opts)).to eq('Alle(ai) 9:46 AM, solo di domenica')
  141 + end
  142 +
  143 + it 'once a week 2' do
  144 + expect(desc('46 9 * * 2', opts)).to eq('Alle(ai) 9:46 AM, solo di lunedì')
  145 + end
  146 +
  147 + it 'once a week 7' do
  148 + expect(desc('46 9 * * 7', opts)).to eq('Alle(ai) 9:46 AM, solo di sabato')
  149 + end
  150 + end
  151 +
  152 + context 'twice a week:' do
  153 + it 'twice a week 1,2' do
  154 + expect(desc('46 9 * * 1,2')).to eq('Alle(ai) 9:46 AM, solo di lunedì e martedì')
  155 + end
  156 +
  157 + it 'twice a week MON,TUE' do
  158 + expect(desc('46 9 * * MON,TUE')).to eq('Alle(ai) 9:46 AM, solo di lunedì e martedì')
  159 + end
  160 +
  161 + it 'twice a week 0,6' do
  162 + expect(desc('46 9 * * 0,6')).to eq('Alle(ai) 9:46 AM, solo di domenica e sabato')
  163 + end
  164 +
  165 + it 'twice a week 6,7' do
  166 + expect(desc('46 9 * * 6,7')).to eq('Alle(ai) 9:46 AM, solo di sabato e domenica')
  167 + end
  168 + end
  169 +
  170 + context 'twice a week non zero based:' do
  171 + it 'twice a week 1,2' do
  172 + expect(desc('46 9 * * 1,2', opts)).to eq('Alle(ai) 9:46 AM, solo di domenica e lunedì')
  173 + end
  174 +
  175 + it 'twice a week SUN,MON' do
  176 + expect(desc('46 9 * * SUN,MON', opts)).to eq('Alle(ai) 9:46 AM, solo di domenica e lunedì')
  177 + end
  178 +
  179 + it 'twice a week 6,7' do
  180 + expect(desc('46 9 * * 6,7', opts)).to eq('Alle(ai) 9:46 AM, solo di venerdì e sabato')
  181 + end
  182 + end
  183 +
  184 + it 'day of month' do
  185 + expect(desc('23 12 15 * *')).to eq('Alle(ai) 12:23 PM, il giorno 15 del mese')
  186 + end
  187 +
  188 + it 'day of month with day of week' do
  189 + expect(desc('23 12 15 * SUN')).to eq('Alle(ai) 12:23 PM, il giorno 15 del mese, solo di domenica')
  190 + end
  191 +
  192 + it 'month name' do
  193 + expect(desc('23 12 * JAN *')).to eq('Alle(ai) 12:23 PM, solo a(nel) gennaio')
  194 + end
  195 +
  196 + it 'day of month with question mark' do
  197 + expect(desc('23 12 ? JAN *')).to eq('Alle(ai) 12:23 PM, solo a(nel) gennaio')
  198 + end
  199 +
  200 + it 'month name range 2' do
  201 + expect(desc('23 12 * JAN-FEB *')).to eq('Alle(ai) 12:23 PM, da gennaio a febbraio')
  202 + end
  203 +
  204 + it 'month name range 3' do
  205 + expect(desc('23 12 * JAN-MAR *')).to eq('Alle(ai) 12:23 PM, da gennaio a marzo')
  206 + end
  207 +
  208 + it 'day of week name' do
  209 + expect(desc('23 12 * * SUN')).to eq('Alle(ai) 12:23 PM, solo di domenica')
  210 + end
  211 +
  212 + context 'day of week range:' do
  213 + it 'day of week range MON-FRI' do
  214 + expect(desc('*/5 15 * * MON-FRI')).to eq('Ogni 5 minuti, alle(ai) 3:00 PM, da lunedì a venerdì')
  215 + end
  216 +
  217 + it 'day of week range 0-6' do
  218 + expect(desc('*/5 15 * * 0-6')).to eq('Ogni 5 minuti, alle(ai) 3:00 PM, da domenica a sabato')
  219 + end
  220 +
  221 + it 'day of week range 6-7' do
  222 + expect(desc('*/5 15 * * 6-7')).to eq('Ogni 5 minuti, alle(ai) 3:00 PM, da sabato a domenica')
  223 + end
  224 + end
  225 +
  226 + context 'day of week once in month:' do
  227 + it 'day of week once MON#3' do
  228 + expect(desc('* * * * MON#3')).to eq('Ogni minuto, il(la) terzo(a) lunedì del mese')
  229 + end
  230 +
  231 + it 'day of week once 0#3' do
  232 + expect(desc('* * * * 0#3')).to eq('Ogni minuto, il(la) terzo(a) domenica del mese')
  233 + end
  234 + end
  235 +
  236 + context 'last day of week del mese:' do
  237 + it 'last day of week 4L' do
  238 + expect(desc('* * * * 4L')).to eq('Ogni minuto, l\'ultimo(a) giovedì del mese')
  239 + end
  240 +
  241 + it 'last day of week 0L' do
  242 + expect(desc('* * * * 0L')).to eq('Ogni minuto, l\'ultimo(a) domenica del mese')
  243 + end
  244 + end
  245 +
  246 + context 'last day of the month:' do
  247 + it 'on the last day of the month' do
  248 + expect(desc('*/5 * L JAN *')).to eq('Ogni 5 minuti, l\'ultimo giorno del mese, solo a(nel) gennaio')
  249 + end
  250 +
  251 + it 'between a day and last day of the month' do
  252 + expect(desc('*/5 * 23-L JAN *')).to eq('Ogni 5 minuti, tra il giorno 23 e il ultimo giorno del mese, solo a(nel) gennaio')
  253 + end
  254 + end
  255 +
  256 + it 'time of day with seconds' do
  257 + expect(desc('30 02 14 * * *')).to eq('Alle(ai) 2:02:30 PM')
  258 + end
  259 +
  260 + it 'second intervals' do
  261 + expect(desc('5-10 * * * * *')).to eq('Dal secondo 5 al 10 dopo il minuto')
  262 + end
  263 +
  264 + it 'second minutes hours intervals' do
  265 + expect(desc('5-10 30-35 10-12 * * *')).to eq(
  266 + 'Dal secondo 5 al 10 dopo il minuto, dal minuto 30 al 35 dopo l\'ora, tra le 10:00 AM e le 12:59 PM')
  267 + end
  268 +
  269 + it 'every 5 minutes at 30 seconds' do
  270 + expect(desc('30 */5 * * * *')).to eq('A 30 secondi dopo il minuto, ogni 5 minuti')
  271 + end
  272 +
  273 + it 'minutes past the hour range' do
  274 + expect(desc('0 30 10-13 ? * WED,FRI')).to eq(
  275 + 'Alle(ai) 30 minuti dopo l\'ora, tra le 10:00 AM e le 1:59 PM, solo di mercoledì e venerdì')
  276 + end
  277 +
  278 + it 'seconds past the minute interval' do
  279 + expect(desc('10 0/5 * * * ?')).to eq('A 10 secondi dopo il minuto, ogni 5 minuti')
  280 + end
  281 +
  282 + it 'between with interval' do
  283 + expect(desc('2-59/3 1,9,22 11-26 1-6 ?')).to eq(
  284 + 'Ogni 3 minuti, dal minuto 02 al 59 dopo l\'ora, alle(ai) 1:00 AM, 9:00 AM e 10:00 PM, tra il giorno 11 e il 26 del mese, da gennaio a giugno')
  285 + end
  286 +
  287 + it 'recurring first of month' do
  288 + expect(desc('0 0 6 1/1 * ?')).to eq('Alle(ai) 6:00 AM')
  289 + end
  290 +
  291 + it 'minutes past the hour' do
  292 + expect(desc('0 5 0/1 * * ?')).to eq('Alle(ai) 05 minuti dopo l\'ora')
  293 + end
  294 +
  295 + it 'every past the hour' do
  296 + expect(desc('0 0,5,10,15,20,25,30,35,40,45,50,55 * ? * *')).to eq(
  297 + 'Alle(ai) 00, 05, 10, 15, 20, 25, 30, 35, 40, 45, 50 e 55 minuti dopo l\'ora')
  298 + end
  299 +
  300 + it 'every X minutes past the hour with interval' do
  301 + expect(desc('0 0-30/2 17 ? * MON-FRI')).to eq(
  302 + 'Ogni 2 minuti, dal minuto 00 al 30 dopo l\'ora, alle(ai) 5:00 PM, da lunedì a venerdì')
  303 + end
  304 +
  305 + it 'every X days with interval' do
  306 + expect(desc('30 7 1-L/2 * *')).to eq('Alle(ai) 7:30 AM, ogni 2 giorni, tra il giorno 1 e il ultimo giorno del mese')
  307 + end
  308 +
  309 + it 'one year only with seconds' do
  310 + expect(desc('* * * * * * 2013')).to eq('Ogni secondo, solo a(nel) 2013')
  311 + end
  312 +
  313 + it 'one year only without seconds' do
  314 + expect(desc('* * * * * 2013')).to eq('Ogni minuto, solo a(nel) 2013')
  315 + end
  316 +
  317 + it 'two years only' do
  318 + expect(desc('* * * * * 2013,2014')).to eq('Ogni minuto, solo a(nel) 2013 e 2014')
  319 + end
  320 +
  321 + it 'year range 2' do
  322 + expect(desc('23 12 * JAN-FEB * 2013-2014')).to eq('Alle(ai) 12:23 PM, da gennaio a febbraio, da 2013 a 2014')
  323 + end
  324 +
  325 + it 'year range 3' do
  326 + expect(desc('23 12 * JAN-MAR * 2013-2015')).to eq('Alle(ai) 12:23 PM, da gennaio a marzo, da 2013 a 2015')
  327 + end
  328 +
  329 + context 'multi part range seconds:' do
  330 + it 'multi part range seconds 2,4-5' do
  331 + expect(desc('2,4-5 1 * * *')).to eq('Dal minuto 02,04 al 05 dopo l\'ora, alle(ai) 1:00 AM')
  332 + end
  333 +
  334 + it 'multi part range seconds 2,26-28' do
  335 + expect(desc('2,26-28 18 * * *')).to eq('Dal minuto 02,26 al 28 dopo l\'ora, alle(ai) 6:00 PM')
  336 + end
  337 + end
  338 +
  339 + context 'minutes past the hour:' do
  340 + it 'minutes past the hour 5,10, midnight hour' do
  341 + expect(desc('5,10 0 * * *')).to eq('Alle(ai) 05 e 10 minuti dopo l\'ora, alle(ai) 12:00 AM')
  342 + end
  343 +
  344 + it 'minutes past the hour 5,10' do
  345 + expect(desc('5,10 * * * *')).to eq('Alle(ai) 05 e 10 minuti dopo l\'ora')
  346 + end
  347 +
  348 + it 'minutes past the hour 5,10 day 2' do
  349 + expect(desc('5,10 * 2 * *')).to eq('Alle(ai) 05 e 10 minuti dopo l\'ora, il giorno 2 del mese')
  350 + end
  351 +
  352 + it 'minutes past the hour 5/10 day 2' do
  353 + expect(desc('5/10 * 2 * *')).to eq('Ogni 10 minuti, a partire da alle(ai) 05 minuti dopo l\'ora, il giorno 2 del mese')
  354 + end
  355 + end
  356 +
  357 + context 'seconds past the minute:' do
  358 + it 'seconds past the minute 5,6, midnight hour' do
  359 + expect(desc('5,6 0 0 * * *')).to eq('A 5 e 6 secondi dopo il minuto, alle(ai) 12:00 AM')
  360 + end
  361 +
  362 + it 'seconds past the minute 5,6' do
  363 + expect(desc('5,6 0 * * * *')).to eq('A 5 e 6 secondi dopo il minuto')
  364 + end
  365 +
  366 + it 'seconds past the minute 5,6 at 1' do
  367 + expect(desc('5,6 0 1 * * *')).to eq('A 5 e 6 secondi dopo il minuto, alle(ai) 1:00 AM')
  368 + end
  369 +
  370 + it 'seconds past the minute 5,6 day 2' do
  371 + expect(desc('5,6 0 * 2 * *')).to eq('A 5 e 6 secondi dopo il minuto, il giorno 2 del mese')
  372 + end
  373 + end
  374 +
  375 + context 'increments starting at X > 1:' do
  376 + it 'second increments' do
  377 + expect(desc('5/15 0 * * * *')).to eq('Ogni 15 secondi, a partire da a 5 secondi dopo il minuto')
  378 + end
  379 +
  380 + it 'minute increments' do
  381 + expect(desc('30/10 * * * *')).to eq('Ogni 10 minuti, a partire da alle(ai) 30 minuti dopo l\'ora')
  382 + end
  383 +
  384 + it 'hour increments' do
  385 + expect(desc('0 30 2/6 * * ?')).to eq('Alle(ai) 30 minuti dopo l\'ora, ogni 6 ore, a partire da alle(ai) 2:00 AM')
  386 + end
  387 +
  388 + it 'day of month increments' do
  389 + expect(desc('0 30 8 2/7 * *')).to eq('Alle(ai) 8:30 AM, ogni 7 giorni, a partire da il giorno 2 del mese')
  390 + end
  391 +
  392 + it 'day of week increments' do
  393 + expect(desc('0 30 11 * * 2/2')).to eq('Alle(ai) 11:30 AM, 2 giorni alla settimana, a partire da il martedì')
  394 + end
  395 +
  396 + it 'month increments' do
  397 + expect(desc('0 20 10 * 2/3 THU')).to eq('Alle(ai) 10:20 AM, solo di giovedì, ogni 3 mesi, a partire da febbraio')
  398 + end
  399 +
  400 + it 'year increments' do
  401 + expect(desc('0 0 0 1 MAR * 2010/5')).to eq('Alle(ai) 12:00 AM, il giorno 1 del mese, solo a(nel) marzo, ogni 5 anni, a partire da 2010')
  402 + end
  403 + end
  404 + end
  405 +end
... ...
spec/exp_descriptor_pt_BR_spec.rb 0 → 100644
  1 +++ a/spec/exp_descriptor_pt_BR_spec.rb
... ... @@ -0,0 +1,405 @@
  1 +# encoding: utf-8
  2 +require 'cronex'
  3 +
  4 +module Cronex
  5 + describe ExpressionDescriptor do
  6 +
  7 + def desc(expression, opts = {})
  8 + opts[:locale] = 'pt_BR'
  9 + Cronex::ExpressionDescriptor.new(expression, opts).description
  10 + end
  11 +
  12 + let(:opts) { { zero_based_dow: false } }
  13 +
  14 + it 'every second' do
  15 + expect(desc('* * * * * *')).to eq('A cada segundo')
  16 + end
  17 +
  18 + it 'every 45 seconds' do
  19 + expect(desc('*/45 * * * * *')).to eq('A cada 45 segundos')
  20 + end
  21 +
  22 + it 'minute span' do
  23 + expect(desc('0-10 11 * * *')).to eq('A cada minuto entre 11:00 AM e 11:10 AM')
  24 + end
  25 +
  26 + context 'every minute' do
  27 + it 'every minute' do
  28 + expect(desc('* * * * *')).to eq('A cada minuto')
  29 + end
  30 +
  31 + it 'every minute */1' do
  32 + expect(desc('*/1 * * * *')).to eq('A cada minuto')
  33 + end
  34 +
  35 + it 'every minute 0 0/1' do
  36 + expect(desc('0 0/1 * * * ?')).to eq('A cada minuto')
  37 + end
  38 + end
  39 +
  40 + context 'every X minutes:' do
  41 + it 'every 5 minutes' do
  42 + expect(desc('*/5 * * * *')).to eq('A cada 5 minutos')
  43 + end
  44 +
  45 + it 'every 5 minutes at Midnight' do
  46 + expect(desc('*/5 0 * * *')).to eq('A cada 5 minutos, 12:00 AM')
  47 + end
  48 +
  49 + it 'every 5 minutes 0 */5' do
  50 + expect(desc('0 */5 * * * *')).to eq('A cada 5 minutos')
  51 + end
  52 +
  53 + it 'every 10 minutes 0 0/10' do
  54 + expect(desc('0 0/10 * * * ?')).to eq('A cada 10 minutos')
  55 + end
  56 + end
  57 +
  58 + context 'every hour:' do
  59 + it 'every hour 0 0' do
  60 + expect(desc('0 0 * * * ?')).to eq('A cada hora')
  61 + end
  62 +
  63 + it 'every hour 0 0 0/1' do
  64 + expect(desc('0 0 0/1 * * ?')).to eq('A cada hora')
  65 + end
  66 + end
  67 +
  68 + context 'daily:' do
  69 + it 'daily at /\d\d/:/\d\d/' do
  70 + expect(desc('30 11 * * *')).to eq('Às 11:30 AM')
  71 + end
  72 +
  73 + it 'daily at /\d/:/\d/' do
  74 + expect(desc('9 8 * * *')).to eq('Às 8:09 AM')
  75 + end
  76 +
  77 + it 'daily at /0[89]/:/0[89]/' do
  78 + expect(desc('09 08 * * *')).to eq('Às 8:09 AM')
  79 + end
  80 +
  81 + it 'daily at /0[1-7]/ /0[1-7/' do
  82 + expect(desc('02 01 * * *')).to eq('Às 1:02 AM')
  83 + end
  84 + end
  85 +
  86 + context 'time of day certain days of week:' do
  87 + it 'time of day on MON-FRI' do
  88 + expect(desc('0 23 ? * MON-FRI')).to eq('Às 11:00 PM, de segunda-feira a sexta-feira')
  89 + end
  90 +
  91 + it 'time of day on 1-5' do
  92 + expect(desc('30 11 * * 1-5')).to eq('Às 11:30 AM, de segunda-feira a sexta-feira')
  93 + end
  94 + end
  95 +
  96 + it 'one month todo(a)' do
  97 + expect(desc('* * * 3 *')).to eq('A cada minuto, em março')
  98 + end
  99 +
  100 + it 'two months todo(a)' do
  101 + expect(desc('* * * 3,6 *')).to eq('A cada minuto, em março e junho')
  102 + end
  103 +
  104 + it 'two times each afternoon' do
  105 + expect(desc('30 14,16 * * *')).to eq('Às 2:30 PM e 4:30 PM')
  106 + end
  107 +
  108 + it 'three times daily' do
  109 + expect(desc('30 6,14,16 * * *')).to eq('Às 6:30 AM, 2:30 PM e 4:30 PM')
  110 + end
  111 +
  112 + context 'once a week:' do
  113 + it 'once a week 0' do
  114 + expect(desc('46 9 * * 0')).to eq('Às 9:46 AM, todo(a) domingo')
  115 + end
  116 +
  117 + it 'once a week SUN' do
  118 + expect(desc('46 9 * * SUN')).to eq('Às 9:46 AM, todo(a) domingo')
  119 + end
  120 +
  121 + it 'once a week 7' do
  122 + expect(desc('46 9 * * 7')).to eq('Às 9:46 AM, todo(a) domingo')
  123 + end
  124 +
  125 + it 'once a week 1' do
  126 + expect(desc('46 9 * * 1')).to eq('Às 9:46 AM, todo(a) segunda-feira')
  127 + end
  128 +
  129 + it 'once a week 6' do
  130 + expect(desc('46 9 * * 6')).to eq('Às 9:46 AM, todo(a) sábado')
  131 + end
  132 + end
  133 +
  134 + context 'once a week non zero based:' do
  135 + it 'once a week 1' do
  136 + expect(desc('46 9 * * 1', opts)).to eq('Às 9:46 AM, todo(a) domingo')
  137 + end
  138 +
  139 + it 'once a week SUN' do
  140 + expect(desc('46 9 * * SUN', opts)).to eq('Às 9:46 AM, todo(a) domingo')
  141 + end
  142 +
  143 + it 'once a week 2' do
  144 + expect(desc('46 9 * * 2', opts)).to eq('Às 9:46 AM, todo(a) segunda-feira')
  145 + end
  146 +
  147 + it 'once a week 7' do
  148 + expect(desc('46 9 * * 7', opts)).to eq('Às 9:46 AM, todo(a) sábado')
  149 + end
  150 + end
  151 +
  152 + context 'twice a week:' do
  153 + it 'twice a week 1,2' do
  154 + expect(desc('46 9 * * 1,2')).to eq('Às 9:46 AM, todo(a) segunda-feira e terça-feira')
  155 + end
  156 +
  157 + it 'twice a week MON,TUE' do
  158 + expect(desc('46 9 * * MON,TUE')).to eq('Às 9:46 AM, todo(a) segunda-feira e terça-feira')
  159 + end
  160 +
  161 + it 'twice a week 0,6' do
  162 + expect(desc('46 9 * * 0,6')).to eq('Às 9:46 AM, todo(a) domingo e sábado')
  163 + end
  164 +
  165 + it 'twice a week 6,7' do
  166 + expect(desc('46 9 * * 6,7')).to eq('Às 9:46 AM, todo(a) sábado e domingo')
  167 + end
  168 + end
  169 +
  170 + context 'twice a week non zero based:' do
  171 + it 'twice a week 1,2' do
  172 + expect(desc('46 9 * * 1,2', opts)).to eq('Às 9:46 AM, todo(a) domingo e segunda-feira')
  173 + end
  174 +
  175 + it 'twice a week SUN,MON' do
  176 + expect(desc('46 9 * * SUN,MON', opts)).to eq('Às 9:46 AM, todo(a) domingo e segunda-feira')
  177 + end
  178 +
  179 + it 'twice a week 6,7' do
  180 + expect(desc('46 9 * * 6,7', opts)).to eq('Às 9:46 AM, todo(a) sexta-feira e sábado')
  181 + end
  182 + end
  183 +
  184 + it 'day of month' do
  185 + expect(desc('23 12 15 * *')).to eq('Às 12:23 PM, no dia 15 do mês')
  186 + end
  187 +
  188 + it 'day of month with day of week' do
  189 + expect(desc('23 12 15 * SUN')).to eq('Às 12:23 PM, no dia 15 do mês, todo(a) domingo')
  190 + end
  191 +
  192 + it 'month name' do
  193 + expect(desc('23 12 * JAN *')).to eq('Às 12:23 PM, em janeiro')
  194 + end
  195 +
  196 + it 'day of month with question mark' do
  197 + expect(desc('23 12 ? JAN *')).to eq('Às 12:23 PM, em janeiro')
  198 + end
  199 +
  200 + it 'month name range 2' do
  201 + expect(desc('23 12 * JAN-FEB *')).to eq('Às 12:23 PM, de janeiro a fevereiro')
  202 + end
  203 +
  204 + it 'month name range 3' do
  205 + expect(desc('23 12 * JAN-MAR *')).to eq('Às 12:23 PM, de janeiro a março')
  206 + end
  207 +
  208 + it 'day of week name' do
  209 + expect(desc('23 12 * * SUN')).to eq('Às 12:23 PM, todo(a) domingo')
  210 + end
  211 +
  212 + context 'day of week range:' do
  213 + it 'day of week range MON-FRI' do
  214 + expect(desc('*/5 15 * * MON-FRI')).to eq('A cada 5 minutos, 3:00 PM, de segunda-feira a sexta-feira')
  215 + end
  216 +
  217 + it 'day of week range 0-6' do
  218 + expect(desc('*/5 15 * * 0-6')).to eq('A cada 5 minutos, 3:00 PM, de domingo a sábado')
  219 + end
  220 +
  221 + it 'day of week range 6-7' do
  222 + expect(desc('*/5 15 * * 6-7')).to eq('A cada 5 minutos, 3:00 PM, de sábado a domingo')
  223 + end
  224 + end
  225 +
  226 + context 'day of week once in month:' do
  227 + it 'day of week once MON#3' do
  228 + expect(desc('* * * * MON#3')).to eq('A cada minuto, no(a) terceiro(a) segunda-feira do mês')
  229 + end
  230 +
  231 + it 'day of week once 0#3' do
  232 + expect(desc('* * * * 0#3')).to eq('A cada minuto, no(a) terceiro(a) domingo do mês')
  233 + end
  234 + end
  235 +
  236 + context 'last day of week of the month:' do
  237 + it 'last day of week 4L' do
  238 + expect(desc('* * * * 4L')).to eq('A cada minuto, no(a) último(a) quinta-feira do mês')
  239 + end
  240 +
  241 + it 'last day of week 0L' do
  242 + expect(desc('* * * * 0L')).to eq('A cada minuto, no(a) último(a) domingo do mês')
  243 + end
  244 + end
  245 +
  246 + context 'last day of the month:' do
  247 + it 'on the last day of the month' do
  248 + expect(desc('*/5 * L JAN *')).to eq('A cada 5 minutos, no último dia do mês, em janeiro')
  249 + end
  250 +
  251 + it 'between a day and last day of the month' do
  252 + expect(desc('*/5 * 23-L JAN *')).to eq('A cada 5 minutos, entre os dias 23 e último dia do mês, em janeiro')
  253 + end
  254 + end
  255 +
  256 + it 'time of day with seconds' do
  257 + expect(desc('30 02 14 * * *')).to eq('Às 2:02:30 PM')
  258 + end
  259 +
  260 + it 'second intervals' do
  261 + expect(desc('5-10 * * * * *')).to eq('Entre 5 e 10 segundos após o minuto')
  262 + end
  263 +
  264 + it 'second minutes hours intervals' do
  265 + expect(desc('5-10 30-35 10-12 * * *')).to eq(
  266 + 'Entre 5 e 10 segundos após o minuto, entre 30 e 35 minutos após a hora, entre 10:00 AM e 12:59 PM')
  267 + end
  268 +
  269 + it 'every 5 minutes at 30 seconds' do
  270 + expect(desc('30 */5 * * * *')).to eq('30 segundos após o minuto, a cada 5 minutos')
  271 + end
  272 +
  273 + it 'minutes past the hour range' do
  274 + expect(desc('0 30 10-13 ? * WED,FRI')).to eq(
  275 + '30 minutos após a hora, entre 10:00 AM e 1:59 PM, todo(a) quarta-feira e sexta-feira')
  276 + end
  277 +
  278 + it 'seconds past the minute interval' do
  279 + expect(desc('10 0/5 * * * ?')).to eq('10 segundos após o minuto, a cada 5 minutos')
  280 + end
  281 +
  282 + it 'between with interval' do
  283 + expect(desc('2-59/3 1,9,22 11-26 1-6 ?')).to eq(
  284 + 'A cada 3 minutos, entre 02 e 59 minutos após a hora, 1:00 AM, 9:00 AM e 10:00 PM, entre os dias 11 e 26 do mês, de janeiro a junho')
  285 + end
  286 +
  287 + it 'recurring first of month' do
  288 + expect(desc('0 0 6 1/1 * ?')).to eq('Às 6:00 AM')
  289 + end
  290 +
  291 + it 'minutes past the hour' do
  292 + expect(desc('0 5 0/1 * * ?')).to eq('05 minutos após a hora')
  293 + end
  294 +
  295 + it 'every past the hour' do
  296 + expect(desc('0 0,5,10,15,20,25,30,35,40,45,50,55 * ? * *')).to eq(
  297 + '00, 05, 10, 15, 20, 25, 30, 35, 40, 45, 50 e 55 minutos após a hora')
  298 + end
  299 +
  300 + it 'every X minutes past the hour with interval' do
  301 + expect(desc('0 0-30/2 17 ? * MON-FRI')).to eq(
  302 + 'A cada 2 minutos, entre 00 e 30 minutos após a hora, 5:00 PM, de segunda-feira a sexta-feira')
  303 + end
  304 +
  305 + it 'every X days with interval' do
  306 + expect(desc('30 7 1-L/2 * *')).to eq('Às 7:30 AM, a cada 2 dias, entre os dias 1 e último dia do mês')
  307 + end
  308 +
  309 + it 'one year only with seconds' do
  310 + expect(desc('* * * * * * 2013')).to eq('A cada segundo, em 2013')
  311 + end
  312 +
  313 + it 'one year todo(a) without seconds' do
  314 + expect(desc('* * * * * 2013')).to eq('A cada minuto, em 2013')
  315 + end
  316 +
  317 + it 'two years todo(a)' do
  318 + expect(desc('* * * * * 2013,2014')).to eq('A cada minuto, em 2013 e 2014')
  319 + end
  320 +
  321 + it 'year range 2' do
  322 + expect(desc('23 12 * JAN-FEB * 2013-2014')).to eq('Às 12:23 PM, de janeiro a fevereiro, de 2013 a 2014')
  323 + end
  324 +
  325 + it 'year range 3' do
  326 + expect(desc('23 12 * JAN-MAR * 2013-2015')).to eq('Às 12:23 PM, de janeiro a março, de 2013 a 2015')
  327 + end
  328 +
  329 + context 'multi part range seconds:' do
  330 + it 'multi part range seconds 2,4-5' do
  331 + expect(desc('2,4-5 1 * * *')).to eq('Entre 02,04 e 05 minutos após a hora, 1:00 AM')
  332 + end
  333 +
  334 + it 'multi part range seconds 2,26-28' do
  335 + expect(desc('2,26-28 18 * * *')).to eq('Entre 02,26 e 28 minutos após a hora, 6:00 PM')
  336 + end
  337 + end
  338 +
  339 + context 'minutes past the hour:' do
  340 + it 'minutes past the hour 5,10, midnight hour' do
  341 + expect(desc('5,10 0 * * *')).to eq('05 e 10 minutos após a hora, 12:00 AM')
  342 + end
  343 +
  344 + it 'minutes past the hour 5,10' do
  345 + expect(desc('5,10 * * * *')).to eq('05 e 10 minutos após a hora')
  346 + end
  347 +
  348 + it 'minutes past the hour 5,10 day 2' do
  349 + expect(desc('5,10 * 2 * *')).to eq('05 e 10 minutos após a hora, no dia 2 do mês')
  350 + end
  351 +
  352 + it 'minutes past the hour 5/10 day 2' do
  353 + expect(desc('5/10 * 2 * *')).to eq('A cada 10 minutos, iniciando 05 minutos após a hora, no dia 2 do mês')
  354 + end
  355 + end
  356 +
  357 + context 'seconds past the minute:' do
  358 + it 'seconds past the minute 5,6, midnight hour' do
  359 + expect(desc('5,6 0 0 * * *')).to eq('5 e 6 segundos após o minuto, 12:00 AM')
  360 + end
  361 +
  362 + it 'seconds past the minute 5,6' do
  363 + expect(desc('5,6 0 * * * *')).to eq('5 e 6 segundos após o minuto')
  364 + end
  365 +
  366 + it 'seconds past the minute 5,6 at 1' do
  367 + expect(desc('5,6 0 1 * * *')).to eq('5 e 6 segundos após o minuto, 1:00 AM')
  368 + end
  369 +
  370 + it 'seconds past the minute 5,6 day 2' do
  371 + expect(desc('5,6 0 * 2 * *')).to eq('5 e 6 segundos após o minuto, no dia 2 do mês')
  372 + end
  373 + end
  374 +
  375 + context 'increments starting at X > 1:' do
  376 + it 'second increments' do
  377 + expect(desc('5/15 0 * * * *')).to eq('A cada 15 segundos, iniciando 5 segundos após o minuto')
  378 + end
  379 +
  380 + it 'minute increments' do
  381 + expect(desc('30/10 * * * *')).to eq('A cada 10 minutos, iniciando 30 minutos após a hora')
  382 + end
  383 +
  384 + it 'hour increments' do
  385 + expect(desc('0 30 2/6 * * ?')).to eq('30 minutos após a hora, a cada 6 horas, iniciando 2:00 AM')
  386 + end
  387 +
  388 + it 'day of month increments' do
  389 + expect(desc('0 30 8 2/7 * *')).to eq('Às 8:30 AM, a cada 7 dias, iniciando no dia 2 do mês')
  390 + end
  391 +
  392 + it 'day of week increments' do
  393 + expect(desc('0 30 11 * * 2/2')).to eq('Às 11:30 AM, a cada 2 dias da semana, iniciando terça-feira')
  394 + end
  395 +
  396 + it 'month increments' do
  397 + expect(desc('0 20 10 * 2/3 THU')).to eq('Às 10:20 AM, todo(a) quinta-feira, a cada 3 mêses, iniciando em fevereiro')
  398 + end
  399 +
  400 + it 'year increments' do
  401 + expect(desc('0 0 0 1 MAR * 2010/5')).to eq('Às 12:00 AM, no dia 1 do mês, em março, a cada 5 anos, iniciando em 2010')
  402 + end
  403 + end
  404 + end
  405 +end
... ...
spec/exp_descriptor_ro_spec.rb 0 → 100644
  1 +++ a/spec/exp_descriptor_ro_spec.rb
... ... @@ -0,0 +1,405 @@
  1 +# encoding: utf-8
  2 +require 'cronex'
  3 +
  4 +module Cronex
  5 + describe ExpressionDescriptor do
  6 +
  7 + def desc(expression, opts = {})
  8 + opts[:locale] = 'ro'
  9 + Cronex::ExpressionDescriptor.new(expression, opts).description
  10 + end
  11 +
  12 + let(:opts) { { zero_based_dow: false } }
  13 +
  14 + it 'every second' do
  15 + expect(desc('* * * * * *')).to eq('În fiecare secundă')
  16 + end
  17 +
  18 + it 'every 45 seconds' do
  19 + expect(desc('*/45 * * * * *')).to eq('La fiecare 45 secunde')
  20 + end
  21 +
  22 + it 'minute span' do
  23 + expect(desc('0-10 11 * * *')).to eq('În fiecare minut între 11:00 AM și 11:10 AM')
  24 + end
  25 +
  26 + context 'every minute' do
  27 + it 'every minute' do
  28 + expect(desc('* * * * *')).to eq('În fiecare minut')
  29 + end
  30 +
  31 + it 'every minute */1' do
  32 + expect(desc('*/1 * * * *')).to eq('În fiecare minut')
  33 + end
  34 +
  35 + it 'every minute 0 0/1' do
  36 + expect(desc('0 0/1 * * * ?')).to eq('În fiecare minut')
  37 + end
  38 + end
  39 +
  40 + context 'every X minutes:' do
  41 + it 'every 5 minutes' do
  42 + expect(desc('*/5 * * * *')).to eq('La fiecare 5 minute')
  43 + end
  44 +
  45 + it 'every 5 minutes at Midnight' do
  46 + expect(desc('*/5 0 * * *')).to eq('La fiecare 5 minute, la 12:00 AM')
  47 + end
  48 +
  49 + it 'every 5 minutes 0 */5' do
  50 + expect(desc('0 */5 * * * *')).to eq('La fiecare 5 minute')
  51 + end
  52 +
  53 + it 'every 10 minutes 0 0/10' do
  54 + expect(desc('0 0/10 * * * ?')).to eq('La fiecare 10 minute')
  55 + end
  56 + end
  57 +
  58 + context 'every hour:' do
  59 + it 'every hour 0 0' do
  60 + expect(desc('0 0 * * * ?')).to eq('În fiecare oră')
  61 + end
  62 +
  63 + it 'every hour 0 0 0/1' do
  64 + expect(desc('0 0 0/1 * * ?')).to eq('În fiecare oră')
  65 + end
  66 + end
  67 +
  68 + context 'daily:' do
  69 + it 'daily at /\d\d/:/\d\d/' do
  70 + expect(desc('30 11 * * *')).to eq('La 11:30 AM')
  71 + end
  72 +
  73 + it 'daily at /\d/:/\d/' do
  74 + expect(desc('9 8 * * *')).to eq('La 8:09 AM')
  75 + end
  76 +
  77 + it 'daily at /0[89]/:/0[89]/' do
  78 + expect(desc('09 08 * * *')).to eq('La 8:09 AM')
  79 + end
  80 +
  81 + it 'daily at /0[1-7]/ /0[1-7/' do
  82 + expect(desc('02 01 * * *')).to eq('La 1:02 AM')
  83 + end
  84 + end
  85 +
  86 + context 'time of day certain days of week:' do
  87 + it 'time of day on MON-FRI' do
  88 + expect(desc('0 23 ? * MON-FRI')).to eq('La 11:00 PM, de luni până vineri')
  89 + end
  90 +
  91 + it 'time of day on 1-5' do
  92 + expect(desc('30 11 * * 1-5')).to eq('La 11:30 AM, de luni până vineri')
  93 + end
  94 + end
  95 +
  96 + it 'one month only' do
  97 + expect(desc('* * * 3 *')).to eq('În fiecare minut, numai în martie')
  98 + end
  99 +
  100 + it 'two months only' do
  101 + expect(desc('* * * 3,6 *')).to eq('În fiecare minut, numai în martie și iunie')
  102 + end
  103 +
  104 + it 'two times each afternoon' do
  105 + expect(desc('30 14,16 * * *')).to eq('La 2:30 PM și 4:30 PM')
  106 + end
  107 +
  108 + it 'three times daily' do
  109 + expect(desc('30 6,14,16 * * *')).to eq('La 6:30 AM, 2:30 PM și 4:30 PM')
  110 + end
  111 +
  112 + context 'once a week:' do
  113 + it 'once a week 0' do
  114 + expect(desc('46 9 * * 0')).to eq('La 9:46 AM, numai duminică')
  115 + end
  116 +
  117 + it 'once a week SUN' do
  118 + expect(desc('46 9 * * SUN')).to eq('La 9:46 AM, numai duminică')
  119 + end
  120 +
  121 + it 'once a week 7' do
  122 + expect(desc('46 9 * * 7')).to eq('La 9:46 AM, numai duminică')
  123 + end
  124 +
  125 + it 'once a week 1' do
  126 + expect(desc('46 9 * * 1')).to eq('La 9:46 AM, numai luni')
  127 + end
  128 +
  129 + it 'once a week 6' do
  130 + expect(desc('46 9 * * 6')).to eq('La 9:46 AM, numai sâmbătă')
  131 + end
  132 + end
  133 +
  134 + context 'once a week non zero based:' do
  135 + it 'once a week 1' do
  136 + expect(desc('46 9 * * 1', opts)).to eq('La 9:46 AM, numai duminică')
  137 + end
  138 +
  139 + it 'once a week SUN' do
  140 + expect(desc('46 9 * * SUN', opts)).to eq('La 9:46 AM, numai duminică')
  141 + end
  142 +
  143 + it 'once a week 2' do
  144 + expect(desc('46 9 * * 2', opts)).to eq('La 9:46 AM, numai luni')
  145 + end
  146 +
  147 + it 'once a week 7' do
  148 + expect(desc('46 9 * * 7', opts)).to eq('La 9:46 AM, numai sâmbătă')
  149 + end
  150 + end
  151 +
  152 + context 'twice a week:' do
  153 + it 'twice a week 1,2' do
  154 + expect(desc('46 9 * * 1,2')).to eq('La 9:46 AM, numai luni și marți')
  155 + end
  156 +
  157 + it 'twice a week MON,TUE' do
  158 + expect(desc('46 9 * * MON,TUE')).to eq('La 9:46 AM, numai luni și marți')
  159 + end
  160 +
  161 + it 'twice a week 0,6' do
  162 + expect(desc('46 9 * * 0,6')).to eq('La 9:46 AM, numai duminică și sâmbătă')
  163 + end
  164 +
  165 + it 'twice a week 6,7' do
  166 + expect(desc('46 9 * * 6,7')).to eq('La 9:46 AM, numai sâmbătă și duminică')
  167 + end
  168 + end
  169 +
  170 + context 'twice a week non zero based:' do
  171 + it 'twice a week 1,2' do
  172 + expect(desc('46 9 * * 1,2', opts)).to eq('La 9:46 AM, numai duminică și luni')
  173 + end
  174 +
  175 + it 'twice a week SUN,MON' do
  176 + expect(desc('46 9 * * SUN,MON', opts)).to eq('La 9:46 AM, numai duminică și luni')
  177 + end
  178 +
  179 + it 'twice a week 6,7' do
  180 + expect(desc('46 9 * * 6,7', opts)).to eq('La 9:46 AM, numai vineri și sâmbătă')
  181 + end
  182 + end
  183 +
  184 + it 'day of month' do
  185 + expect(desc('23 12 15 * *')).to eq('La 12:23 PM, în a 15-a zi a lunii')
  186 + end
  187 +
  188 + it 'day of month with day of week' do
  189 + expect(desc('23 12 15 * SUN')).to eq('La 12:23 PM, în a 15-a zi a lunii, numai duminică')
  190 + end
  191 +
  192 + it 'month name' do
  193 + expect(desc('23 12 * JAN *')).to eq('La 12:23 PM, numai în ianuarie')
  194 + end
  195 +
  196 + it 'day of month with question mark' do
  197 + expect(desc('23 12 ? JAN *')).to eq('La 12:23 PM, numai în ianuarie')
  198 + end
  199 +
  200 + it 'month name range 2' do
  201 + expect(desc('23 12 * JAN-FEB *')).to eq('La 12:23 PM, din ianuarie până în februarie')
  202 + end
  203 +
  204 + it 'month name range 3' do
  205 + expect(desc('23 12 * JAN-MAR *')).to eq('La 12:23 PM, din ianuarie până în martie')
  206 + end
  207 +
  208 + it 'day of week name' do
  209 + expect(desc('23 12 * * SUN')).to eq('La 12:23 PM, numai duminică')
  210 + end
  211 +
  212 + context 'day of week range:' do
  213 + it 'day of week range MON-FRI' do
  214 + expect(desc('*/5 15 * * MON-FRI')).to eq('La fiecare 5 minute, la 3:00 PM, de luni până vineri')
  215 + end
  216 +
  217 + it 'day of week range 0-6' do
  218 + expect(desc('*/5 15 * * 0-6')).to eq('La fiecare 5 minute, la 3:00 PM, de duminică până sâmbătă')
  219 + end
  220 +
  221 + it 'day of week range 6-7' do
  222 + expect(desc('*/5 15 * * 6-7')).to eq('La fiecare 5 minute, la 3:00 PM, de sâmbătă până duminică')
  223 + end
  224 + end
  225 +
  226 + context 'day of week once in month:' do
  227 + it 'day of week once MON#3' do
  228 + expect(desc('* * * * MON#3')).to eq('În fiecare minut, în a treia luni a lunii')
  229 + end
  230 +
  231 + it 'day of week once 0#3' do
  232 + expect(desc('* * * * 0#3')).to eq('În fiecare minut, în a treia duminică a lunii')
  233 + end
  234 + end
  235 +
  236 + context 'last day of week of the month:' do
  237 + it 'last day of week 4L' do
  238 + expect(desc('* * * * 4L')).to eq('În fiecare minut, în ultima joi din lună')
  239 + end
  240 +
  241 + it 'last day of week 0L' do
  242 + expect(desc('* * * * 0L')).to eq('În fiecare minut, în ultima duminică din lună')
  243 + end
  244 + end
  245 +
  246 + context 'last day of the month:' do
  247 + it 'on the last day of the month' do
  248 + expect(desc('*/5 * L JAN *')).to eq('La fiecare 5 minute, în ultima zi a lunii, numai în ianuarie')
  249 + end
  250 +
  251 + it 'between a day and last day of the month' do
  252 + expect(desc('*/5 * 23-L JAN *')).to eq('La fiecare 5 minute, între zilele 23 și ultima zi a lunii, numai în ianuarie')
  253 + end
  254 + end
  255 +
  256 + it 'time of day with seconds' do
  257 + expect(desc('30 02 14 * * *')).to eq('La 2:02:30 PM')
  258 + end
  259 +
  260 + it 'second intervals' do
  261 + expect(desc('5-10 * * * * *')).to eq('Între secundele 5 și 10')
  262 + end
  263 +
  264 + it 'second minutes hours intervals' do
  265 + expect(desc('5-10 30-35 10-12 * * *')).to eq(
  266 + 'Între secundele 5 și 10, între minutele 30 și 35, între 10:00 AM și 12:59 PM')
  267 + end
  268 +
  269 + it 'every 5 minutes at 30 seconds' do
  270 + expect(desc('30 */5 * * * *')).to eq('La secunda 30, la fiecare 5 minute')
  271 + end
  272 +
  273 + it 'minutes past the hour range' do
  274 + expect(desc('0 30 10-13 ? * WED,FRI')).to eq(
  275 + 'La 30 minute în fiecare oră, între 10:00 AM și 1:59 PM, numai miercuri și vineri')
  276 + end
  277 +
  278 + it 'seconds past the minute interval' do
  279 + expect(desc('10 0/5 * * * ?')).to eq('La secunda 10, la fiecare 5 minute')
  280 + end
  281 +
  282 + it 'between with interval' do
  283 + expect(desc('2-59/3 1,9,22 11-26 1-6 ?')).to eq(
  284 + 'La fiecare 3 minute, între minutele 02 și 59, la 1:00 AM, 9:00 AM și 10:00 PM, între zilele 11 și 26 a lunii, din ianuarie până în iunie')
  285 + end
  286 +
  287 + it 'recurring first of month' do
  288 + expect(desc('0 0 6 1/1 * ?')).to eq('La 6:00 AM')
  289 + end
  290 +
  291 + it 'minutes past the hour' do
  292 + expect(desc('0 5 0/1 * * ?')).to eq('La 05 minute în fiecare oră')
  293 + end
  294 +
  295 + it 'every past the hour' do
  296 + expect(desc('0 0,5,10,15,20,25,30,35,40,45,50,55 * ? * *')).to eq(
  297 + 'La 00, 05, 10, 15, 20, 25, 30, 35, 40, 45, 50 și 55 minute în fiecare oră')
  298 + end
  299 +
  300 + it 'every X minutes past the hour with interval' do
  301 + expect(desc('0 0-30/2 17 ? * MON-FRI')).to eq(
  302 + 'La fiecare 2 minute, între minutele 00 și 30, la 5:00 PM, de luni până vineri')
  303 + end
  304 +
  305 + it 'every X days with interval' do
  306 + expect(desc('30 7 1-L/2 * *')).to eq('La 7:30 AM, la fiecare 2 zile, între zilele 1 și ultima zi a lunii')
  307 + end
  308 +
  309 + it 'one year only with seconds' do
  310 + expect(desc('* * * * * * 2013')).to eq('În fiecare secundă, numai în 2013')
  311 + end
  312 +
  313 + it 'one year only without seconds' do
  314 + expect(desc('* * * * * 2013')).to eq('În fiecare minut, numai în 2013')
  315 + end
  316 +
  317 + it 'two years only' do
  318 + expect(desc('* * * * * 2013,2014')).to eq('În fiecare minut, numai în 2013 și 2014')
  319 + end
  320 +
  321 + it 'year range 2' do
  322 + expect(desc('23 12 * JAN-FEB * 2013-2014')).to eq('La 12:23 PM, din ianuarie până în februarie, din 2013 până în 2014')
  323 + end
  324 +
  325 + it 'year range 3' do
  326 + expect(desc('23 12 * JAN-MAR * 2013-2015')).to eq('La 12:23 PM, din ianuarie până în martie, din 2013 până în 2015')
  327 + end
  328 +
  329 + context 'multi part range seconds:' do
  330 + it 'multi part range seconds 2,4-5' do
  331 + expect(desc('2,4-5 1 * * *')).to eq('Între minutele 02,04 și 05, la 1:00 AM')
  332 + end
  333 +
  334 + it 'multi part range seconds 2,26-28' do
  335 + expect(desc('2,26-28 18 * * *')).to eq('Între minutele 02,26 și 28, la 6:00 PM')
  336 + end
  337 + end
  338 +
  339 + context 'minutes past the hour:' do
  340 + it 'minutes past the hour 5,10, midnight hour' do
  341 + expect(desc('5,10 0 * * *')).to eq('La 05 și 10 minute în fiecare oră, la 12:00 AM')
  342 + end
  343 +
  344 + it 'minutes past the hour 5,10' do
  345 + expect(desc('5,10 * * * *')).to eq('La 05 și 10 minute în fiecare oră')
  346 + end
  347 +
  348 + it 'minutes past the hour 5,10 day 2' do
  349 + expect(desc('5,10 * 2 * *')).to eq('La 05 și 10 minute în fiecare oră, în a 2-a zi a lunii')
  350 + end
  351 +
  352 + it 'minutes past the hour 5/10 day 2' do
  353 + expect(desc('5/10 * 2 * *')).to eq('La fiecare 10 minute, pornire la 05 minute în fiecare oră, în a 2-a zi a lunii')
  354 + end
  355 + end
  356 +
  357 + context 'seconds past the minute:' do
  358 + it 'seconds past the minute 5,6, midnight hour' do
  359 + expect(desc('5,6 0 0 * * *')).to eq('La secunda 5 și 6, la 12:00 AM')
  360 + end
  361 +
  362 + it 'seconds past the minute 5,6' do
  363 + expect(desc('5,6 0 * * * *')).to eq('La secunda 5 și 6')
  364 + end
  365 +
  366 + it 'seconds past the minute 5,6 at 1' do
  367 + expect(desc('5,6 0 1 * * *')).to eq('La secunda 5 și 6, la 1:00 AM')
  368 + end
  369 +
  370 + it 'seconds past the minute 5,6 day 2' do
  371 + expect(desc('5,6 0 * 2 * *')).to eq('La secunda 5 și 6, în a 2-a zi a lunii')
  372 + end
  373 + end
  374 +
  375 + context 'increments starting at X > 1:' do
  376 + it 'second increments' do
  377 + expect(desc('5/15 0 * * * *')).to eq('La fiecare 15 secunde, pornire la secunda 5')
  378 + end
  379 +
  380 + it 'minute increments' do
  381 + expect(desc('30/10 * * * *')).to eq('La fiecare 10 minute, pornire la 30 minute în fiecare oră')
  382 + end
  383 +
  384 + it 'hour increments' do
  385 + expect(desc('0 30 2/6 * * ?')).to eq('La 30 minute în fiecare oră, la fiecare 6 ore, pornire la 2:00 AM')
  386 + end
  387 +
  388 + it 'day of month increments' do
  389 + expect(desc('0 30 8 2/7 * *')).to eq('La 8:30 AM, la fiecare 7 zile, pornire în a 2-a zi a lunii')
  390 + end
  391 +
  392 + it 'day of week increments' do
  393 + expect(desc('0 30 11 * * 2/2')).to eq('La 11:30 AM, în fiecare 2 zile din săptămână, pornire de marți')
  394 + end
  395 +
  396 + it 'month increments' do
  397 + expect(desc('0 20 10 * 2/3 THU')).to eq('La 10:20 AM, numai joi, la fiecare 3 luni, pornire în februarie')
  398 + end
  399 +
  400 + it 'year increments' do
  401 + expect(desc('0 0 0 1 MAR * 2010/5')).to eq('La 12:00 AM, în a 1-a zi a lunii, numai în martie, la fiecare 5 ani, pornire în 2010')
  402 + end
  403 + end
  404 + end
  405 +end
... ...
spec/exp_descriptor_ru_spec.rb 0 → 100644
  1 +++ a/spec/exp_descriptor_ru_spec.rb
... ... @@ -0,0 +1,405 @@
  1 +# encoding: utf-8
  2 +require 'cronex'
  3 +
  4 +module Cronex
  5 + describe ExpressionDescriptor do
  6 +
  7 + def desc(expression, opts = {})
  8 + opts[:locale] = 'ru'
  9 + Cronex::ExpressionDescriptor.new(expression, opts).description
  10 + end
  11 +
  12 + let(:opts) { { zero_based_dow: false } }
  13 +
  14 + it 'every second' do
  15 + expect(desc('* * * * * *')).to eq('Каждую секунду')
  16 + end
  17 +
  18 + it 'every 45 seconds' do
  19 + expect(desc('*/45 * * * * *')).to eq('Каждые 45 секунд')
  20 + end
  21 +
  22 + it 'minute span' do
  23 + expect(desc('0-10 11 * * *')).to eq('Каждую минуту с 11:00 AM по 11:10 AM')
  24 + end
  25 +
  26 + context 'every minute' do
  27 + it 'every minute' do
  28 + expect(desc('* * * * *')).to eq('Каждую минуту')
  29 + end
  30 +
  31 + it 'every minute */1' do
  32 + expect(desc('*/1 * * * *')).to eq('Каждую минуту')
  33 + end
  34 +
  35 + it 'every minute 0 0/1' do
  36 + expect(desc('0 0/1 * * * ?')).to eq('Каждую минуту')
  37 + end
  38 + end
  39 +
  40 + context 'every X minutes:' do
  41 + it 'every 5 minutes' do
  42 + expect(desc('*/5 * * * *')).to eq('Каждые 5 минут')
  43 + end
  44 +
  45 + it 'every 5 minutes at Midnight' do
  46 + expect(desc('*/5 0 * * *')).to eq('Каждые 5 минут, в 12:00 AM')
  47 + end
  48 +
  49 + it 'every 5 minutes 0 */5' do
  50 + expect(desc('0 */5 * * * *')).to eq('Каждые 5 минут')
  51 + end
  52 +
  53 + it 'every 10 minutes 0 0/10' do
  54 + expect(desc('0 0/10 * * * ?')).to eq('Каждые 10 минут')
  55 + end
  56 + end
  57 +
  58 + context 'every hour:' do
  59 + it 'every hour 0 0' do
  60 + expect(desc('0 0 * * * ?')).to eq('Каждый час')
  61 + end
  62 +
  63 + it 'every hour 0 0 0/1' do
  64 + expect(desc('0 0 0/1 * * ?')).to eq('Каждый час')
  65 + end
  66 + end
  67 +
  68 + context 'daily:' do
  69 + it 'daily at /\d\d/:/\d\d/' do
  70 + expect(desc('30 11 * * *')).to eq('В 11:30 AM')
  71 + end
  72 +
  73 + it 'daily at /\d/:/\d/' do
  74 + expect(desc('9 8 * * *')).to eq('В 8:09 AM')
  75 + end
  76 +
  77 + it 'daily at /0[89]/:/0[89]/' do
  78 + expect(desc('09 08 * * *')).to eq('В 8:09 AM')
  79 + end
  80 +
  81 + it 'daily at /0[1-7]/ /0[1-7/' do
  82 + expect(desc('02 01 * * *')).to eq('В 1:02 AM')
  83 + end
  84 + end
  85 +
  86 + context 'time of day certain days of week:' do
  87 + it 'time of day on MON-FRI' do
  88 + expect(desc('0 23 ? * MON-FRI')).to eq('В 11:00 PM, понедельник - пятница')
  89 + end
  90 +
  91 + it 'time of day on 1-5' do
  92 + expect(desc('30 11 * * 1-5')).to eq('В 11:30 AM, понедельник - пятница')
  93 + end
  94 + end
  95 +
  96 + it 'one month only' do
  97 + expect(desc('* * * 3 *')).to eq('Каждую минуту, только март')
  98 + end
  99 +
  100 + it 'two months only' do
  101 + expect(desc('* * * 3,6 *')).to eq('Каждую минуту, только март и июнь')
  102 + end
  103 +
  104 + it 'two times each afternoon' do
  105 + expect(desc('30 14,16 * * *')).to eq('В 2:30 PM и 4:30 PM')
  106 + end
  107 +
  108 + it 'three times daily' do
  109 + expect(desc('30 6,14,16 * * *')).to eq('В 6:30 AM, 2:30 PM и 4:30 PM')
  110 + end
  111 +
  112 + context 'once a week:' do
  113 + it 'once a week 0' do
  114 + expect(desc('46 9 * * 0')).to eq('В 9:46 AM, только воскресенье')
  115 + end
  116 +
  117 + it 'once a week SUN' do
  118 + expect(desc('46 9 * * SUN')).to eq('В 9:46 AM, только воскресенье')
  119 + end
  120 +
  121 + it 'once a week 7' do
  122 + expect(desc('46 9 * * 7')).to eq('В 9:46 AM, только воскресенье')
  123 + end
  124 +
  125 + it 'once a week 1' do
  126 + expect(desc('46 9 * * 1')).to eq('В 9:46 AM, только понедельник')
  127 + end
  128 +
  129 + it 'once a week 6' do
  130 + expect(desc('46 9 * * 6')).to eq('В 9:46 AM, только суббота')
  131 + end
  132 + end
  133 +
  134 + context 'once a week non zero based:' do
  135 + it 'once a week 1' do
  136 + expect(desc('46 9 * * 1', opts)).to eq('В 9:46 AM, только воскресенье')
  137 + end
  138 +
  139 + it 'once a week SUN' do
  140 + expect(desc('46 9 * * SUN', opts)).to eq('В 9:46 AM, только воскресенье')
  141 + end
  142 +
  143 + it 'once a week 2' do
  144 + expect(desc('46 9 * * 2', opts)).to eq('В 9:46 AM, только понедельник')
  145 + end
  146 +
  147 + it 'once a week 7' do
  148 + expect(desc('46 9 * * 7', opts)).to eq('В 9:46 AM, только суббота')
  149 + end
  150 + end
  151 +
  152 + context 'twice a week:' do
  153 + it 'twice a week 1,2' do
  154 + expect(desc('46 9 * * 1,2')).to eq('В 9:46 AM, только понедельник и вторник')
  155 + end
  156 +
  157 + it 'twice a week MON,TUE' do
  158 + expect(desc('46 9 * * MON,TUE')).to eq('В 9:46 AM, только понедельник и вторник')
  159 + end
  160 +
  161 + it 'twice a week 0,6' do
  162 + expect(desc('46 9 * * 0,6')).to eq('В 9:46 AM, только воскресенье и суббота')
  163 + end
  164 +
  165 + it 'twice a week 6,7' do
  166 + expect(desc('46 9 * * 6,7')).to eq('В 9:46 AM, только суббота и воскресенье')
  167 + end
  168 + end
  169 +
  170 + context 'twice a week non zero based:' do
  171 + it 'twice a week 1,2' do
  172 + expect(desc('46 9 * * 1,2', opts)).to eq('В 9:46 AM, только воскресенье и понедельник')
  173 + end
  174 +
  175 + it 'twice a week SUN,MON' do
  176 + expect(desc('46 9 * * SUN,MON', opts)).to eq('В 9:46 AM, только воскресенье и понедельник')
  177 + end
  178 +
  179 + it 'twice a week 6,7' do
  180 + expect(desc('46 9 * * 6,7', opts)).to eq('В 9:46 AM, только пятница и суббота')
  181 + end
  182 + end
  183 +
  184 + it 'day of month' do
  185 + expect(desc('23 12 15 * *')).to eq('В 12:23 PM, 15 день месяца')
  186 + end
  187 +
  188 + it 'day of month with day of week' do
  189 + expect(desc('23 12 15 * SUN')).to eq('В 12:23 PM, 15 день месяца, только воскресенье')
  190 + end
  191 +
  192 + it 'month name' do
  193 + expect(desc('23 12 * JAN *')).to eq('В 12:23 PM, только январь')
  194 + end
  195 +
  196 + it 'day of month with question mark' do
  197 + expect(desc('23 12 ? JAN *')).to eq('В 12:23 PM, только январь')
  198 + end
  199 +
  200 + it 'month name range 2' do
  201 + expect(desc('23 12 * JAN-FEB *')).to eq('В 12:23 PM, январь - февраль')
  202 + end
  203 +
  204 + it 'month name range 3' do
  205 + expect(desc('23 12 * JAN-MAR *')).to eq('В 12:23 PM, январь - март')
  206 + end
  207 +
  208 + it 'day of week name' do
  209 + expect(desc('23 12 * * SUN')).to eq('В 12:23 PM, только воскресенье')
  210 + end
  211 +
  212 + context 'day of week range:' do
  213 + it 'day of week range MON-FRI' do
  214 + expect(desc('*/5 15 * * MON-FRI')).to eq('Каждые 5 минут, в 3:00 PM, понедельник - пятница')
  215 + end
  216 +
  217 + it 'day of week range 0-6' do
  218 + expect(desc('*/5 15 * * 0-6')).to eq('Каждые 5 минут, в 3:00 PM, воскресенье - суббота')
  219 + end
  220 +
  221 + it 'day of week range 6-7' do
  222 + expect(desc('*/5 15 * * 6-7')).to eq('Каждые 5 минут, в 3:00 PM, суббота - воскресенье')
  223 + end
  224 + end
  225 +
  226 + context 'day of week once in month:' do
  227 + it 'day of week once MON#3' do
  228 + expect(desc('* * * * MON#3')).to eq('Каждую минуту, в третий понедельник месяца')
  229 + end
  230 +
  231 + it 'day of week once 0#3' do
  232 + expect(desc('* * * * 0#3')).to eq('Каждую минуту, в третий воскресенье месяца')
  233 + end
  234 + end
  235 +
  236 + context 'last day of week of the month:' do
  237 + it 'last day of week 4L' do
  238 + expect(desc('* * * * 4L')).to eq('Каждую минуту, в последний четверг месяца')
  239 + end
  240 +
  241 + it 'last day of week 0L' do
  242 + expect(desc('* * * * 0L')).to eq('Каждую минуту, в последний воскресенье месяца')
  243 + end
  244 + end
  245 +
  246 + context 'last day of the month:' do
  247 + it 'on the last day of the month' do
  248 + expect(desc('*/5 * L JAN *')).to eq('Каждые 5 минут, в последний день месяца, только январь')
  249 + end
  250 +
  251 + it 'between a day and last day of the month' do
  252 + expect(desc('*/5 * 23-L JAN *')).to eq('Каждые 5 минут, между 23 днем и последним днем месяца, только январь')
  253 + end
  254 + end
  255 +
  256 + it 'time of day with seconds' do
  257 + expect(desc('30 02 14 * * *')).to eq('В 2:02:30 PM')
  258 + end
  259 +
  260 + it 'second intervals' do
  261 + expect(desc('5-10 * * * * *')).to eq('Секунды с 5 по 10')
  262 + end
  263 +
  264 + it 'second minutes hours intervals' do
  265 + expect(desc('5-10 30-35 10-12 * * *')).to eq(
  266 + 'Секунды с 5 по 10, минуты с 30 по 35, между 10:00 AM и 12:59 PM')
  267 + end
  268 +
  269 + it 'every 5 minutes at 30 seconds' do
  270 + expect(desc('30 */5 * * * *')).to eq('В 30 секунд, каждые 5 минут')
  271 + end
  272 +
  273 + it 'minutes past the hour range' do
  274 + expect(desc('0 30 10-13 ? * WED,FRI')).to eq(
  275 + 'В 30 минут часа, между 10:00 AM и 1:59 PM, только среда и пятница')
  276 + end
  277 +
  278 + it 'seconds past the minute interval' do
  279 + expect(desc('10 0/5 * * * ?')).to eq('В 10 секунд, каждые 5 минут')
  280 + end
  281 +
  282 + it 'between with interval' do
  283 + expect(desc('2-59/3 1,9,22 11-26 1-6 ?')).to eq(
  284 + 'Каждые 3 минут, минуты с 02 по 59, в 1:00 AM, 9:00 AM и 10:00 PM, между 11 днем и 26 днем месяца, январь - июнь')
  285 + end
  286 +
  287 + it 'recurring first of month' do
  288 + expect(desc('0 0 6 1/1 * ?')).to eq('В 6:00 AM')
  289 + end
  290 +
  291 + it 'minutes past the hour' do
  292 + expect(desc('0 5 0/1 * * ?')).to eq('В 05 минут часа')
  293 + end
  294 +
  295 + it 'every past the hour' do
  296 + expect(desc('0 0,5,10,15,20,25,30,35,40,45,50,55 * ? * *')).to eq(
  297 + 'В 00, 05, 10, 15, 20, 25, 30, 35, 40, 45, 50 и 55 минут часа')
  298 + end
  299 +
  300 + it 'every X minutes past the hour with interval' do
  301 + expect(desc('0 0-30/2 17 ? * MON-FRI')).to eq(
  302 + 'Каждые 2 минут, минуты с 00 по 30, в 5:00 PM, понедельник - пятница')
  303 + end
  304 +
  305 + it 'every X days with interval' do
  306 + expect(desc('30 7 1-L/2 * *')).to eq('В 7:30 AM, каждые 2 дня(ей), между 1 днем и последним днем месяца')
  307 + end
  308 +
  309 + it 'one year only with seconds' do
  310 + expect(desc('* * * * * * 2013')).to eq('Каждую секунду, только 2013')
  311 + end
  312 +
  313 + it 'one year only without seconds' do
  314 + expect(desc('* * * * * 2013')).to eq('Каждую минуту, только 2013')
  315 + end
  316 +
  317 + it 'two years only' do
  318 + expect(desc('* * * * * 2013,2014')).to eq('Каждую минуту, только 2013 и 2014')
  319 + end
  320 +
  321 + it 'year range 2' do
  322 + expect(desc('23 12 * JAN-FEB * 2013-2014')).to eq('В 12:23 PM, январь - февраль, 2013 - 2014')
  323 + end
  324 +
  325 + it 'year range 3' do
  326 + expect(desc('23 12 * JAN-MAR * 2013-2015')).to eq('В 12:23 PM, январь - март, 2013 - 2015')
  327 + end
  328 +
  329 + context 'multi part range seconds:' do
  330 + it 'multi part range seconds 2,4-5' do
  331 + expect(desc('2,4-5 1 * * *')).to eq('Минуты с 02,04 по 05, в 1:00 AM')
  332 + end
  333 +
  334 + it 'multi part range seconds 2,26-28' do
  335 + expect(desc('2,26-28 18 * * *')).to eq('Минуты с 02,26 по 28, в 6:00 PM')
  336 + end
  337 + end
  338 +
  339 + context 'minutes past the hour:' do
  340 + it 'minutes past the hour 5,10, midnight hour' do
  341 + expect(desc('5,10 0 * * *')).to eq('В 05 и 10 минут часа, в 12:00 AM')
  342 + end
  343 +
  344 + it 'minutes past the hour 5,10' do
  345 + expect(desc('5,10 * * * *')).to eq('В 05 и 10 минут часа')
  346 + end
  347 +
  348 + it 'minutes past the hour 5,10 day 2' do
  349 + expect(desc('5,10 * 2 * *')).to eq('В 05 и 10 минут часа, 2 день месяца')
  350 + end
  351 +
  352 + it 'minutes past the hour 5/10 day 2' do
  353 + expect(desc('5/10 * 2 * *')).to eq('Каждые 10 минут, начало в 05 минут часа, 2 день месяца')
  354 + end
  355 + end
  356 +
  357 + context 'seconds past the minute:' do
  358 + it 'seconds past the minute 5,6, midnight hour' do
  359 + expect(desc('5,6 0 0 * * *')).to eq('В 5 и 6 секунд, в 12:00 AM')
  360 + end
  361 +
  362 + it 'seconds past the minute 5,6' do
  363 + expect(desc('5,6 0 * * * *')).to eq('В 5 и 6 секунд')
  364 + end
  365 +
  366 + it 'seconds past the minute 5,6 at 1' do
  367 + expect(desc('5,6 0 1 * * *')).to eq('В 5 и 6 секунд, в 1:00 AM')
  368 + end
  369 +
  370 + it 'seconds past the minute 5,6 day 2' do
  371 + expect(desc('5,6 0 * 2 * *')).to eq('В 5 и 6 секунд, 2 день месяца')
  372 + end
  373 + end
  374 +
  375 + context 'increments starting at X > 1:' do
  376 + it 'second increments' do
  377 + expect(desc('5/15 0 * * * *')).to eq('Каждые 15 секунд, начало в 5 секунд')
  378 + end
  379 +
  380 + it 'minute increments' do
  381 + expect(desc('30/10 * * * *')).to eq('Каждые 10 минут, начало в 30 минут часа')
  382 + end
  383 +
  384 + it 'hour increments' do
  385 + expect(desc('0 30 2/6 * * ?')).to eq('В 30 минут часа, каждые 6 часов, начало в 2:00 AM')
  386 + end
  387 +
  388 + it 'day of month increments' do
  389 + expect(desc('0 30 8 2/7 * *')).to eq('В 8:30 AM, каждые 7 дня(ей), начало 2 день месяца')
  390 + end
  391 +
  392 + it 'day of week increments' do
  393 + expect(desc('0 30 11 * * 2/2')).to eq('В 11:30 AM, каждые 2 дня(ей) недели, начало в вторник')
  394 + end
  395 +
  396 + it 'month increments' do
  397 + expect(desc('0 20 10 * 2/3 THU')).to eq('В 10:20 AM, только четверг, каждые 3 месяцев, начало в февраль')
  398 + end
  399 +
  400 + it 'year increments' do
  401 + expect(desc('0 0 0 1 MAR * 2010/5')).to eq('В 12:00 AM, 1 день месяца, только март, каждые 5 лет, начало в 2010')
  402 + end
  403 + end
  404 + end
  405 +end
... ...
spec/spec_helper.rb 0 → 100644
  1 +++ a/spec/spec_helper.rb
... ... @@ -0,0 +1,11 @@
  1 +require 'rspec'
  2 +
  3 +RSpec.configure do |config|
  4 + config.expect_with :rspec do |c|
  5 + c.syntax = :expect
  6 + end
  7 +
  8 + def desc(expression, opts = {})
  9 + Cronex::ExpressionDescriptor.new(expression, opts).description
  10 + end
  11 +end
... ...