Merge pull request #21 from Ptico/discontinued

Inflecto is dead, long live dry-inflector
This commit is contained in:
Markus Schirp 2018-02-26 13:49:39 +00:00 committed by GitHub
commit 09cb16619d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 2 additions and 1879 deletions

37
.gitignore vendored
View File

@ -1,37 +0,0 @@
## MAC OS
.DS_Store
## TEXTMATE
*.tmproj
tmtags
## EMACS
*~
\#*
.\#*
## VIM
*.swp
## Rubinius
*.rbc
.rbx
## PROJECT::GENERAL
*.gem
coverage
profiling
turbulence
rdoc
pkg
tmp
doc
log
.yardoc
measurements
## BUNDLER
.bundle
Gemfile.lock
## PROJECT::SPECIFIC

1
.rspec
View File

@ -1 +0,0 @@
--color

1
.rvmrc
View File

@ -1 +0,0 @@
rvm use @$(basename `pwd`) --create

View File

@ -1,25 +0,0 @@
language: ruby
before_install: gem install bundler
bundler_args: --without yard guard benchmarks
script: "bundle exec rake ci"
rvm:
- 1.9.3
- 2.0.0
- 2.1.3
- ruby-head
- rbx-19mode
notifications:
irc:
channels:
- "irc.freenode.org#rom-rb"
on_success: never
on_failure: change
email:
on_success: never
on_failure: change
matrix:
include:
- rvm: jruby-19mode
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
- rvm: jruby-head
env: JRUBY_OPTS="$JRUBY_OPTS --debug"

View File

@ -1,7 +0,0 @@
# v0.0.2 2013-01-20
[change] Do not depend on backports
# v0.0.1 2012-12-12
First public release!

View File

@ -1,7 +0,0 @@
source 'https://rubygems.org'
gemspec
group :development, :test do
gem 'devtools', '~> 0.1.x'
end

View File

@ -1,18 +0,0 @@
# encoding: utf-8
guard :bundler do
watch('Gemfile')
end
guard :rspec do
# run all specs if the spec_helper or supporting files files are modified
watch('spec/spec_helper.rb') { 'spec' }
watch(%r{\Aspec/(?:lib|support|shared)/.+\.rb\z}) { 'spec' }
# run unit specs if associated lib code is modified
watch(%r{\Alib/(.+)\.rb\z}) { |m| Dir["spec/unit/#{m[1]}"] }
watch("lib/#{File.basename(File.expand_path('../', __FILE__))}.rb") { 'spec' }
# run a spec if it is modified
watch(%r{\Aspec/(?:unit|integration)/.+_spec\.rb\z})
end

20
LICENSE
View File

@ -1,20 +0,0 @@
Copyright (c) The rails, merb & datamapper team
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,52 +1,4 @@
inflecto
Discontinued
========
[![Gem Version](https://badge.fury.io/rb/inflecto.png)][gem]
[![Build Status](https://secure.travis-ci.org/mbj/inflecto.png?branch=master)][travis]
[![Dependency Status](https://gemnasium.com/mbj/inflecto.png)][gemnasium]
[![Code Climate](https://codeclimate.com/github/mbj/inflecto.png)][codeclimate]
[![Coverage Status](https://coveralls.io/repos/mbj/inflecto/badge.png?branch=master)][coveralls]
[gem]: https://rubygems.org/gems/inflecto
[travis]: https://travis-ci.org/mbj/inflecto
[gemnasium]: https://gemnasium.com/mbj/inflecto
[codeclimate]: https://codeclimate.com/github/mbj/inflecto
[coveralls]: https://coveralls.io/r/mbj/inflecto
This is a standalone inflector ripped out from [dm-core](https://github.com/datamapper/dm-core)
The dm-core inflector originated from [extlib](https://github.com/datamapper/extlib)
The extlib inflecto originated from [active_support](https://github.com/rails/rails)
Installation
------------
Install the gem ```inflecto``` via your preferred method.
Examples
--------
Soon.
Credits
-------
The rails, merb & datamapper team
The current maintainer is Markus Schirp ([mbj](https://github.com/mbj)) with help from [indrekj](https://github.com/indrekj).
Contributing
-------------
* If you want your code merged into the mainline, please discuss the proposed changes with me before doing any work on it. This library is still in early development, and the direction it is going may not always be clear. Some features may not be appropriate yet, may need to be deferred until later when the foundation for them is laid, or may be more applicable in a plugin.
* Fork the project.
* Make your feature addition or bug fix.
* Follow this [style guide](https://github.com/dkubb/styleguide).
* Add specs for it. This is important so I don't break it in a future version unintentionally. Tests must cover all branches within the code, and code must be fully covered.
* Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
* Run "rake ci". This must pass and not show any regressions in the metrics for the code to be merged.
* Send me a pull request. Bonus points for topic branches.
License
-------
See LICENSE for details
This gem has been discontinued in favor of [dry-inflector](https://github.com/dry-rb/dry-inflector)

View File

@ -1,5 +0,0 @@
# encoding: utf-8
require 'devtools'
Devtools.init_rake_tasks

1
TODO
View File

@ -1 +0,0 @@
* Find the guys to mention in credits.

View File

@ -1,3 +0,0 @@
---
threshold: 12
total_score: 73

View File

@ -1,2 +0,0 @@
---
threshold: 11.3

View File

@ -1,4 +0,0 @@
---
name: inflecto
namespace: Inflecto
expect_coverage: '331/332'

View File

@ -1,111 +0,0 @@
---
Attribute:
enabled: true
exclude:
- Inflecto::Inflections
BooleanParameter:
enabled: true
exclude: []
ClassVariable:
enabled: true
exclude: []
ControlParameter:
enabled: true
exclude: []
DataClump:
enabled: true
exclude:
- Inflecto::Inflections
max_copies: 2
min_clump_size: 2
DuplicateMethodCall:
enabled: true
exclude:
- Inflecto#self.camelize
max_calls: 1
allow_calls: []
FeatureEnvy:
enabled: true
exclude: []
IrresponsibleModule:
enabled: true
exclude: []
LongParameterList:
enabled: true
exclude:
- Inflecto::Inflections#add_irregular
- Inflecto::Inflections#rule
max_params: 2
overrides:
initialize:
max_params: 3
LongYieldList:
enabled: true
exclude: []
max_params: 2
NestedIterators:
enabled: true
exclude: []
max_allowed_nesting: 1
ignore_iterators: []
NilCheck:
enabled: true
exclude: []
RepeatedConditional:
enabled: true
exclude: []
max_ifs: 1
TooManyInstanceVariables:
enabled: true
exclude:
- Inflecto::Inflections
max_instance_variables: 3
TooManyMethods:
enabled: true
exclude: []
max_methods: 10
TooManyStatements:
enabled: true
exclude:
- each
- 'Inflecto#self.underscore'
- 'Inflecto#self.ordinalize'
max_statements: 5
UncommunicativeMethodName:
enabled: true
exclude: []
reject:
- !ruby/regexp /^[a-z]$/
- !ruby/regexp /[0-9]$/
- !ruby/regexp /[A-Z]/
accept: []
UncommunicativeModuleName:
enabled: true
exclude: []
reject:
- !ruby/regexp /^.$/
- !ruby/regexp /[0-9]$/
accept: []
UncommunicativeParameterName:
enabled: true
exclude: []
reject:
- !ruby/regexp /^.$/
- !ruby/regexp /[0-9]$/
- !ruby/regexp /[A-Z]/
accept: []
UncommunicativeVariableName:
enabled: true
exclude: []
reject:
- !ruby/regexp /^.$/
- !ruby/regexp /[0-9]$/
- !ruby/regexp /[A-Z]/
accept: []
UnusedParameters:
enabled: true
exclude: []
UtilityFunction:
enabled: true
exclude: []
max_helper_calls: 0

View File

@ -1,20 +0,0 @@
---
AbcMetricMethodCheck: { score: 70 }
AssignmentInConditionalCheck: { }
CaseMissingElseCheck: { }
ClassLineCountCheck: { line_count: 325 }
ClassNameCheck:
pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/
ClassVariableCheck: { }
CyclomaticComplexityBlockCheck: { complexity: 4 }
CyclomaticComplexityMethodCheck: { complexity: 4 }
EmptyRescueBodyCheck: { }
ForLoopCheck: { }
MethodLineCountCheck: { line_count: 16 }
MethodNameCheck:
pattern: !ruby/regexp /\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|<<|[+*&|-])\z/
ModuleLineCountCheck: { line_count: 331 }
ModuleNameCheck:
pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/
# TODO: decrease parameter_count to 2 or less
ParameterNumberCheck: { parameter_count: 3 }

View File

@ -1,7 +0,0 @@
AllCops:
Exclude:
- 'lib/**/*'
- 'spec/**/*'
- 'Gemfile'
- 'Guardfile'
- 'inflecto.gemspec'

View File

@ -1,2 +0,0 @@
---
threshold: 100.0

View File

@ -1,19 +0,0 @@
# -*- encoding: utf-8 -*-
Gem::Specification.new do |gem|
gem.name = 'inflecto'
gem.version = '0.1.0'
gem.authors = ['The rails, merb & datamapper team', 'Markus Schirp']
gem.email = ['mbj@seonic.net']
gem.description = 'Inflector for strings'
gem.summary = gem.description
gem.homepage = 'https://github.com/mbj/inflecto'
gem.license = 'MIT'
gem.require_paths = %w[lib]
gem.files = `git ls-files`.split($/)
gem.test_files = `git ls-files spec/{unit,integration}`.split($/)
gem.extra_rdoc_files = %w[LICENSE README.md TODO]
gem.required_ruby_version = '>= 1.9.3'
end

View File

@ -1,331 +0,0 @@
require 'set'
# The Inflecto transforms words from singular to plural, class names to table names, modularized class names to ones without,
# and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
# in inflections.rb.
#
# The Rails core team has stated patches for the inflections library will not be accepted
# in order to avoid breaking legacy applications which may be relying on errant inflections.
# If you discover an incorrect inflection and require it for your application, you'll need
# to correct it yourself (explained below).
module Inflecto
# Convert input to UpperCamelCase
#
# Will also convert '/' to '::' which is useful for converting paths to namespaces.
#
# @param [String] input
#
# @example
# Inflecto.camelize("data_mapper") # => "DataMapper"
# Inflecto.camelize("data_mapper/errors") # => "DataMapper::Errors"
#
# @return [String]
#
# @api public
#
def self.camelize(input)
input.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:\A|_)(.)/) { $1.upcase }
end
# Convert input to underscored, lowercase string
#
# Changes '::' to '/' to convert namespaces to paths.
#
# @param [String] input
#
# @example
# Inflecto.underscore("DataMapper") # => "data_mapper"
# Inflecto.underscore("DataMapper::Errors") # => "data_mapper/errors"
#
# @return [String]
#
# @api public
#
def self.underscore(input)
word = input.gsub(/::/, '/')
underscorize(word)
end
# Convert input underscores to dashes
#
# @param [String] input
#
# @example
# Inflecto.dasherize("foo_bar") # => "foo-bar"
#
# @return [String]
#
# @api public
#
def self.dasherize(input)
input.tr('_', '-')
end
# Return unscoped constant name
#
# @param [String] input
#
# @example
#
# Inflecto.demodulize("DataMapper::Error") # => "Error"
# Inflecto.demodulize("DataMapper") # => "DataMapper"
#
# @return [String]
#
# @api public
#
def self.demodulize(input)
input.split('::').last
end
# Creates a foreign key name
#
# @param [String] input
#
# @example
#
# Inflecto.foreign_key("Message") => "message_id"
#
# @return [String]
#
# @api public
#
def self.foreign_key(input)
"#{underscorize(demodulize(input))}_id"
end
# Find a constant with the name specified in the argument string
#
# The name is assumed to be the one of a top-level constant, constant scope of caller is ignored
#
# @param [String] input
#
# @example
#
# Inflecto.constantize("Module") # => Module
# Inflecto.constantize("DataMapper::Error") # => DataMapper::Error
#
# @return [Class, Module]
#
# @api public
#
def self.constantize(input)
names = input.split('::')
names.shift if names.first.empty?
names.inject(Object) do |constant, name|
if constant.const_defined?(name, false)
constant.const_get(name)
else
constant.const_missing(name)
end
end
end
ORDINALIZE_TH = (4..16).to_set.freeze
# Convert a number into an ordinal string
#
# @param [Fixnum] number
#
# @example
#
# ordinalize(1) # => "1st"
# ordinalize(2) # => "2nd"
# ordinalize(1002) # => "1002nd"
# ordinalize(1003) # => "1003rd"
#
# @return [String]
#
# @api public
#
def self.ordinalize(number)
abs_value = number.abs
if ORDINALIZE_TH.include?(abs_value % 100)
"#{number}th"
else
case abs_value % 10
when 1; "#{number}st"
when 2; "#{number}nd"
when 3; "#{number}rd"
end
end
end
# Yields a singleton instance of Inflecto::Inflections
#
# @example
#
# Inflecto.inflections do |inflect|
# inflect.uncountable "rails"
# end
#
# @return [Inflecto::Inflections]
#
# @api public
#
def self.inflections
instance = Inflections.instance
block_given? ? yield(instance) : instance
end
# Convert input word string to plural
#
# @param [String] word
#
# @example
#
# Inflecto.pluralize("post") # => "posts"
# Inflecto.pluralize("octopus") # => "octopi"
# Inflecto.pluralize("sheep") # => "sheep"
# Inflecto.pluralize("words") # => "words"
# Inflecto.pluralize("CamelOctopus") # => "CamelOctopi"
#
# @return [String]
#
# @api public
#
def self.pluralize(word)
return word if uncountable?(word)
inflections.plurals.apply_to(word)
end
# Convert word to singular
#
# @param [String] word
#
# @example
#
# Inflecto.singularize("posts") # => "post"
# Inflecto.singularize("octopi") # => "octopus"
# Inflecto.singularize("sheep") # => "sheep"
# Inflecto.singularize("word") # => "word"
# Inflecto.singularize("CamelOctopi") # => "CamelOctopus"
#
# @return [String]
#
# @api public
#
def self.singularize(word)
return word if uncountable?(word)
inflections.singulars.apply_to(word)
end
# Humanize string
#
# @param [String] input
#
# capitalizes the first word and turns underscores into spaces and strips a # trailing "_id", if any.
# Like +titleize+, this is meant for creating pretty output.
#
# @example
#
# Inflecto.humanize("employee_salary") # => "Employee salary"
# Inflecto.humanize("author_id") # => "Author"
#
# @return [String]
#
# @api public
#
def self.humanize(input)
result = inflections.humans.apply_to(input)
result.gsub!(/_id\z/, "")
result.tr!('_', " ")
result.capitalize!
result
end
# Tabelize input string
#
# @param [String] input
#
# Create the name of a table like Rails does for models to table names.
# This method # uses the +pluralize+ method on the last word in the string.
#
# @example
#
# Inflecto.tableize("RawScaledScorer") # => "raw_scaled_scorers"
# Inflecto.tableize("egg_and_ham") # => "egg_and_hams"
# Inflecto.tableize("fancyCategory") # => "fancy_categories"
#
# @return [String]
#
# @api public
#
def self.tableize(input)
word = input.gsub(/::/, '_')
pluralize(underscorize(word))
end
# Classify input
#
# Create a class name from a plural table name like Rails does for table names to models.
# Note that this returns a string and not a Class.
#
# To convert to an actual class # follow +classify+ with +constantize+.
#
# @examples:
#
# Inflecto.classify("egg_and_hams") # => "EggAndHam"
# Inflecto.classify("posts") # => "Post"
#
# # Singular names are not handled correctly:
# Inflecto.classify("business") # => "Busines"
#
# @return [String]
#
# @api public
#
def self.classify(table_name)
# strip out any leading schema name
camelize(singularize(table_name.sub(/.*\./, '')))
end
# Test if word is uncountable
#
# @example
#
# Inflecto.uncountable?('rice') #=> true
# Inflecto.uncountable?('apple') #=> false
#
# @param [String] word
#
# @return [Boolean]
# true, if word is uncountable
#
# @api public
#
def self.uncountable?(word)
word.empty? || inflections.uncountables.include?(word.downcase)
end
# Convert input to underscored, lowercase string
#
# Contains main logic for .underscore and .tableize
# Does nothing with '::' divider
#
# @param [String] input
#
# @example
# Inflecto.underscorize("DataMapper") # => "data_mapper"
# Inflecto.underscorize("DataMapper::Errors") # => "data_mapper::errors"
#
# @return [String]
#
# @api private
#
def self.underscorize(word)
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
word.tr!('-', '_')
word.downcase!
word
end
private_class_method :underscorize
end
require 'inflecto/rules_collection'
require 'inflecto/inflections'
require 'inflecto/defaults'

View File

@ -1,58 +0,0 @@
Inflecto.inflections do |inflect|
inflect.plural(/\z/, 's')
inflect.plural(/s\z/i, 's')
inflect.plural(/(ax|test)is\z/i, '\1es')
inflect.plural(/(octop|vir)us\z/i, '\1i')
inflect.plural(/(octop|vir)i\z/i, '\1i')
inflect.plural(/(alias|status)\z/i, '\1es')
inflect.plural(/(bu)s\z/i, '\1ses')
inflect.plural(/(buffal|tomat)o\z/i, '\1oes')
inflect.plural(/([ti])um\z/i, '\1a')
inflect.plural(/([ti])a\z/i, '\1a')
inflect.plural(/sis\z/i, 'ses')
inflect.plural(/(?:([^f])fe|([lr])f)\z/i, '\1\2ves')
inflect.plural(/(hive)\z/i, '\1s')
inflect.plural(/([^aeiouy]|qu)y\z/i, '\1ies')
inflect.plural(/(x|ch|ss|sh)\z/i, '\1es')
inflect.plural(/(matr|vert|ind)(?:ix|ex)\z/i, '\1ices')
inflect.plural(/([m|l])ouse\z/i, '\1ice')
inflect.plural(/([m|l])ice\z/i, '\1ice')
inflect.plural(/^(ox)\z/i, '\1en')
inflect.plural(/^(oxen)\z/i, '\1')
inflect.plural(/(quiz)\z/i, '\1zes')
inflect.singular(/s\z/i, '')
inflect.singular(/(n)ews\z/i, '\1ews')
inflect.singular(/([ti])a\z/i, '\1um')
inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses\z/i, '\1\2sis')
inflect.singular(/(^analy)ses\z/i, '\1sis')
inflect.singular(/([^f])ves\z/i, '\1fe')
inflect.singular(/(hive)s\z/i, '\1')
inflect.singular(/(tive)s\z/i, '\1')
inflect.singular(/([lr])ves\z/i, '\1f')
inflect.singular(/([^aeiouy]|qu)ies\z/i, '\1y')
inflect.singular(/(s)eries\z/i, '\1eries')
inflect.singular(/(m)ovies\z/i, '\1ovie')
inflect.singular(/(x|ch|ss|sh)es\z/i, '\1')
inflect.singular(/([m|l])ice\z/i, '\1ouse')
inflect.singular(/(bus)es\z/i, '\1')
inflect.singular(/(o)es\z/i, '\1')
inflect.singular(/(shoe)s\z/i, '\1')
inflect.singular(/(cris|ax|test)es\z/i, '\1is')
inflect.singular(/(octop|vir)i\z/i, '\1us')
inflect.singular(/(alias|status)es\z/i, '\1')
inflect.singular(/^(ox)en/i, '\1')
inflect.singular(/(vert|ind)ices\z/i, '\1ex')
inflect.singular(/(matr)ices\z/i, '\1ix')
inflect.singular(/(quiz)zes\z/i, '\1')
inflect.singular(/(database)s\z/i, '\1')
inflect.irregular('person', 'people')
inflect.irregular('man', 'men')
inflect.irregular('child', 'children')
inflect.irregular('sex', 'sexes')
inflect.irregular('move', 'moves')
inflect.irregular('cow', 'cows')
inflect.uncountable(%w(hovercraft moose milk rain Swiss grass equipment information rice money species series fish sheep jeans))
end

View File

@ -1,232 +0,0 @@
module Inflecto
# A singleton instance of this class is yielded by Inflecto.inflections, which can then be used to specify additional
# inflection rules. Examples:
#
# Inflecto.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1\2en'
# inflect.singular /^(ox)en/i, '\1'
#
# inflect.irregular 'octopus', 'octopi'
#
# inflect.uncountable "equipment"
# end
#
# New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
# pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
# already have been loaded.
#
class Inflections
# Return instance
#
# @return [Inflections]
#
# @api private
#
def self.instance
@__instance__ ||= new
end
# Return plurals
#
# @return [Array]
#
# @api private
#
attr_reader :plurals
# Return singulars
#
# @return [Array]
#
# @api private
#
attr_reader :singulars
# Return uncountables
#
# @return [Array]
#
# @api private
#
attr_reader :uncountables
# Return humans
#
# @return [Array]
#
# @api private
#
#
attr_reader :humans
# Initialize object
#
# @return [undefined]
#
# @api private
#
def initialize
@plurals = RulesCollection.new
@singulars = RulesCollection.new
@humans = RulesCollection.new
@uncountables = Set[]
end
# Add a new plural role
#
# Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
# The replacement should always be a string that may include references to the matched data from the rule.
#
# @param [String, Regexp] rule
# @param [String, Regexp] replacement
#
# @return [self]
#
# @api private
#
def plural(rule, replacement)
rule(rule, replacement, plurals)
self
end
# Add a new singular rule
#
# Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
# The replacement should always be a string that may include references to the matched data from the rule.
#
# @param [String, Regexp] rule
# @param [String, Regexp] replacement
#
# @return [self]
#
# @api private
#
def singular(rule, replacement)
rule(rule, replacement, singulars)
self
end
# Add a new irregular pluralization
#
# Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
# for strings, not regular expressions. You simply pass the irregular in singular and plural form.
#
# @example
#
# Inflecto.irregular('octopus', 'octopi')
# Inflecto.irregular('person', 'people')
#
# @param [String] singular
# @param [String] plural
#
# @return [self]
#
# @api private
#
def irregular(singular, plural)
uncountables.delete(singular)
uncountables.delete(plural)
add_irregular(singular, plural, plurals)
add_irregular(plural, singular, singulars)
self
end
# Add uncountable words
#
# Uncountable will not be inflected
#
# @example
#
# Inflecto.uncountable "money"
# Inflecto.uncountable "money", "information"
# Inflecto.uncountable %w( money information rice )
#
# @param [Enumerable<String>] words
#
# @return [self]
#
# @api private
#
def uncountable(*words)
uncountables.merge(words.flatten)
self
end
# Add humanize rule
#
# Specifies a humanized form of a string by a regular expression rule or by a string mapping.
# When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
# When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
#
# @example
# Inflecto.human(/_cnt$/i, '\1_count')
# Inflecto.human("legacy_col_person_name", "Name")
#
# @param [String, Regexp] rule
# @param [String, Regexp] replacement
#
# @api private
#
# @return [self]
#
def human(rule, replacement)
humans.insert(0, [rule, replacement])
self
end
# Clear all inflection rules
#
# @example
#
# Inflecto.clear
#
# @return [self]
#
# @api private
#
def clear
initialize
self
end
private
# Add irregular inflection
#
# @param [String] rule
# @param [String] replacement
#
# @return [undefined]
#
# @api private
#
def add_irregular(rule, replacement, target)
head, *tail = rule.chars.to_a
rule(/(#{head})#{tail.join}\z/i, '\1' + replacement[1..-1], target)
end
# Add a new rule
#
# @param [String, Regexp] rule
# @param [String, Regexp] replacement
# @param [Array] target
#
# @return [undefined]
#
# @api private
#
def rule(rule, replacement, target)
uncountables.delete(rule)
uncountables.delete(replacement)
target.insert(0, [rule, replacement])
end
end
end

View File

@ -1,20 +0,0 @@
module Inflecto
# Wraps inflections array
#
class RulesCollection < Array
# Applies first found rule to given word
#
# @param [String] word
#
# @return [String]
# modified word
#
# @api private
#
def apply_to(word)
result = word.dup
each { |rule, replacement| break if result.gsub!(rule, replacement) }
result
end
end
end

View File

@ -1,7 +0,0 @@
require 'spec_helper'
describe Inflecto, 'underscore' do
specify 'allows to create snake_case from CamelCase' do
expect(Inflecto.underscore('CamelCase')).to eql('camel_case')
end
end

View File

@ -1,7 +0,0 @@
--exclude-only "spec/,^/"
--sort coverage
--callsites
--xrefs
--profile
--text-summary
--failure-threshold 100

View File

@ -1,41 +0,0 @@
# encoding: utf-8
require 'devtools/spec_helper'
if ENV['COVERAGE'] == 'true'
require 'simplecov'
SimpleCov.start do
command_name 'spec:unit'
add_filter 'config'
add_filter 'spec'
minimum_coverage 100
end
end
require 'inflecto'
# require spec support files and shared behavior
Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file|
require file
end
# Mutant is already using inflecto. If it mutates inflecto methods then our
# tests start to fail. Instead, we force mutant to use unmutated version of
# inflecto.
if defined?(Mutant)
module Mutant
module Inflecto
::Inflecto.singleton_methods.each do |name|
define_singleton_method name, ::Inflecto.method(name).to_proc
end
end
end
end
RSpec.configure do |config|
# Helps to ensure that inflecto does not modify original input
def i(object)
object.freeze
end
end

View File

@ -1,19 +0,0 @@
require 'spec_helper'
describe Inflecto, '.camelize' do
it 'camelizes data_mapper as DataMapper' do
Inflecto.camelize(i('data_mapper')).should == 'DataMapper'
end
it 'camelizes merb as Merb' do
Inflecto.camelize(i('merb')).should == 'Merb'
end
it 'camelizes data_mapper/resource as DataMapper::Resource' do
Inflecto.camelize(i('data_mapper/resource')).should == 'DataMapper::Resource'
end
it 'camelizes data_mapper/associations/one_to_many as DataMapper::Associations::OneToMany' do
Inflecto.camelize(i('data_mapper/associations/one_to_many')).should == 'DataMapper::Associations::OneToMany'
end
end

View File

@ -1,19 +0,0 @@
require 'spec_helper'
describe Inflecto, '.classify' do
it 'classifies data_mapper as DataMapper' do
Inflecto.classify(i('data_mapper')).should == 'DataMapper'
end
it 'classifies data.mapper as Mapper' do
Inflecto.classify(i('data.mapper')).should == 'Mapper'
end
it 'classifies enlarged_testes as EnlargedTestis' do
Inflecto.classify(i('enlarged_testes')).should == 'EnlargedTestis'
end
it 'singularizes string first: classifies data_mappers as egg_and_hams as EggAndHam' do
Inflecto.classify(i('egg_and_hams')).should == 'EggAndHam'
end
end

View File

@ -1,60 +0,0 @@
require 'spec_helper'
describe Inflecto, '.constantize' do
it 'constantizes Module' do
Inflecto.constantize(i('Module')).should == Module
end
it 'constantizes ::Module' do
Inflecto.constantize(i('::Module')).should == Module
end
it 'constantizes nested constant Inflecto::Inflections' do
Inflecto.constantize(i('Inflecto::Inflections')).should == Inflecto::Inflections
end
it 'does not search ancestors' do
module Foo
class Bar
VAL = 10
end
class Baz < Bar; end
end
expect {
Inflecto.constantize(i('Foo::Baz::VAL'))
}.to raise_error(NameError)
end
it 'searches in const_missing' do
module Foo
class Bar
def self.const_missing(name)
name.to_s == 'Const' ? Baz : super
end
end
class Baz < Bar; end
def self.const_missing(name)
name.to_s == 'Autoloaded' ? Bar : super
end
end
Inflecto.constantize(i('Foo::Autoloaded::Const')).should == Foo::Baz
Inflecto.constantize(i('Foo::Bar::Const')).should == Foo::Baz
end
it 'raises exception when empty string given' do
expect {
Inflecto.constantize(i(''))
}.to raise_error(NameError)
end
it 'raises exception when constant not found' do
expect {
Inflecto.constantize(i('Qwerty'))
}.to raise_error(NameError)
end
end

View File

@ -1,7 +0,0 @@
require 'spec_helper'
describe Inflecto, '.dasherize' do
it 'dasherizes data_mapper_rspec as data-mapper-rspec' do
Inflecto.dasherize(i('data_mapper_rspec')).should == 'data-mapper-rspec'
end
end

View File

@ -1,11 +0,0 @@
require 'spec_helper'
describe Inflecto, '.demodulize' do
it 'demodulizes module name: DataMapper::Inflecto => Inflecto' do
Inflecto.demodulize(i('DataMapper::Inflecto')).should == 'Inflecto'
end
it 'demodulizes module name: A::B::C::D::E => E' do
Inflecto.demodulize(i('A::B::C::D::E')).should == 'E'
end
end

View File

@ -1,11 +0,0 @@
require 'spec_helper'
describe Inflecto, '.foreign_key' do
it 'adds _id to downcased string: Message => message_id' do
Inflecto.foreign_key(i('Message')).should == 'message_id'
end
it 'demodulizes string first: Admin::Post => post_id' do
Inflecto.foreign_key(i('Admin::Post')).should == 'post_id'
end
end

View File

@ -1,20 +0,0 @@
require 'spec_helper'
describe Inflecto, '.humanize' do
it 'replaces _ with space: humanizes employee_salary as Employee salary' do
Inflecto.humanize(i('employee_salary')).should == 'Employee salary'
end
it 'strips _id endings: humanizes author_id as Author' do
Inflecto.humanize(i('author_id')).should == 'Author'
end
it 'uses user added rules when possible' do
Inflecto.inflections do |inflect|
inflect.human('Question', 'Fancy question')
inflect.human('questionary', 'Questionnaire')
end
Inflecto.humanize(i('questionary')).should == 'Questionnaire'
end
end

View File

@ -1,21 +0,0 @@
require 'spec_helper'
describe Inflecto, '.inflections' do
context 'when block given' do
it 'yields inflections instance' do
yielded = nil
described_class.inflections do |inflect|
yielded = inflect
end
yielded.should be(Inflecto::Inflections.instance)
end
end
context 'when without block' do
subject { described_class.inflections }
it { should be(Inflecto::Inflections.instance) }
end
end

View File

@ -1,51 +0,0 @@
require 'spec_helper'
describe Inflecto, '.ordinalize' do
context 'when number ends with digit 1' do
it 'adds -th suffix when number ends with 11' do
[-1011, -111, -11, 11, 111, 1011].each do |number|
Inflecto.ordinalize(number).should eq("#{number}th")
end
end
it 'adds -st suffix when number does not end with 11' do
[-1001, -101, -21, -1, 1, 21, 101, 1001].each do |number|
Inflecto.ordinalize(number).should eq("#{number}st")
end
end
end
context 'when number ends with digit 2' do
it 'adds -th suffix when number ends with 12' do
[-1012, -112, -12, 12, 112, 1012].each do |number|
Inflecto.ordinalize(number).should eq("#{number}th")
end
end
it 'adds -nd suffix when number does not end with 12' do
[-1002, -102, -22, -2, 2, 22, 102, 1002].each do |number|
Inflecto.ordinalize(number).should eq("#{number}nd")
end
end
end
context 'when number ends with digit 3' do
it 'adds -th suffix when number ends with 13' do
[-1013, -113, -13, 13, 113, 1013].each do |number|
Inflecto.ordinalize(number).should eq("#{number}th")
end
end
it 'adds -rd suffix when number does not end with 13' do
[-1003, -103, -23, -3, 3, 23, 103, 1003].each do |number|
Inflecto.ordinalize(number).should eq("#{number}rd")
end
end
end
it 'ordinalizes other numbers with -th suffix' do
[-4, 4, 5, 6, 7, 8, 9, 10, 14, 15, 16].each do |number|
Inflecto.ordinalize(number).should eq("#{number}th")
end
end
end

View File

@ -1,193 +0,0 @@
require 'spec_helper'
describe Inflecto, '.pluralize' do
SINGULAR_TO_PLURAL = {
'equipment' => 'equipment',
'information' => 'information',
'money' => 'money',
'species' => 'species',
'series' => 'series',
'fish' => 'fish',
'sheep' => 'sheep',
'news' => 'news',
'matrix' => 'matrices',
'life' => 'lives',
'wife' => 'wives',
'alias' => 'aliases',
'status' => 'statuses',
'axis' => 'axes',
'crisis' => 'crises',
'testis' => 'testes',
'child' => 'children',
'person' => 'people',
'tomato' => 'tomatoes',
'buffalo' => 'buffaloes',
'quiz' => 'quizzes',
'vertex' => 'vertices',
'index' => 'indices',
'ox' => 'oxen',
'mouse' => 'mice',
'louse' => 'lice',
'thesis' => 'theses',
'analysis' => 'analyses',
'octopus' => 'octopi',
'grass' => 'grass',
'drive' => 'drives',
# ==== bugs, typos and reported issues
# ==== rules and most common cases
'forum' => 'forums',
'hive' => 'hives',
'athlete' => 'athletes',
'dwarf' => 'dwarves',
'man' => 'men',
'woman' => 'women',
'sportsman' => 'sportsmen',
'branch' => 'branches',
'crunch' => 'crunches',
'trash' => 'trashes',
'mash' => 'mashes',
'cross' => 'crosses',
'erratum' => 'errata',
# FIXME: add -ia => -ium cases
# FIXME: add -ra => -rum cases
'ray' => 'rays',
'spray' => 'sprays',
# Merriam-Webster dictionary says
# preys is correct, too.
'prey' => 'preys',
'toy' => 'toys',
'joy' => 'joys',
'buy' => 'buys',
'guy' => 'guys',
'cry' => 'cries',
'fly' => 'flies',
'fox' => 'foxes',
'elf' => 'elves',
'shelf' => 'shelves',
'cat' => 'cats',
'rat' => 'rats',
'rose' => 'roses',
'project' => 'projects',
'post' => 'posts',
'article' => 'articles',
'location' => 'locations',
'friend' => 'friends',
'link' => 'links',
'url' => 'urls',
'account' => 'accounts',
'server' => 'servers',
'fruit' => 'fruits',
'map' => 'maps',
'income' => 'incomes',
'ping' => 'pings',
'event' => 'events',
'proof' => 'proofs',
'typo' => 'typos',
'attachment' => 'attachments',
'download' => 'downloads',
'asset' => 'assets',
'job' => 'jobs',
'city' => 'cities',
'package' => 'packages',
'commit' => 'commits',
'version' => 'versions',
'document' => 'documents',
'edition' => 'editions',
'movie' => 'movies',
'song' => 'songs',
'invoice' => 'invoices',
'product' => 'products',
'book' => 'books',
'ticket' => 'tickets',
'game' => 'games',
'tournament' => 'tournaments',
'prize' => 'prizes',
'price' => 'prices',
'installation' => 'installations',
'date' => 'dates',
'schedule' => 'schedules',
'arena' => 'arenas',
'spam' => 'spams',
'bus' => 'buses',
'rice' => 'rice',
# Some specs from Rails
'search' => 'searches',
'switch' => 'switches',
'fix' => 'fixes',
'box' => 'boxes',
'process' => 'processes',
'address' => 'addresses',
'case' => 'cases',
'stack' => 'stacks',
'wish' => 'wishes',
'category' => 'categories',
'query' => 'queries',
'ability' => 'abilities',
'agency' => 'agencies',
'archive' => 'archives',
'safe' => 'saves',
'half' => 'halves',
'move' => 'moves',
'salesperson' => 'salespeople',
'spokesman' => 'spokesmen',
'basis' => 'bases',
'diagnosis' => 'diagnoses',
'diagnosis_a' => 'diagnosis_as',
'datum' => 'data',
'medium' => 'media',
'node_child' => 'node_children',
'experience' => 'experiences',
'day' => 'days',
'comment' => 'comments',
'foobar' => 'foobars',
'newsletter' => 'newsletters',
'old_news' => 'old_news',
'perspective' => 'perspectives',
'photo' => 'photos',
'status_code' => 'status_codes',
'house' => 'houses',
'portfolio' => 'portfolios',
'matrix_fu' => 'matrix_fus',
'axis' => 'axes',
'shoe' => 'shoes',
'horse' => 'horses',
'edge' => 'edges',
'cow' => 'cows',
}
# Missing rule or exception?
PENDING = {
'virus' => 'viruses',
'torpedo' => 'torpedoes',
'Swiss' => 'Swiss',
'goose' => 'geese',
'milk' => 'milk',
'plus' => 'plusses',
'thesaurus' => 'thesauri',
'thief' => 'thieves',
'hovercraft' => 'hovercraft',
'zero' => 'zeroes',
'rain' => 'rain',
'cactus' => 'cacti',
'moose' => 'moose',
'criterion' => 'criteria',
'potato' => 'potatoes',
'phenomenon' => 'phenomena',
'hero' => 'heroes',
}
PENDING.each do |singular, plural|
pending "missing exception or rule for #{singular} => #{plural}"
end
SINGULAR_TO_PLURAL.each do |singular, plural|
it "pluralizes #{singular} => #{plural}" do
Inflecto.pluralize(i(singular)).should eql(plural)
end
end
end

View File

@ -1,153 +0,0 @@
require 'spec_helper'
describe Inflecto, '.singularize' do
# ==== exceptional cases
PLURAL_TO_SINGULAR = {
'equipment' => 'equipment',
'mysql' => 'mysql',
'information' => 'information',
'money' => 'money',
'species' => 'species',
'series' => 'series',
'fish' => 'fish',
'sheep' => 'sheep',
'news' => 'news',
'rain' => 'rain',
'milk' => 'milk',
'moose' => 'moose',
'hovercraft' => 'hovercraft',
'matrices' => 'matrix',
'lives' => 'life',
'wives' => 'wife',
'aliases' => 'alias',
'statuses' => 'status',
'axes' => 'axis',
'crises' => 'crisis',
'testes' => 'testis',
'children' => 'child',
'people' => 'person',
'potatoes' => 'potato',
'tomatoes' => 'tomato',
'buffaloes' => 'buffalo',
'torpedoes' => 'torpedo',
'quizzes' => 'quiz',
'vertices' => 'vertex',
'indices' => 'index',
'indexes' => 'index',
'oxen' => 'ox',
'mice' => 'mouse',
'lice' => 'louse',
'theses' => 'thesis',
'analyses' => 'analysis',
'octopi' => 'octopus',
'grass' => 'grass',
# ==== bugs, typos and reported issues
# ==== rules
'forums' => 'forum',
'hives' => 'hive',
'athletes' => 'athlete',
'dwarves' => 'dwarf',
'heroes' => 'hero',
'zeroes' => 'zero',
'men' => 'man',
'women' => 'woman',
'sportsmen' => 'sportsman',
'branches' => 'branch',
'crunches' => 'crunch',
'trashes' => 'trash',
'mashes' => 'mash',
'crosses' => 'cross',
'errata' => 'erratum',
# FIXME: add -ia => -ium cases
# FIXME: add -ra => -rum cases
'rays' => 'ray',
'sprays' => 'spray',
# Merriam-Webster dictionary says
# preys is correct, too.
'preys' => 'prey',
'toys' => 'toy',
'joys' => 'joy',
'buys' => 'buy',
'guys' => 'guy',
'cries' => 'cry',
'flies' => 'fly',
'foxes' => 'fox',
'elves' => 'elf',
'shelves' => 'shelf',
'cats' => 'cat',
'rats' => 'rat',
'roses' => 'rose',
'projects' => 'project',
'posts' => 'post',
'articles' => 'article',
'locations' => 'location',
'friends' => 'friend',
'links' => 'link',
'urls' => 'url',
'accounts' => 'account',
'servers' => 'server',
'fruits' => 'fruit',
'maps' => 'map',
'incomes' => 'income',
'pings' => 'ping',
'events' => 'event',
'proofs' => 'proof',
'typos' => 'typo',
'attachments' => 'attachment',
'downloads' => 'download',
'assets' => 'asset',
'jobs' => 'job',
'cities' => 'city',
'packages' => 'package',
'commits' => 'commit',
'versions' => 'version',
'documents' => 'document',
'editions' => 'edition',
'movies' => 'movie',
'songs' => 'song',
'invoices' => 'invoice',
'products' => 'product',
'books' => 'book',
'tickets' => 'ticket',
'games' => 'game',
'tournaments' => 'tournament',
'prizes' => 'prize',
'prices' => 'price',
'installations' => 'installation',
'dates' => 'date',
'schedules' => 'schedule',
'arenas' => 'arena',
'spams' => 'spam',
'rice' => 'rice'
}
# Missing exceptions or missing rules?
PENDING = {
'cacti' => 'cactus',
'cactuses' => 'cactus',
'thesauri' => 'thesaurus',
'geese' => 'goose',
'phenomena' => 'phenomenon',
'Swiss' => 'Swiss',
'drives' => 'drive',
'pluses' => 'plus',
'thieves' => 'thief',
'criteria' => 'criterion',
'postgres' => 'postgres'
}
PENDING.each do |plural, singular|
pending "missing rule or exception for #{plural} => #{singular}"
end
PLURAL_TO_SINGULAR.each do |plural, singular|
it "should signularize #{plural} => #{singular}" do
Inflecto.singularize(i(plural)).should eql(singular)
end
end
end

View File

@ -1,27 +0,0 @@
require 'spec_helper'
describe Inflecto, '.tableize' do
it 'pluralizes last word in snake_case strings: fancy_category => fancy_categories' do
Inflecto.tableize(i('fancy_category')).should == 'fancy_categories'
end
it 'underscores CamelCase strings before pluralization: enlarged_testis => enlarged_testes' do
Inflecto.tableize(i('enlarged_testis')).should == 'enlarged_testes'
end
it 'underscores CamelCase strings before pluralization: FancyCategory => fancy_categories' do
Inflecto.tableize(i('FancyCategory')).should == 'fancy_categories'
end
it 'underscores CamelCase strings before pluralization: EnlargedTestis => enlarged_testes' do
Inflecto.tableize(i('EnlargedTestis')).should == 'enlarged_testes'
end
it 'replaces :: with underscores: My::Fancy::Category => my_fancy_categories' do
Inflecto.tableize(i('My::Fancy::Category')).should == 'my_fancy_categories'
end
it 'underscores CamelCase strings before pluralization: Enlarged::Testis => enlarged_testes' do
Inflecto.tableize(i('Enlarged::Testis')).should == 'enlarged_testes'
end
end

View File

@ -1,19 +0,0 @@
require 'spec_helper'
describe Inflecto, '.uncountable?' do
it 'truthy when empty string' do
Inflecto.uncountable?('').should be(true)
end
it 'truthy when word is present in list' do
Inflecto.uncountable?('grass').should be(true)
end
it 'falsy when word is not present in list' do
Inflecto.uncountable?('user').should be(false)
end
it 'truthy when word is present in list but in different case' do
Inflecto.uncountable?('FiSH').should be(true)
end
end

View File

@ -1,35 +0,0 @@
require 'spec_helper'
describe Inflecto, '.underscore' do
it 'underscores DataMapper as data_mapper' do
Inflecto.underscore(i('DataMapper')).should == 'data_mapper'
end
it 'underscores Merb as merb' do
Inflecto.underscore(i('Merb')).should == 'merb'
end
it 'underscores DataMapper::Resource as data_mapper/resource' do
Inflecto.underscore(i('DataMapper::Resource')).should == 'data_mapper/resource'
end
it 'underscores Merb::BootLoader::Rackup as merb/boot_loader/rackup' do
Inflecto.underscore(i('Merb::BootLoader::Rackup')).should == 'merb/boot_loader/rackup'
end
it 'underscores data-mapper as data_mapper' do
Inflecto.underscore(i('data-mapper')).should == 'data_mapper'
end
it 'underscores CLI as cli' do
Inflecto.underscore(i('CLI')).should == 'cli'
end
it 'underscores castleKing as castle_king' do
Inflecto.underscore(i('castleKing')).should == 'castle_king'
end
it 'underscores CLIRunner as cli_runner' do
Inflecto.underscore(i('CLIRunner')).should == 'cli_runner'
end
end

View File

@ -1,11 +0,0 @@
require 'spec_helper'
describe Inflecto::Inflections, '.instance' do
subject { described_class.instance }
it { should be_instance_of(described_class) }
it 'returns always same instance' do
subject.should equal(described_class.instance)
end
end

View File

@ -1,21 +0,0 @@
require 'spec_helper'
describe Inflecto::Inflections, '#clear' do
subject { object.clear }
let(:object) { described_class.new }
before do
object.uncountable('apple')
object.plural('people', 'person')
object.singular('apple', 'apples')
object.human('person_name', 'Name')
end
it { should be(object) }
its(:plurals) { should be_empty }
its(:singulars) { should be_empty }
its(:uncountables) { should be_empty }
its(:humans) { should be_empty }
end

View File

@ -1,22 +0,0 @@
require 'spec_helper'
describe Inflecto::Inflections, '#human' do
subject { object.human(rule, replacement) }
let(:object) { described_class.new }
let(:rule) { double(:rule) }
let(:replacement) { double(:replacement) }
it { should be(object) }
its(:humans) { should eq([[rule, replacement]]) }
it 'adds rule as a first item' do
subject
object.human(double, double)
humans = object.humans
humans.size.should be(2)
humans.last.should eq([rule, replacement])
end
end

View File

@ -1,30 +0,0 @@
require 'spec_helper'
describe Inflecto::Inflections, '#irregular' do
subject { object.irregular(singular, plural) }
let(:object) { described_class.new }
let(:singular) { 'person' }
let(:plural) { 'people' }
it { should be(object) }
its(:plurals) { should include([/(p)erson\z/i, "\\1eople"]) }
its(:singulars) { should include([/(p)eople\z/i, "\\1erson"]) }
context 'when singular form is in uncountables' do
before { object.uncountable('person') }
it 'removes it from uncountables' do
subject.uncountables.should_not include('person')
end
end
context 'when plural form is in uncountables' do
before { object.uncountable('people') }
it 'removes it from uncountables' do
subject.uncountables.should_not include('people')
end
end
end

View File

@ -1,38 +0,0 @@
require 'spec_helper'
describe Inflecto::Inflections, '#plural' do
subject { object.plural(rule, replacement) }
let(:object) { described_class.new }
let(:rule) { double(:rule) }
let(:replacement) { double(:replacement) }
it { should be(object) }
its(:plurals) { should eq([[rule, replacement]]) }
it 'adds rule as a first item' do
subject
object.plural(double, double)
plurals = object.plurals
plurals.size.should be(2)
plurals.last.should eq([rule, replacement])
end
context 'when rule is in the uncountables' do
before { object.uncountable(rule) }
it 'removes it from uncountables' do
subject.uncountables.should eql(Set[])
end
end
context 'when replacement is in the uncountables' do
before { object.uncountable(replacement) }
it 'removes it from uncountables' do
subject.uncountables.should eql(Set[])
end
end
end

View File

@ -1,38 +0,0 @@
require 'spec_helper'
describe Inflecto::Inflections, '#singular' do
subject { object.singular(rule, replacement) }
let(:object) { described_class.new }
let(:rule) { double(:rule) }
let(:replacement) { double(:replacement) }
it { should be(object) }
its(:singulars) { should eq([[rule, replacement]]) }
it 'adds rule as a first item' do
subject
object.singular(double, double)
singulars = object.singulars
singulars.size.should be(2)
singulars.last.should eq([rule, replacement])
end
context 'when rule is in the uncountables' do
before { object.uncountable(rule) }
it 'removes it from uncountables' do
subject.uncountables.should eql(Set[])
end
end
context 'when replacement is in the uncountables' do
before { object.uncountable(replacement) }
it 'removes it from uncountables' do
subject.uncountables.should eql(Set[])
end
end
end

View File

@ -1,20 +0,0 @@
require 'spec_helper'
describe Inflecto::Inflections, '#uncountable' do
let(:object) { described_class.new }
context 'when word given' do
subject { object.uncountable('water') }
its(:uncountables) { should eql(Set['water']) }
end
context 'when array of words given' do
subject { object.uncountable(['water', 'sugar']) }
its(:uncountables) { should eql(Set['water', 'sugar']) }
end
context 'when multiple words given' do
subject { object.uncountable('water', 'sugar') }
its(:uncountables) { should eql(Set['water', 'sugar']) }
end
end

View File

@ -1,17 +0,0 @@
require 'spec_helper'
describe Inflecto::RulesCollection, '#apply_to' do
subject { described_class.new(rules).apply_to(input) }
let(:rules) do
[
['question', 'questions'],
['quest', 'quests']
]
end
let(:input) { 'question' }
it { should eq('questions') }
it { should_not equal(input) }
end