pax_global_header00006660000000000000000000000064140670270420014514gustar00rootroot0000000000000052 comment=ad49b481fb157e8facf994d8a6a8c5dc4747d16f dry-inflector-0.2.1/000077500000000000000000000000001406702704200142755ustar00rootroot00000000000000dry-inflector-0.2.1/.action_hero.yml000066400000000000000000000010501406702704200173640ustar00rootroot00000000000000# This is a config synced from dry-rb/template-gem repo sources: - repo: dry-rb/template-gem sync: - ".action_hero.yml.erb" - ".devtools/templates/*.sync:${{dir}}/${{name}}" - ".github/**/*.*" - "gemspec.erb:dry-inflector.gemspec" - "spec/support/*" - "CODE_OF_CONDUCT.md" - "CONTRIBUTING.md" - "CODEOWNERS" - "LICENSE.erb" - "README.md.erb" - "Gemfile.devtools" - ".rspec" - ".rubocop.yml" - repo: action-hero/workflows sync: - ".github/workflows/*.yml" dry-inflector-0.2.1/.devtools/000077500000000000000000000000001406702704200162125ustar00rootroot00000000000000dry-inflector-0.2.1/.devtools/templates/000077500000000000000000000000001406702704200202105ustar00rootroot00000000000000dry-inflector-0.2.1/.devtools/templates/changelog.erb000066400000000000000000000013711406702704200226330ustar00rootroot00000000000000 <% releases.each_with_index do |r, idx| %> ## <%= r.version %> <%= r.date %> <% if r.summary %> <%= r.summary %> <% end %> <% if r.added? %> ### Added <% r.added.each do |log| %> - <%= log %> <% end %> <% end %> <% if r.fixed? %> ### Fixed <% r.fixed.each do |log| %> - <%= log %> <% end %> <% end %> <% if r.changed? %> ### Changed <% r.changed.each do |log| %> - <%= log %> <% end %> <% end %> <% curr_ver = r.date ? "v#{r.version}" : 'master' %> <% prev_rel = releases[idx + 1] %> <% if prev_rel %> <% ver_range = "v#{prev_rel.version}...#{curr_ver}" %> [Compare <%=ver_range%>](https://github.com/dry-rb/<%= project.name %>/compare/<%=ver_range%>) <% end %> <% end %> dry-inflector-0.2.1/.devtools/templates/release.erb000066400000000000000000000013171406702704200223240ustar00rootroot00000000000000 <% if latest_release.summary %> <%= latest_release.summary %> <% end %> <% if latest_release.added? %> ### Added <% latest_release.added.each do |log| %> - <%= log %> <% end %> <% end %> <% if latest_release.fixed? %> ### Fixed <% latest_release.fixed.each do |log| %> - <%= log %> <% end %> <% end %> <% if latest_release.changed? %> ### Changed <% latest_release.changed.each do |log| %> - <%= log %> <% end %> <% end %> <% if previous_release %> <% ver_range = "v#{previous_release.version}...v#{latest_release.version}" %> [Compare <%=ver_range%>](https://github.com/dry-rb/<%= project.name %>/compare/<%=ver_range%>) <% end %> dry-inflector-0.2.1/.github/000077500000000000000000000000001406702704200156355ustar00rootroot00000000000000dry-inflector-0.2.1/.github/FUNDING.yml000066400000000000000000000000441406702704200174500ustar00rootroot00000000000000github: [jodosha, solnic, timriley] dry-inflector-0.2.1/.github/ISSUE_TEMPLATE/000077500000000000000000000000001406702704200200205ustar00rootroot00000000000000dry-inflector-0.2.1/.github/ISSUE_TEMPLATE/bug-report.md000066400000000000000000000007521406702704200224340ustar00rootroot00000000000000--- name: "\U0001F41B Bug report" about: See CONTRIBUTING.md for more information title: '' labels: bug, help wanted assignees: '' --- ## Describe the bug A clear and concise description of what the bug is. ## To Reproduce Provide detailed steps to reproduce, **an executable script would be best**. ## Expected behavior A clear and concise description of what you expected to happen. ## My environment - Affects my production application: **YES/NO** - Ruby version: ... - OS: ... dry-inflector-0.2.1/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000002361406702704200220110ustar00rootroot00000000000000blank_issues_enabled: false contact_links: - name: Community Support url: https://discourse.dry-rb.org about: Please ask and answer questions here. dry-inflector-0.2.1/.github/SUPPORT.md000066400000000000000000000004441406702704200173350ustar00rootroot00000000000000## Support If you need help with any of the dry-rb libraries, feel free to ask questions on our [discussion forum](https://discourse.dry-rb.org/). This is the best place to seek help. Make sure to search for a potential solution in past threads before posting your question. Thanks! :heart: dry-inflector-0.2.1/.github/workflows/000077500000000000000000000000001406702704200176725ustar00rootroot00000000000000dry-inflector-0.2.1/.github/workflows/ci.yml000066400000000000000000000043321406702704200210120ustar00rootroot00000000000000# This file is synced from dry-rb/template-gem repo name: CI on: push: paths: - ".github/workflows/ci.yml" - "lib/**" - "*.gemspec" - "spec/**" - "Rakefile" - "Gemfile" - "Gemfile.devtools" - ".rubocop.yml" - "project.yml" pull_request: branches: - master create: jobs: tests: runs-on: ubuntu-latest name: Tests strategy: fail-fast: false matrix: ruby: - "3.0" - "2.7" - "2.6" include: - ruby: "3.0" coverage: "true" env: COVERAGE: ${{matrix.coverage}} COVERAGE_TOKEN: ${{secrets.CODACY_PROJECT_TOKEN}} steps: - name: Checkout uses: actions/checkout@v1 - name: Install package dependencies run: "[ -e $APT_DEPS ] || sudo apt-get install -y --no-install-recommends $APT_DEPS" - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{matrix.ruby}} bundler-cache: true - name: Run all tests run: bundle exec rake - name: Run codacy-coverage-reporter uses: codacy/codacy-coverage-reporter-action@master if: env.COVERAGE == 'true' && env.COVERAGE_TOKEN != '' with: project-token: ${{secrets.CODACY_PROJECT_TOKEN}} coverage-reports: coverage/coverage.xml release: runs-on: ubuntu-latest if: contains(github.ref, 'tags') && github.event_name == 'create' needs: tests env: GITHUB_LOGIN: dry-bot GITHUB_TOKEN: ${{secrets.GH_PAT}} steps: - uses: actions/checkout@v1 - name: Install package dependencies run: "[ -e $APT_DEPS ] || sudo apt-get install -y --no-install-recommends $APT_DEPS" - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: 2.6 - name: Install dependencies run: gem install ossy --no-document - name: Trigger release workflow run: | tag=$(echo $GITHUB_REF | cut -d / -f 3) ossy gh w dry-rb/devtools release --payload "{\"tag\":\"$tag\",\"sha\":\"${{github.sha}}\",\"tag_creator\":\"$GITHUB_ACTOR\",\"repo\":\"$GITHUB_REPOSITORY\",\"repo_name\":\"${{github.event.repository.name}}\"}" dry-inflector-0.2.1/.github/workflows/docsite.yml000066400000000000000000000032651406702704200220550ustar00rootroot00000000000000# this file is managed by dry-rb/devtools project name: docsite on: push: paths: - docsite/** - .github/workflows/docsite.yml branches: - master - release-** tags: jobs: update-docs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - run: | git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/* - name: Set up Ruby uses: actions/setup-ruby@v1 with: ruby-version: "2.6.x" - name: Set up git user run: | git config --local user.email "dry-bot@dry-rb.org" git config --local user.name "dry-bot" - name: Install dependencies run: gem install ossy --no-document - name: Update release branches run: | branches=`git log --format=%B -n 1 $GITHUB_SHA | grep "docsite:release-" || echo "nothing"` if [[ ! $branches -eq "nothing" ]]; then for b in $branches do name=`echo $b | ruby -e 'puts gets[/:(.+)/, 1].gsub(/\s+/, "")'` echo "merging $GITHUB_SHA to $name" git checkout -b $name --track origin/$name echo `git log -n 1` git cherry-pick $GITHUB_SHA -m 1 done git push --all "https://dry-bot:${{secrets.GH_PAT}}@github.com/$GITHUB_REPOSITORY.git" git checkout master else echo "no need to update branches" fi - name: Trigger dry-rb.org deploy env: GITHUB_LOGIN: dry-bot GITHUB_TOKEN: ${{secrets.GH_PAT}} run: ossy github workflow dry-rb/dry-rb.org ci dry-inflector-0.2.1/.github/workflows/rubocop.yml000066400000000000000000000017071406702704200220730ustar00rootroot00000000000000name: "RuboCop" on: push: branches: - "main" - "master" paths: - "**/*.rb" - "**/*.rake" - "Rakefile" - "Gemfile*" - ".rubocop.yml" pull_request: branches: - "main" - "master" types: - "opened" - "synchronize" workflow_dispatch: jobs: run: runs-on: ubuntu-latest name: ${{ matrix.type }} strategy: fail-fast: false matrix: type: ["Style", "Layout", "Naming", "Lint", "Metrics", "Security"] steps: - name: Clone uses: actions/checkout@v2 - name: Get git diff id: get_diff uses: technote-space/get-diff-action@v4 with: PATTERNS: | **/*.rb **/*.rake Gemfile Rakefile - name: Check ${{ matrix.type }} uses: action-hero/actions/rubocop@main if: ${{ env.GIT_DIFF != '' }} with: diff: ${{ env.GIT_DIFF }} type: ${{ matrix.type }} dry-inflector-0.2.1/.github/workflows/sync_configs.yml000066400000000000000000000027161406702704200231070ustar00rootroot00000000000000# This file is synced from dry-rb/template-gem repo name: sync on: repository_dispatch: push: branches: - "master" jobs: main: runs-on: ubuntu-latest if: (github.event_name == 'repository_dispatch' && github.event.action == 'sync_configs') || github.event_name != 'repository_dispatch' env: GITHUB_LOGIN: dry-bot GITHUB_TOKEN: ${{ secrets.GH_PAT }} steps: - name: Checkout ${{github.repository}} uses: actions/checkout@v1 - name: Checkout devtools uses: actions/checkout@v2 with: repository: dry-rb/devtools path: tmp/devtools - name: Setup git user run: | git config --local user.email "dry-bot@dry-rb.org" git config --local user.name "dry-bot" - name: Set up Ruby uses: actions/setup-ruby@v1 with: ruby-version: "2.6" - name: Install dependencies run: gem install ossy --no-document - name: Update changelog.yml from commit run: tmp/devtools/bin/update-changelog-from-commit $GITHUB_SHA - name: Compile CHANGELOG.md run: tmp/devtools/bin/compile-changelog - name: Commit run: | git add -A git commit -m "[devtools] sync" || echo "nothing to commit" - name: Push changes run: | git pull --rebase origin master git push https://dry-bot:${{secrets.GH_PAT}}@github.com/${{github.repository}}.git HEAD:master dry-inflector-0.2.1/.gitignore000066400000000000000000000001631406702704200162650ustar00rootroot00000000000000/.bundle/ /.yardoc /Gemfile.lock /_yardoc/ /coverage/ /doc/ /pkg/ /spec/reports/ /tmp/ .DS_Store # editors .vscode dry-inflector-0.2.1/.rspec000066400000000000000000000000701406702704200154070ustar00rootroot00000000000000--color --require spec_helper --order random --warnings dry-inflector-0.2.1/.rubocop.yml000066400000000000000000000056731406702704200165620ustar00rootroot00000000000000# This is a config synced from dry-rb/template-gem repo AllCops: TargetRubyVersion: 2.6 NewCops: enable Exclude: - spec/support/coverage.rb - spec/support/warnings.rb - spec/support/rspec_options.rb - Gemfile.devtools - "*.gemspec" Layout/SpaceAroundMethodCallOperator: Enabled: false Layout/SpaceInLambdaLiteral: Enabled: false Layout/MultilineMethodCallIndentation: Enabled: true EnforcedStyle: indented Layout/FirstArrayElementIndentation: EnforcedStyle: consistent Layout/SpaceInsideHashLiteralBraces: Enabled: true EnforcedStyle: no_space EnforcedStyleForEmptyBraces: no_space Layout/LineLength: Max: 100 Exclude: - "spec/**/*.rb" Lint/AmbiguousBlockAssociation: Enabled: true # because 'expect { foo }.to change { bar }' is fine Exclude: - "spec/**/*.rb" Lint/BooleanSymbol: Enabled: false Lint/ConstantDefinitionInBlock: Exclude: - "spec/**/*.rb" Lint/RaiseException: Enabled: false Lint/StructNewOverride: Enabled: false Lint/SuppressedException: Exclude: - "spec/spec_helper.rb" Naming/PredicateName: Enabled: false Naming/FileName: Exclude: - "lib/*-*.rb" Naming/MethodName: Enabled: false Naming/MethodParameterName: Enabled: true Exclude: - "spec/**/*.rb" Naming/MemoizedInstanceVariableName: Enabled: false Metrics/MethodLength: Enabled: false Metrics/ClassLength: Enabled: false Metrics/BlockLength: Enabled: false Metrics/AbcSize: Max: 25 Metrics/CyclomaticComplexity: Enabled: true Max: 12 Style/ExponentialNotation: Enabled: false Style/HashEachMethods: Enabled: false Style/HashTransformKeys: Enabled: false Style/HashTransformValues: Enabled: false Style/AccessModifierDeclarations: Enabled: false Style/Alias: Enabled: true EnforcedStyle: prefer_alias_method Style/AsciiComments: Enabled: false Style/BlockDelimiters: Enabled: false Style/ClassAndModuleChildren: Exclude: - "spec/**/*.rb" Style/ConditionalAssignment: Enabled: false Style/DateTime: Enabled: false Style/Documentation: Enabled: false Style/EachWithObject: Enabled: false Style/FormatString: Enabled: false Style/GuardClause: Enabled: false Style/IfUnlessModifier: Enabled: false Style/Lambda: Enabled: false Style/LambdaCall: Enabled: false Style/ParallelAssignment: Enabled: false Style/StabbyLambdaParentheses: Enabled: false Style/StringLiterals: Enabled: true EnforcedStyle: double_quotes ConsistentQuotesInMultiline: false Style/StringLiteralsInInterpolation: Enabled: true EnforcedStyle: double_quotes Style/SymbolArray: Exclude: - "spec/**/*.rb" Style/TrailingUnderscoreVariable: Enabled: false Style/MultipleComparison: Enabled: false Style/Next: Enabled: false Lint/UnusedBlockArgument: Exclude: - "spec/**/*.rb" Metrics/ParameterLists: Exclude: - "spec/**/*.rb" Lint/EmptyBlock: Exclude: - "spec/**/*.rb" Naming/ConstantName: Exclude: - "spec/**/*.rb" dry-inflector-0.2.1/CHANGELOG.md000066400000000000000000000036311406702704200161110ustar00rootroot00000000000000 ## unreleased ### Fixed - Fix singularizing -us suffix (issue #33 via #38) (@cllns) [Compare v0.2.0...master](https://github.com/dry-rb/dry-inflector/compare/v0.2.0...master) ## 0.2.0 2019-10-13 ### Added - [Abinoam P. Marques Jr. & Andrii Savchenko] Introduced `Dry::Inflector#camelize_upper` and `Dry::Inflector#camelize_lower`. `Dry::Inflector#camelize` is now an alias for `Dry::Inflector#camelize_upper`. - ```ruby - inflector.camelize_upper("data_mapper") # => "DataMapper" - inflector.camelize_lower("data_mapper") # => "dataMapper" - ``` ### Fixed - [ecnal] Fixed singularization rules for words like "alias" or "status" [Compare v0.1.2...v0.2.0](https://github.com/dry-rb/dry-inflector/compare/v0.1.2...v0.2.0) ## 0.1.2 2018-04-25 ### Added - [Gustavo Caso & Nikita Shilnikov] Added support for acronyms [Compare v0.1.1...v0.1.2](https://github.com/dry-rb/dry-inflector/compare/v0.1.1...v0.1.2) ## 0.1.1 2017-11-18 ### Fixed - [Luca Guidi & Abinoam P. Marques Jr.] Ensure `Dry::Inflector#ordinalize` to work for all the numbers from 0 to 100 [Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-inflector/compare/v0.1.0...v0.1.1) ## 0.1.0 2017-11-17 ### Added - [Luca Guidi] Introduced `Dry::Inflector#pluralize` - [Luca Guidi] Introduced `Dry::Inflector#singularize` - [Luca Guidi] Introduced `Dry::Inflector#camelize` - [Luca Guidi] Introduced `Dry::Inflector#classify` - [Luca Guidi] Introduced `Dry::Inflector#tableize` - [Luca Guidi] Introduced `Dry::Inflector#dasherize` - [Luca Guidi] Introduced `Dry::Inflector#underscore` - [Luca Guidi] Introduced `Dry::Inflector#demodulize` - [Luca Guidi] Introduced `Dry::Inflector#humanize` - [Luca Guidi] Introduced `Dry::Inflector#ordinalize` - [Abinoam P. Marques Jr.] Introduced `Dry::Inflector#foreign_key` - [Abinoam P. Marques Jr.] Introduced `Dry::Inflector#constantize` dry-inflector-0.2.1/CODEOWNERS000066400000000000000000000000121406702704200156610ustar00rootroot00000000000000* @solnic dry-inflector-0.2.1/CODE_OF_CONDUCT.md000066400000000000000000000026611406702704200171010ustar00rootroot00000000000000# Contributor Code of Conduct As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion. Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.4.0, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct](https://www.contributor-covenant.org/version/1/4/code-of-conduct) dry-inflector-0.2.1/CONTRIBUTING.md000066400000000000000000000026471406702704200165370ustar00rootroot00000000000000# Issue Guidelines ## Reporting bugs If you found a bug, report an issue and describe what's the expected behavior versus what actually happens. If the bug causes a crash, attach a full backtrace. If possible, a reproduction script showing the problem is highly appreciated. ## Reporting feature requests Report a feature request **only after discussing it first on [discourse.dry-rb.org](https://discourse.dry-rb.org)** where it was accepted. Please provide a concise description of the feature. ## Reporting questions, support requests, ideas, concerns etc. **PLEASE DON'T** - use [discourse.dry-rb.org](https://discourse.dry-rb.org) instead. # Pull Request Guidelines A Pull Request will only be accepted if it addresses a specific issue that was reported previously, or fixes typos, mistakes in documentation etc. Other requirements: 1) Do not open a pull request if you can't provide tests along with it. If you have problems writing tests, ask for help in the related issue. 2) Follow the style conventions of the surrounding code. In most cases, this is standard ruby style. 3) Add API documentation if it's a new feature 4) Update API documentation if it changes an existing feature 5) Bonus points for sending a PR which updates user documentation in the `docsite` directory # Asking for help If these guidelines aren't helpful, and you're stuck, please post a message on [discourse.dry-rb.org](https://discourse.dry-rb.org). dry-inflector-0.2.1/Gemfile000066400000000000000000000002301406702704200155630ustar00rootroot00000000000000# frozen_string_literal: true source "https://rubygems.org" eval_gemfile "Gemfile.devtools" gemspec group :tools do gem "byebug" gem "yard" end dry-inflector-0.2.1/Gemfile.devtools000066400000000000000000000006031406702704200174250ustar00rootroot00000000000000# frozen_string_literal: true # This file is synced from dry-rb/template-gem repo gem "rake", ">= 12.3.3" group :test do gem "simplecov", require: false, platforms: :ruby gem "simplecov-cobertura", require: false, platforms: :ruby gem "rexml", require: false gem "warning" end group :tools do # this is the same version that we use on codacy gem "rubocop", "1.16.0" end dry-inflector-0.2.1/LICENSE000066400000000000000000000020731406702704200153040ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2015-2021 dry-rb 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. dry-inflector-0.2.1/README.md000066400000000000000000000024201406702704200155520ustar00rootroot00000000000000 [gem]: https://rubygems.org/gems/dry-inflector [actions]: https://github.com/dry-rb/dry-inflector/actions [codacy]: https://www.codacy.com/gh/dry-rb/dry-inflector [chat]: https://dry-rb.zulipchat.com [inchpages]: http://inch-ci.org/github/dry-rb/dry-inflector # dry-inflector [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat] [![Gem Version](https://badge.fury.io/rb/dry-inflector.svg)][gem] [![CI Status](https://github.com/dry-rb/dry-inflector/workflows/ci/badge.svg)][actions] [![Codacy Badge](https://api.codacy.com/project/badge/Grade/00339f2fb77840149f999cac6110c8a8)][codacy] [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/00339f2fb77840149f999cac6110c8a8)][codacy] [![Inline docs](http://inch-ci.org/github/dry-rb/dry-inflector.svg?branch=master)][inchpages] ## Links * [User documentation](https://dry-rb.org/gems/dry-inflector) * [API documentation](http://rubydoc.info/gems/dry-inflector) ## Supported Ruby versions This library officially supports the following Ruby versions: * MRI `>= 2.6.0` * ~~jruby~~ `>= 9.3` (we are waiting for [2.6 support](https://github.com/jruby/jruby/issues/6161)) ## License See `LICENSE` file. dry-inflector-0.2.1/Rakefile000066400000000000000000000003101406702704200157340ustar00rootroot00000000000000# frozen_string_literal: true require "rake" require "bundler/gem_tasks" require "rspec/core/rake_task" task default: :spec desc "Run all specs in spec directory" RSpec::Core::RakeTask.new(:spec) dry-inflector-0.2.1/bin/000077500000000000000000000000001406702704200150455ustar00rootroot00000000000000dry-inflector-0.2.1/bin/.gitkeep000066400000000000000000000000001406702704200164640ustar00rootroot00000000000000dry-inflector-0.2.1/bin/console000077500000000000000000000006741406702704200164440ustar00rootroot00000000000000#!/usr/bin/env ruby # frozen_string_literal: true require "bundler/setup" require "dry/inflector" # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. # (If you use this, don't forget to add pry to your Gemfile!) # require "pry" # Pry.start require "irb" Dry::Inflector.new.instance_exec do binding.irb # rubocop:disable Lint/Debugger end dry-inflector-0.2.1/bin/setup000077500000000000000000000002031406702704200161260ustar00rootroot00000000000000#!/usr/bin/env bash set -euo pipefail IFS=$'\n\t' set -vx bundle install # Do any other automated setup that you need to do here dry-inflector-0.2.1/changelog.yml000066400000000000000000000033331406702704200167510ustar00rootroot00000000000000--- - version: 0.2.1 summary: date: '2021-06-30' fixed: - 'Fix singularizing -us suffix (issue #33 via #38) (@cllns)' added: - 'Add default acronyms: API and CSRF (#35) (@jodosha)' changed: - version: 0.2.0 date: '2019-10-13' added: - "[Abinoam P. Marques Jr. & Andrii Savchenko] Introduced `Dry::Inflector#camelize_upper` and `Dry::Inflector#camelize_lower`. `Dry::Inflector#camelize` is now an alias for `Dry::Inflector#camelize_upper`." - "```ruby" - 'inflector.camelize_upper("data_mapper") # => "DataMapper"' - 'inflector.camelize_lower("data_mapper") # => "dataMapper"' - "```" fixed: - '[ecnal] Fixed singularization rules for words like "alias" or "status"' - version: 0.1.2 date: '2018-04-25' added: - "[Gustavo Caso & Nikita Shilnikov] Added support for acronyms" - version: 0.1.1 date: '2017-11-18' fixed: - "[Luca Guidi & Abinoam P. Marques Jr.] Ensure `Dry::Inflector#ordinalize` to work for all the numbers from 0 to 100" - version: 0.1.0 date: '2017-11-17' added: - "[Luca Guidi] Introduced `Dry::Inflector#pluralize`" - "[Luca Guidi] Introduced `Dry::Inflector#singularize`" - "[Luca Guidi] Introduced `Dry::Inflector#camelize`" - "[Luca Guidi] Introduced `Dry::Inflector#classify`" - "[Luca Guidi] Introduced `Dry::Inflector#tableize`" - "[Luca Guidi] Introduced `Dry::Inflector#dasherize`" - "[Luca Guidi] Introduced `Dry::Inflector#underscore`" - "[Luca Guidi] Introduced `Dry::Inflector#demodulize`" - "[Luca Guidi] Introduced `Dry::Inflector#humanize`" - "[Luca Guidi] Introduced `Dry::Inflector#ordinalize`" - "[Abinoam P. Marques Jr.] Introduced `Dry::Inflector#foreign_key`" - "[Abinoam P. Marques Jr.] Introduced `Dry::Inflector#constantize`" dry-inflector-0.2.1/docsite/000077500000000000000000000000001406702704200157275ustar00rootroot00000000000000dry-inflector-0.2.1/docsite/source/000077500000000000000000000000001406702704200172275ustar00rootroot00000000000000dry-inflector-0.2.1/docsite/source/index.html.md000066400000000000000000000036071406702704200216310ustar00rootroot00000000000000--- title: Introduction description: Standalone inflections layout: gem-single order: 18 type: gem name: dry-inflector --- dry-inflector is an inflector gem for Ruby, which provides a configurable inflector **object**, rather than using a singleton. ### Basic usage ``` ruby require "dry/inflector" inflector = Dry::Inflector.new inflector.pluralize("book") # => "books" inflector.singularize("books") # => "book" inflector.camelize("dry/inflector") # => "Dry::Inflector" inflector.classify("books") # => "Book" inflector.demodulize("Dry::Inflector") # => "Inflector" inflector.constantize("Dry::Inflector") # => Dry::Inflector inflector.dasherize("dry_inflector") # => "dry-inflector" inflector.underscore("dry-inflector") # => "dry_inflector" inflector.humanize("dry_inflector") # => "Dry inflector" inflector.humanize("author_id") # => "Author" inflector.tableize("Book") # => "books" inflector.foreign_key("Book") # => "book_id" inflector.ordinalize(1) # => "1st" inflector.ordinalize(2) # => "2nd" inflector.ordinalize(3) # => "3rd" inflector.ordinalize(10) # => "10th" inflector.ordinalize(23) # => "23rd" ``` ### Custom inflection rules ``` ruby require "dry/inflector" inflector = Dry::Inflector.new do |inflections| inflections.plural "virus", "viruses" # specify a rule for #pluralize inflections.singular "thieves", "thief" # specify a rule for #singularize inflections.uncountable "dry-inflector" # add an exception for an uncountable word end inflector.pluralize("virus") # => "viruses" inflector.singularize("thieves") # => "thief" inflector.pluralize("dry-inflector") # => "dry-inflector" ``` ### Acronyms ```ruby require "dry/inflector" inflector = Dry::Inflector.new do |inflections| inflections.acronym "API", "OpenGL" end inflector.camelize("opengl_api") # => "OpenGLAPI" inflector.underscore("OpenGLAPI") # => "opengl_api" ``` dry-inflector-0.2.1/dry-inflector.gemspec000066400000000000000000000026361406702704200204320ustar00rootroot00000000000000# frozen_string_literal: true # this file is synced from dry-rb/template-gem project lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "dry/inflector/version" Gem::Specification.new do |spec| spec.name = "dry-inflector" spec.authors = ["Luca Guidi", "Andrii Savchenko", "Abinoam P. Marques Jr."] spec.email = ["me@lucaguidi.com", "andrey@aejis.eu", "abinoam@gmail.com"] spec.license = "MIT" spec.version = Dry::Inflector::VERSION.dup spec.summary = "String inflections for dry-rb" spec.description = spec.summary spec.homepage = "https://dry-rb.org/gems/dry-inflector" spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-inflector.gemspec", "lib/**/*"] spec.bindir = "bin" spec.executables = [] spec.require_paths = ["lib"] spec.metadata["allowed_push_host"] = "https://rubygems.org" spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-inflector/blob/master/CHANGELOG.md" spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-inflector" spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-inflector/issues" spec.required_ruby_version = ">= 2.6.0" # to update dependencies edit project.yml spec.add_development_dependency "bundler" spec.add_development_dependency "rake" spec.add_development_dependency "rspec" end dry-inflector-0.2.1/lib/000077500000000000000000000000001406702704200150435ustar00rootroot00000000000000dry-inflector-0.2.1/lib/dry-inflector.rb000066400000000000000000000000671406702704200201540ustar00rootroot00000000000000# frozen_string_literal: true require "dry/inflector" dry-inflector-0.2.1/lib/dry/000077500000000000000000000000001406702704200156415ustar00rootroot00000000000000dry-inflector-0.2.1/lib/dry/inflector.rb000066400000000000000000000212661406702704200201620ustar00rootroot00000000000000# frozen_string_literal: true module Dry # dry-inflector # # @since 0.1.0 class Inflector require "dry/inflector/version" require "dry/inflector/inflections" # Instantiate the inflector # # @param blk [Proc] an optional block to specify custom inflection rules # @yieldparam [Dry::Inflector::Inflections] the inflection rules # # @return [Dry::Inflector] the inflector # # @since 0.1.0 # # @example Basic usage # require "dry/inflector" # # inflector = Dry::Inflector.new # # @example Custom inflection rules # require "dry/inflector" # # inflector = Dry::Inflector.new do |inflections| # inflections.plural "virus", "viruses" # specify a rule for #pluralize # inflections.singular "thieves", "thief" # specify a rule for #singularize # inflections.uncountable "dry-inflector" # add an exception for an uncountable word # end def initialize(&blk) @inflections = Inflections.build(&blk) end # Lower camelize a string # # @param input [String,Symbol] the input # @return [String] the lower camelized string # # @since 0.1.3 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.camelize_lower("data_mapper") # => "dataMapper" def camelize_lower(input) internal_camelize(input, false) end # Upper camelize a string # # @param input [String,Symbol] the input # @return [String] the upper camelized string # # @since 0.1.3 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.camelize_upper("data_mapper") # => "DataMapper" # inflector.camelize_upper("dry/inflector") # => "Dry::Inflector" def camelize_upper(input) internal_camelize(input, true) end alias_method :camelize, :camelize_upper # 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 input [String,Symbol] the input # @return [Class, Module] the class or module # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.constantize("Module") # => Module # inflector.constantize("Dry::Inflector") # => Dry::Inflector def constantize(input) Object.const_get(input, false) end # Classify a string # # @param input [String,Symbol] the input # @return [String] the classified string # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.classify("books") # => "Book" def classify(input) camelize(singularize(input.to_s.sub(/.*\./, ""))) end # Dasherize a string # # @param input [String,Symbol] the input # @return [String] the dasherized string # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.dasherize("dry_inflector") # => "dry-inflector" def dasherize(input) input.to_s.tr("_", "-") end # Demodulize a string # # @param input [String,Symbol] the input # @return [String] the demodulized string # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.demodulize("Dry::Inflector") # => "Inflector" def demodulize(input) input.to_s.split("::").last end # Humanize a string # # @param input [String,Symbol] the input # @return [String] the humanized string # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.humanize("dry_inflector") # => "Dry inflector" # inflector.humanize("author_id") # => "Author" def humanize(input) input = input.to_s result = inflections.humans.apply_to(input) result.chomp!("_id") result.tr!("_", " ") match = /(?\W)/.match(result) separator = match ? match[:separator] : DEFAULT_SEPARATOR result.split(separator).map.with_index { |word, index| inflections.acronyms.apply_to(word, capitalize: index.zero?) }.join(separator) end # Creates a foreign key name # # @param input [String, Symbol] the input # @return [String] foreign key # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.foreign_key("Message") => "message_id" def foreign_key(input) "#{underscore(demodulize(input))}_id" end # Ordinalize a number # # @param number [Integer] the input # @return [String] the ordinalized number # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.ordinalize(1) # => "1st" # inflector.ordinalize(2) # => "2nd" # inflector.ordinalize(3) # => "3rd" # inflector.ordinalize(10) # => "10th" # inflector.ordinalize(23) # => "23rd" def ordinalize(number) abs_value = number.abs if ORDINALIZE_TH.key?(abs_value % 100) "#{number}th" else case abs_value % 10 when 1 then "#{number}st" when 2 then "#{number}nd" when 3 then "#{number}rd" else "#{number}th" end end end # Pluralize a string # # @param input [String,Symbol] the input # @return [String] the pluralized string # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.pluralize("book") # => "books" # inflector.pluralize("money") # => "money" def pluralize(input) input = input.to_s return input if uncountable?(input) inflections.plurals.apply_to(input) end # Singularize a string # # @param input [String] the input # @return [String] the singularized string # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.singularize("books") # => "book" # inflector.singularize("money") # => "money" def singularize(input) input = input.to_s return input if uncountable?(input) inflections.singulars.apply_to(input) end # Tableize a string # # @param input [String,Symbol] the input # @return [String] the tableized string # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.tableize("Book") # => "books" def tableize(input) input = input.to_s.gsub(/::/, "_") pluralize(underscore(input)) end # Underscore a string # # @param input [String,Symbol] the input # @return [String] the underscored string # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new # inflector.underscore("dry-inflector") # => "dry_inflector" def underscore(input) input = input.to_s.gsub("::", "/") input.gsub!(inflections.acronyms.regex) do m1 = Regexp.last_match(1) m2 = Regexp.last_match(2) "#{m1 ? "_" : ""}#{m2.downcase}" end input.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2') input.gsub!(/([a-z\d])([A-Z])/, '\1_\2') input.tr!("-", "_") input.downcase! input end # Check if the input is an uncountable word # # @param input [String] the input # @return [TrueClass,FalseClass] the result of the check # # @since 0.1.0 # @api private def uncountable?(input) !(input =~ /\A[[:space:]]*\z/).nil? || inflections.uncountables.include?(input.downcase) end # @return [String] # # @since 0.2.0 # @api public def to_s "#" end alias_method :inspect, :to_s private # @since 0.1.0 # @api private ORDINALIZE_TH = (11..13).each_with_object({}) { |n, ret| ret[n] = true }.freeze # @since 0.1.2 # @api private DEFAULT_SEPARATOR = " " attr_reader :inflections # @since 0.1.3 # @api private def internal_camelize(input, upper) input = input.to_s.dup input.sub!(/^[a-z\d]*/) { |match| inflections.acronyms.apply_to(match, capitalize: upper) } input.gsub!(%r{(?:_|(/))([a-z\d]*)}i) do m1 = Regexp.last_match(1) m2 = Regexp.last_match(2) "#{m1}#{inflections.acronyms.apply_to(m2)}" end input.gsub!("/", "::") input end end end dry-inflector-0.2.1/lib/dry/inflector/000077500000000000000000000000001406702704200176265ustar00rootroot00000000000000dry-inflector-0.2.1/lib/dry/inflector/acronyms.rb000066400000000000000000000015471406702704200220150ustar00rootroot00000000000000# frozen_string_literal: true module Dry class Inflector # A set of acronyms # # @since 0.1.2 # @api private class Acronyms attr_reader :regex # @since 0.1.2 # @api private def initialize @rules = {} define_regex_patterns end # @since 0.1.2 # @api private def apply_to(word, capitalize: true) @rules[word.downcase] || (capitalize ? word.capitalize : word) end # @since 0.1.2 # @api private def add(rule, replacement) @rules[rule] = replacement define_regex_patterns end private # @since 0.1.2 # @api private def define_regex_patterns regex = @rules.empty? ? /(?=a)b/ : /#{@rules.values.join("|")}/ @regex = /(?:(?<=([A-Za-z\d]))|\b)(#{regex})(?=\b|[^a-z])/ end end end end dry-inflector-0.2.1/lib/dry/inflector/inflections.rb000066400000000000000000000155771406702704200225070ustar00rootroot00000000000000# frozen_string_literal: true require "set" require "dry/inflector/rules" require "dry/inflector/acronyms" module Dry class Inflector # Inflections # # @since 0.1.0 class Inflections require "dry/inflector/inflections/defaults" # Instantiate a set of inflection rules. # It adds the default rules and the optional customizations, passed as a block. # # @param blk [Proc] the optional, custom rules # # @since 0.1.0 # @api private def self.build(&blk) new do |inflect| Defaults.call(inflect) blk.call(inflect) if block_given? end end # Pluralization rules # # @return [Dry::Inflector::Rules] # # @since 0.1.0 # @api private attr_reader :plurals # Singularization rules # # @return [Dry::Inflector::Rules] # # @since 0.1.0 # @api private attr_reader :singulars # Uncountable rules # # @return [Set] # # @since 0.1.0 # @api private attr_reader :uncountables # Human rules # # @return [Dry::Inflector::Rules] # # @since 0.1.0 # @api private attr_reader :humans # Acronyms # # @return [Dry::Inflector::Acronyms] # # @since 0.1.2 # @api private attr_reader :acronyms # Instantiate the rules # # @return [Dry::Inflector::Inflections] # @yieldparam [self] # # @since 0.1.0 # @api private def initialize @plurals = Rules.new @singulars = Rules.new @humans = Rules.new @uncountables = Set[] @acronyms = Acronyms.new yield(self) if block_given? end # Add a custom pluralization rule # # 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 rule [String, Regexp] the rule # @param replacement [String] the replacement # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new do |inflections| # inflections.plural "virus", "viruses" # end def plural(rule, replacement) rule(rule, replacement, plurals) end # Add a custom singularization 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 rule [String, Regexp] the rule # @param replacement [String] the replacement # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new do |inflections| # inflections.singular "thieves", "thief" # end def singular(rule, replacement) rule(rule, replacement, singulars) end # Add a custom pluralization rule # # 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. # # @param singular [String] the singular # @param plural [String] the plural # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new do |inflections| # inflections.singular "octopus", "octopi" # end def irregular(singular, plural) uncountables.delete(singular) uncountables.delete(plural) add_irregular(singular, plural, plurals) add_irregular(plural, singular, singulars) end # Add a custom rule for uncountable words # # Uncountable will not be inflected # # @param [Enumerable] words # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new do |inflections| # inflections.uncountable "money" # inflections.uncountable "money", "information" # inflections.uncountable %w(money information rice) # end def uncountable(*words) uncountables.merge(words.flatten) end # Add one or more acronyms # # Acronyms affect how basic operations are performed, such # as camelize/underscore. # # @param words [Array] a list of acronyms # # @since 0.1.2 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new do |inflections| # inflections.acronym "HTML" # end # # inflector.camelize("html") # => "HTML" # inflector.underscore("HTMLIsFun") # => "html_is_fun" def acronym(*words) words.each { |word| @acronyms.add(word.downcase, word) } end # Add a custom 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"`) # # @param rule [String, Regexp] the rule # @param replacement [String] the replacement # # @since 0.1.0 # # @example # require "dry/inflector" # # inflector = Dry::Inflector.new do |inflections| # inflections.human(/_cnt$/i, '\1_count') # inflections.human("legacy_col_person_name", "Name") # end def human(rule, replacement) humans.insert(0, [rule, replacement]) end private # Add irregular inflection # # @param rule [String] the rule # @param replacement [String] the replacement # # @return [undefined] # # @since 0.1.0 # @api private def add_irregular(rule, replacement, target) head, *tail = rule.chars.to_a rule(/(#{head})#{tail.join}\z/i, "\\1#{replacement[1..]}", target) end # Add a new rule # # @param rule [String, Regexp] the rule # @param replacement [String, Regexp] the replacement # @param target [Dry::Inflector::Rules] the target # # @since 0.1.0 # @api private def rule(rule, replacement, target) uncountables.delete(rule) uncountables.delete(replacement) target.insert(0, [rule, replacement]) end end end end dry-inflector-0.2.1/lib/dry/inflector/inflections/000077500000000000000000000000001406702704200221435ustar00rootroot00000000000000dry-inflector-0.2.1/lib/dry/inflector/inflections/defaults.rb000066400000000000000000000110331406702704200242750ustar00rootroot00000000000000# frozen_string_literal: true module Dry class Inflector class Inflections # Default inflections # # @since 0.1.0 # @api private # # rubocop:disable Metrics/AbcSize module Defaults # @since 0.1.0 # @api private def self.call(inflect) plural(inflect) singular(inflect) irregular(inflect) uncountable(inflect) acronyms(inflect) end # @since 0.1.0 # @api private def self.plural(inflect) inflect.plural(/\z/, "s") inflect.plural(/s\z/i, "s") inflect.plural(/(ax|test)is\z/i, '\1es') inflect.plural(/(.*)us\z/i, '\1uses') inflect.plural(/(octop|vir|cact)us\z/i, '\1i') inflect.plural(/(octop|vir)i\z/i, '\1i') inflect.plural(/(alias|status)\z/i, '\1es') inflect.plural(/(buffal|domin|ech|embarg|her|mosquit|potat|tomat)o\z/i, '\1oes') inflect.plural(/(? "merb", "data_mapper" => "dataMapper", "dry/inflector" => "dry::Inflector", "dry/inflector/inflections" => "dry::Inflector::Inflections", "blog_post/author" => "blogPost::Author", "blog_post/tag_cloud" => "blogPost::TagCloud" }.freeze # Missing rules PENDING = {}.freeze end end dry-inflector-0.2.1/spec/support/fixtures/camelize_upper.rb000066400000000000000000000007741406702704200241550ustar00rootroot00000000000000# frozen_string_literal: true module Fixtures module CamelizeUpper def self.cases CASES end def self.pending PENDING end CASES = { "merb" => "Merb", "data_mapper" => "DataMapper", "dry/inflector" => "Dry::Inflector", "dry/inflector/inflections" => "Dry::Inflector::Inflections", "blog_post/author" => "BlogPost::Author", "blog_post/tag_cloud" => "BlogPost::TagCloud" }.freeze # Missing rules PENDING = {}.freeze end end dry-inflector-0.2.1/spec/support/fixtures/ordinalize.rb000066400000000000000000000041411406702704200233010ustar00rootroot00000000000000# frozen_string_literal: true module Fixtures module Ordinalize def self.cases CASES end CASES = { 0 => "0th", 1 => "1st", 2 => "2nd", 3 => "3rd", 4 => "4th", 5 => "5th", 6 => "6th", 7 => "7th", 8 => "8th", 9 => "9th", 10 => "10th", 11 => "11th", 12 => "12th", 13 => "13th", 14 => "14th", 15 => "15th", 16 => "16th", 17 => "17th", 18 => "18th", 19 => "19th", 20 => "20th", 21 => "21st", 22 => "22nd", 23 => "23rd", 24 => "24th", 25 => "25th", 26 => "26th", 27 => "27th", 28 => "28th", 29 => "29th", 30 => "30th", 31 => "31st", 32 => "32nd", 33 => "33rd", 34 => "34th", 35 => "35th", 36 => "36th", 37 => "37th", 38 => "38th", 39 => "39th", 40 => "40th", 41 => "41st", 42 => "42nd", 43 => "43rd", 44 => "44th", 45 => "45th", 46 => "46th", 47 => "47th", 48 => "48th", 49 => "49th", 50 => "50th", 51 => "51st", 52 => "52nd", 53 => "53rd", 54 => "54th", 55 => "55th", 56 => "56th", 57 => "57th", 58 => "58th", 59 => "59th", 60 => "60th", 61 => "61st", 62 => "62nd", 63 => "63rd", 64 => "64th", 65 => "65th", 66 => "66th", 67 => "67th", 68 => "68th", 69 => "69th", 70 => "70th", 71 => "71st", 72 => "72nd", 73 => "73rd", 74 => "74th", 75 => "75th", 76 => "76th", 77 => "77th", 78 => "78th", 79 => "79th", 80 => "80th", 81 => "81st", 82 => "82nd", 83 => "83rd", 84 => "84th", 85 => "85th", 86 => "86th", 87 => "87th", 88 => "88th", 89 => "89th", 90 => "90th", 91 => "91st", 92 => "92nd", 93 => "93rd", 94 => "94th", 95 => "95th", 96 => "96th", 97 => "97th", 98 => "98th", 99 => "99th", 100 => "100th" }.freeze end end dry-inflector-0.2.1/spec/support/fixtures/pluralize.rb000066400000000000000000000260551406702704200231600ustar00rootroot00000000000000# frozen_string_literal: true module Fixtures # rubocop:disable Metrics/ModuleLength module Pluralize def self.cases CASES end def self.pending PENDING end def self.irregular IRREGULAR end IRREGULAR = { "person" => "people", "man" => "men", "child" => "children", "sex" => "sexes", "foot" => "feet", "tooth" => "teeth", "goose" => "geese" }.freeze CASES = { # # Test cases from Inflecto # "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", "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", "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 (still taken from Inflecto code base) "search" => "searches", "switch" => "switches", "fix" => "fixes", "box" => "boxes", "process" => "processes", "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", "shoe" => "shoes", "horse" => "horses", "edge" => "edges", "cow" => "cows", # # Test cases from Hanami::Utils # # um => a "bacterium" => "bacteria", "agendum" => "agenda", "desideratum" => "desiderata", "stratum" => "strata", "ovum" => "ova", "extremum" => "extrema", "candelabrum" => "candelabra", "curriculum" => "curricula", "millennium" => "millennia", "referendum" => "referenda", "stadium" => "stadia", "memorandum" => "memoranda", "criterium" => "criteria", "perihelium" => "perihelia", "aphelium" => "aphelia", # on => a "phenomenon" => "phenomena", "prolegomenon" => "prolegomena", "noumenon" => "noumena", "organon" => "organa", # o => os "albino" => "albinos", "archipelago" => "archipelagos", "armadillo" => "armadillos", "commando" => "commandos", "crescendo" => "crescendos", "fiasco" => "fiascos", "ditto" => "dittos", "dynamo" => "dynamos", "embryo" => "embryos", "ghetto" => "ghettos", "guano" => "guanos", "inferno" => "infernos", "jumbo" => "jumbos", "lumbago" => "lumbagos", "magneto" => "magnetos", "manifesto" => "manifestos", "medico" => "medicos", "octavo" => "octavos", "pro" => "pros", "quarto" => "quartos", "canto" => "cantos", "lingo" => "lingos", "generalissimo" => "generalissimos", "stylo" => "stylos", "rhino" => "rhinos", "casino" => "casinos", "auto" => "autos", "macro" => "macros", "zero" => "zeros", "todo" => "todos", "studio" => "studios", "avocado" => "avocados", "zoo" => "zoos", "banjo" => "banjos", "cargo" => "cargos", "flamingo" => "flamingos", "fresco" => "frescos", "halo" => "halos", "mango" => "mangos", "memento" => "mementos", "motto" => "mottos", "tornado" => "tornados", "tuxedo" => "tuxedos", "volcano" => "volcanos", # The correct form from italian is: o => i. (Eg. contralto => contralti) # English dictionaries are reporting o => s as a valid rule # # We're sticking to the latter rule, in order to not introduce exceptions # for words that end with "o". See the previous category. "solo" => "solos", "soprano" => "sopranos", "basso" => "bassos", "alto" => "altos", "contralto" => "contraltos", "tempo" => "tempos", "piano" => "pianos", "virtuoso" => "virtuosos", # o => oes "domino" => "dominoes", "echo" => "echoes", "embargo" => "embargoes", "hero" => "heroes", "mosquito" => "mosquitoes", "potato" => "potatoes", "torpedo" => "torpedos", "veto" => "vetos", # a => ata "anathema" => "anathemata", "enema" => "enemata", "oedema" => "oedemata", "bema" => "bemata", "enigma" => "enigmata", "sarcoma" => "sarcomata", "carcinoma" => "carcinomata", "gumma" => "gummata", "schema" => "schemata", "charisma" => "charismata", "lemma" => "lemmata", "soma" => "somata", "diploma" => "diplomata", "lymphoma" => "lymphomata", "stigma" => "stigmata", "dogma" => "dogmata", "magma" => "magmata", "stoma" => "stomata", "drama" => "dramata", "melisma" => "melismata", "trauma" => "traumata", "edema" => "edemata", "miasma" => "miasmata", # us => uses "apparatus" => "apparatuses", "impetus" => "impetuses", "prospectus" => "prospectuses", "cantus" => "cantuses", "nexus" => "nexuses", "sinus" => "sinuses", "coitus" => "coituses", "plexus" => "plexuses", "hiatus" => "hiatuses", # man => mans "human" => "humans", # ch => es "witch" => "witches", "church" => "churches", # ch => chs "stomach" => "stomachs", "epoch" => "epochs", # e => es, "mustache" => "mustaches", "verse" => "verses", "universe" => "universes", "inverse" => "inverses", "advice" => "advices", "device" => "devices", # vowel + y => s "boy" => "boys", "way" => "ways", # consonant + y => ies "baby" => "babies", "lorry" => "lorries", "entity" => "entities", "repository" => "repositories", # f => ves "leaf" => "leaves", "hoof" => "hooves", "self" => "selves", "scarf" => "scarves", "thief" => "thieves", # vocal + fe => ves "knife" => "knives", # eau => eaux "beau" => "beaux", "bureau" => "bureaux", "tableau" => "tableaux", # irregular "cactus" => "cacti", # uncountable "deer" => "deer", "means" => "means", "milk" => "milk", "hovercraft" => "hovercraft", "rain" => "rain", "moose" => "moose", # fallback (add s) "giraffe" => "giraffes", "test" => "tests", "feature" => "features", "fixture" => "fixtures", "controller" => "controllers", "action" => "actions", "router" => "routers", "route" => "routes", "endpoint" => "endpoints", "string" => "strings", "view" => "views", "template" => "templates", "layout" => "layouts", "application" => "applications", "api" => "apis", "model" => "models", "mapper" => "mappers", "mapping" => "mappings", "table" => "tables", "attribute" => "attributes", "column" => "columns", "migration" => "migrations", "presenter" => "presenters", "wizard" => "wizards", "architecture" => "architectures", "car" => "cars", "area" => "areas", # https://github.com/hanami/utils/issues/106 "album" => "albums", # https://github.com/hanami/utils/issues/173 "kitten" => "kittens", # Ending with 'ss' "address" => "addresses", "boss" => "bosses", "class" => "classes", "glass" => "glasses", "kiss" => "kisses", # Ending with 'sses' "addresses" => "addresses", "bosses" => "bosses", "classes" => "classes", "glasses" => "glasses", "kisses" => "kisses" }.merge(IRREGULAR).freeze # Missing rule or exception? PENDING = { "criterion" => "criteria", "thesaurus" => "thesauri", "plus" => "plusses", "virus" => "viruses" }.freeze end # rubocop:enable Metrics/ModuleLength end dry-inflector-0.2.1/spec/support/fixtures/singularize.rb000066400000000000000000000107071406702704200235020ustar00rootroot00000000000000# frozen_string_literal: true module Fixtures module Singularize def self.cases CASES end def self.pending PENDING end # ==== exceptional cases CASES = { "equipment" => "equipment", "mysql" => "mysql", "information" => "information", "money" => "money", "species" => "species", "series" => "series", "fish" => "fish", "sheep" => "sheep", "news" => "news", "rain" => "rain", "milk" => "milk", "moose" => "moose", "geese" => "goose", "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 "alias" => "alias", "status" => "status", "bus" => "bus", "axis" => "axis", "crisis" => "crisis", "testis" => "testis", "thesis" => "thesis", "analysis" => "analysis", "octopuses" => "octopus", "pluses" => "plus", "cactuses" => "cactus", "bonuses" => "bonus", "geniuses" => "genius", "walruses" => "walrus", # ==== 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", # ending with 'ss' "address" => "address", "boss" => "boss", "class" => "class", "glass" => "glass", "kiss" => "kiss", # ending with 'sses' "addresses" => "address", "bosses" => "boss", "classes" => "class", "glasses" => "glass", "kisses" => "kiss", # uncountable "Swiss" => "Swiss" }.freeze # Missing exceptions or missing rules? PENDING = { "cacti" => "cactus", "thesauri" => "thesaurus", "phenomena" => "phenomenon", "drives" => "drive", "thieves" => "thief", "criteria" => "criterion", "postgres" => "postgres" }.freeze end end dry-inflector-0.2.1/spec/support/immutable.rb000066400000000000000000000003631406702704200212510ustar00rootroot00000000000000# frozen_string_literal: true module RSpec module Support module Immutable private def i(string) string.freeze end end end end RSpec.configure do |config| config.include RSpec::Support::Immutable end dry-inflector-0.2.1/spec/support/rspec_options.rb000066400000000000000000000007351406702704200221640ustar00rootroot00000000000000RSpec.configure do |config| # When no filter given, search and run focused tests config.filter_run_when_matching :focus # Disables rspec monkey patches (no reason for their existence tbh) config.disable_monkey_patching! # Run ruby in verbose mode config.warnings = true # Collect all failing expectations automatically, # without calling aggregate_failures everywhere config.define_derived_metadata do |meta| meta[:aggregate_failures] = true end end dry-inflector-0.2.1/spec/support/warnings.rb000066400000000000000000000003701406702704200211200ustar00rootroot00000000000000# frozen_string_literal: true # this file is managed by dry-rb/devtools project require "warning" Warning.ignore(%r{rspec/core}) Warning.ignore(%r{rspec/mocks}) Warning.ignore(/codacy/) Warning[:experimental] = false if Warning.respond_to?(:[]) dry-inflector-0.2.1/spec/unit/000077500000000000000000000000001406702704200162065ustar00rootroot00000000000000dry-inflector-0.2.1/spec/unit/dry/000077500000000000000000000000001406702704200170045ustar00rootroot00000000000000dry-inflector-0.2.1/spec/unit/dry/inflector/000077500000000000000000000000001406702704200207715ustar00rootroot00000000000000dry-inflector-0.2.1/spec/unit/dry/inflector/acronym_spec.rb000066400000000000000000000043351406702704200240050ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do subject do Dry::Inflector.new do |inflect| inflect.acronym("RESTful", "RoR", "PhD", "W3C", "SSL", "HTML") end end describe "acronyms" do it "uses acronyms" do aggregate_failures do # These examples were taken from ActiveSupport's test suite # camelize underscore humanize [ %w[API api API], ["APIController", "api_controller", "API controller"], ["Nokogiri::HTML", "nokogiri/html", "Nokogiri/HTML"], ["HTTPAPI", "http_api", "HTTP API"], ["HTTP::Get", "http/get", "HTTP/get"], ["SSLError", "ssl_error", "SSL error"], %w[RESTful restful RESTful], ["RESTfulController", "restful_controller", "RESTful controller"], ["Nested::RESTful", "nested/restful", "Nested/RESTful"], ["IHeartW3C", "i_heart_w3c", "I heart W3C"], ["PhDRequired", "phd_required", "PhD required"], ["IRoRU", "i_ror_u", "I RoR u"], ["RESTfulHTTPAPI", "restful_http_api", "RESTful HTTP API"], ["HTTP::RESTful", "http/restful", "HTTP/RESTful"], ["HTTP::RESTfulAPI", "http/restful_api", "HTTP/RESTful API"], ["APIRESTful", "api_restful", "API RESTful"], ["CSRF", "csrf", "Cross Site Request Forgery"], # misdirection %w[Capistrano capistrano Capistrano], ["CapiController", "capi_controller", "Capi controller"], ["HttpsApis", "https_apis", "Https apis"], %w[Html5 html5 Html5], %w[Restfully restfully Restfully], ["RoRails", "ro_rails", "Ro rails"] ].each do |camel, under, human| expect(subject.camelize(under)).to eql(camel) expect(subject.camelize(camel)).to eql(camel) expect(subject.underscore(camel)).to eql(under) expect(subject.underscore(under)).to eql(under) expect(subject.humanize(human)).to eql(human) end end end end end dry-inflector-0.2.1/spec/unit/dry/inflector/camelize_lower_spec.rb000066400000000000000000000030501406702704200253270ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#camelize_lower" do Fixtures::CamelizeLower.cases.each do |input, camelized| it "lower camelizes #{input} => #{camelized}" do expect(subject.camelize_lower(i(input))).to eq(camelized) end end Fixtures::CamelizeLower.pending.each do |input, camelized| pending "missing exception or rule for #{input} => #{camelized}" end it "accepts symbols" do expect(subject.camelize_lower(:data_mapper)).to eq("dataMapper") end it "handles acronyms" do expect(subject.camelize_lower(i("json"))).to eql("JSON") expect(subject.camelize_lower(i("http_error"))).to eql("HTTPError") expect(subject.camelize_lower(i("openssl/hmac"))).to eql("OpenSSL::HMAC") expect(subject.camelize_lower(i("openssl/digest"))).to eql("OpenSSL::Digest") end context "custom acronyms" do subject do Dry::Inflector.new do |inflect| inflect.acronym("IP", "HTML", "XML", "BSD") end end it "handles acronyms" do expect(subject.camelize_lower(i("ip"))).to eql("IP") expect(subject.camelize_lower(i("ip_sec"))).to eql("IPSec") expect(subject.camelize_lower(i("html_tidy"))).to eql("HTMLTidy") expect(subject.camelize_lower(i("html_tidy_generator"))).to eql("HTMLTidyGenerator") expect(subject.camelize_lower(i("force_xml_controller"))).to eql("forceXMLController") expect(subject.camelize_lower(i("free_bsd"))).to eql("freeBSD") end end end end dry-inflector-0.2.1/spec/unit/dry/inflector/camelize_upper_spec.rb000066400000000000000000000032201406702704200253310ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#camelize_upper" do Fixtures::CamelizeUpper.cases.each do |input, camelized| it "upper camelizes #{input} => #{camelized}" do expect(subject.camelize_upper(i(input))).to eq(camelized) end end Fixtures::CamelizeUpper.pending.each do |input, camelized| pending "missing exception or rule for #{input} => #{camelized}" end it "accepts symbols" do expect(subject.camelize_upper(:data_mapper)).to eq("DataMapper") end it "have alias" do expect(subject.camelize("camelize_upper")).to eq("CamelizeUpper") end it "handles acronyms" do expect(subject.camelize_upper(i("json"))).to eql("JSON") expect(subject.camelize_upper(i("http_error"))).to eql("HTTPError") expect(subject.camelize_upper(i("openssl/hmac"))).to eql("OpenSSL::HMAC") expect(subject.camelize_upper(i("openssl/digest"))).to eql("OpenSSL::Digest") end context "custom acronyms" do subject do Dry::Inflector.new do |inflect| inflect.acronym("IP", "HTML", "XML", "BSD") end end it "handles acronyms" do expect(subject.camelize_upper(i("ip"))).to eql("IP") expect(subject.camelize_upper(i("ip_sec"))).to eql("IPSec") expect(subject.camelize_upper(i("html_tidy"))).to eql("HTMLTidy") expect(subject.camelize_upper(i("html_tidy_generator"))).to eql("HTMLTidyGenerator") expect(subject.camelize_upper(i("force_xml_controller"))).to eql("ForceXMLController") expect(subject.camelize_upper(i("free_bsd"))).to eql("FreeBSD") end end end end dry-inflector-0.2.1/spec/unit/dry/inflector/classify_spec.rb000066400000000000000000000013701406702704200241460ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#classify" do it "classifies data_mapper as DataMapper" do expect(subject.classify(i("data_mapper"))).to eq("DataMapper") end it "classifies data.mapper as Mapper" do expect(subject.classify(i("data.mapper"))).to eq("Mapper") end it "classifies enlarged_testes as EnlargedTestis" do expect(subject.classify(i("enlarged_testes"))).to eq("EnlargedTestis") end it "singularizes string first: classifies data_mappers as egg_and_hams as EggAndHam" do expect(subject.classify(i("egg_and_hams"))).to eq("EggAndHam") end it "accepts symbols" do expect(subject.classify(:data_mapper)).to eq("DataMapper") end end end dry-inflector-0.2.1/spec/unit/dry/inflector/constantize_spec.rb000066400000000000000000000032111406702704200246660ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#constantize" do it "constantizes Module" do expect(subject.constantize(i("Module"))).to eq Module end it "constantizes ::Module" do expect(subject.constantize(i("::Module"))).to eq Module end it "accepts symbols" do expect(subject.constantize(i(:Module))).to eq Module end it "constantizes nested constant Dry::Inflector::Inflections" do expect(subject.constantize(i("Dry::Inflector::Inflections"))).to eq Dry::Inflector::Inflections end it "does not search ancestors" do module Foo class Bar VAL = 10 end class Baz < Bar; end end expect(subject.constantize(i("Foo::Bar::VAL"))).to be(10) expect { subject.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 expect(subject.constantize(i("Foo::Autoloaded::Const"))).to eq Foo::Baz expect(subject.constantize(i("Foo::Bar::Const"))).to eq Foo::Baz end it "raises exception when empty string given" do expect do subject.constantize(i("")) end.to raise_error(NameError) end it "raises exception when constant not found" do expect do subject.constantize(i("Qwerty")) end.to raise_error(NameError) end end end dry-inflector-0.2.1/spec/unit/dry/inflector/dasherize_spec.rb000066400000000000000000000005621406702704200243110ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#dasherize" do it "dasherizes data_mapper_rspec as data-mapper-rspec" do expect(subject.dasherize(i("data_mapper_rspec"))).to eq("data-mapper-rspec") end it "accepts symbols" do expect(subject.dasherize(:data_mapper_rspec)).to eq("data-mapper-rspec") end end end dry-inflector-0.2.1/spec/unit/dry/inflector/demodulize_spec.rb000066400000000000000000000007641406702704200245000ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#demodulize" do it "demodulizes module name: DataMapper::Inflecto => Inflecto" do expect(subject.demodulize(i("DataMapper::Inflecto"))).to eq("Inflecto") end it "demodulizes module name: A::B::C::D::E => E" do expect(subject.demodulize(i("A::B::C::D::E"))).to eq("E") end it "accepts symbols" do expect(subject.demodulize(:"DataMapper::Inflecto")).to eq("Inflecto") end end end dry-inflector-0.2.1/spec/unit/dry/inflector/foreign_key_spec.rb000066400000000000000000000007431406702704200246350ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#foreign_key" do it "adds _id to downcased string: Message => message_id" do expect(subject.foreign_key(i("Message"))).to eq "message_id" end it "demodulizes string first: Admin::Post => post_id" do expect(subject.foreign_key(i("Admin::Post"))).to eq "post_id" end it "accepts symbols" do expect(subject.foreign_key(i(:message))).to eq "message_id" end end end dry-inflector-0.2.1/spec/unit/dry/inflector/humanize_spec.rb000066400000000000000000000021401406702704200241450ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#humanize" do it "replaces _ with space: humanizes employee_salary as Employee salary" do expect(subject.humanize(i("employee_salary"))).to eq("Employee salary") end it "strips _id endings: humanizes author_id as Author" do expect(subject.humanize(i("author_id"))).to eq("Author") end it "uses user added rules when possible" do subject = described_class.new do |inflect| inflect.human("Question", "Fancy question") inflect.human("questionary", "Questionnaire") end expect(subject.humanize(i("questionary"))).to eq("Questionnaire") end it "accepts symbols" do expect(subject.humanize(:employee_salary)).to eq("Employee salary") end it "handles acronyms" do expect(subject.humanize(i("json"))).to eql("JSON") expect(subject.humanize(i("http_error"))).to eql("HTTP error") expect(subject.humanize(i("openssl/hmac"))).to eql("OpenSSL/HMAC") expect(subject.humanize(i("openssl/digest"))).to eql("OpenSSL/digest") end end end dry-inflector-0.2.1/spec/unit/dry/inflector/ordinalize_spec.rb000066400000000000000000000035541406702704200244770ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#ordinalize" do Fixtures::Ordinalize.cases.each do |n, expected| it "ordinalizes #{n} => #{expected}" do expect(subject.ordinalize(n)).to eq(expected) end end 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| expect(subject.ordinalize(number)).to 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| expect(subject.ordinalize(number)).to 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| expect(subject.ordinalize(number)).to 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| expect(subject.ordinalize(number)).to 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| expect(subject.ordinalize(number)).to 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| expect(subject.ordinalize(number)).to 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| expect(subject.ordinalize(number)).to eq("#{number}th") end end end end dry-inflector-0.2.1/spec/unit/dry/inflector/pluralize_spec.rb000066400000000000000000000030751406702704200243440ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#pluralize" do Fixtures::Pluralize.cases.each do |singular, plural| it "pluralizes #{singular} => #{plural}" do expect(subject.pluralize(i(singular))).to eq(plural) end end Fixtures::Pluralize.irregular.each do |singular, plural| it "(irregular) pluralizes#{singular} => #{plural}" do expect(subject.pluralize(i(singular))).to eq(plural) end end Fixtures::Pluralize.pending.each do |singular, plural| pending "missing exception or rule for #{singular} => #{plural}" it "fails as expected since it's 'pending' (tip: remove it from pending!)" do expect(subject.singularize(singular)).to_not eq(plural) end end it "accepts symbols" do expect(subject.pluralize(:user)).to eq("users") expect(subject.pluralize(:money)).to eq("money") end context "with custom inflection rules" do subject do described_class.new do |inflections| inflections.plural "virus", "viruses" inflections.irregular "plus", "plusses" inflections.uncountable "dry-inflector" end end it "pluralizes using '#plural' rule" do expect(subject.pluralize("virus")).to eq("viruses") end it "pluralizes using '#irregular' rule" do expect(subject.pluralize("plus")).to eq("plusses") end it "doesn't pluralize uncountable" do expect(subject.pluralize("dry-inflector")).to eq("dry-inflector") end end end end dry-inflector-0.2.1/spec/unit/dry/inflector/singularize_spec.rb000066400000000000000000000026111406702704200246640ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#singularize" do Fixtures::Singularize.cases.each do |plural, singular| it "singularizes #{plural} => #{singular}" do expect(subject.singularize(i(plural))).to eq(singular) end end Fixtures::Singularize.pending.each do |plural, singular| pending "missing exception or rule for #{plural} => #{singular}" it "fails as expected since it's 'pending' (tip: remove it from pending!)" do expect(subject.singularize(plural)).to_not eq(singular) end end it "accepts symbols" do expect(subject.singularize(:users)).to eq("user") expect(subject.singularize(:money)).to eq("money") end context "with custom inflection rules" do subject do described_class.new do |inflections| inflections.singular "viruses", "virus" inflections.irregular "plus", "plusses" inflections.uncountable "dry-inflector" end end it "pluralizes using '#singular' rule" do expect(subject.singularize("viruses")).to eq("virus") end it "pluralizes using '#irregular' rule" do expect(subject.singularize("plusses")).to eq("plus") end it "doesn't singularize uncountable" do expect(subject.singularize("dry-inflector")).to eq("dry-inflector") end end end end dry-inflector-0.2.1/spec/unit/dry/inflector/tableize_spec.rb000066400000000000000000000024361406702704200241340ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#tableize" do it "pluralizes last word in snake_case strings: fancy_category => fancy_categories" do expect(subject.tableize(i("fancy_category"))).to eq("fancy_categories") end it "underscores CamelCase strings before pluralization: enlarged_testis => enlarged_testes" do expect(subject.tableize(i("enlarged_testis"))).to eq("enlarged_testes") end it "underscores CamelCase strings before pluralization: FancyCategory => fancy_categories" do expect(subject.tableize(i("FancyCategory"))).to eq("fancy_categories") end it "underscores CamelCase strings before pluralization: EnlargedTestis => enlarged_testes" do expect(subject.tableize(i("EnlargedTestis"))).to eq("enlarged_testes") end it "replaces :: with underscores: My::Fancy::Category => my_fancy_categories" do expect(subject.tableize(i("My::Fancy::Category"))).to eq("my_fancy_categories") end it "underscores CamelCase strings before pluralization: Enlarged::Testis => enlarged_testes" do expect(subject.tableize(i("Enlarged::Testis"))).to eq("enlarged_testes") end it "accepts symbols" do expect(subject.tableize(:fancy_category)).to eq("fancy_categories") end end end dry-inflector-0.2.1/spec/unit/dry/inflector/uncountable_spec.rb000066400000000000000000000013061406702704200246470ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#uncountable?" do it "returns true when empty string" do expect(subject.uncountable?(i(""))).to be(true) end it "returns true when blank string" do expect(subject.uncountable?(i(" "))).to be(true) end it "returns true when word is present in list" do expect(subject.uncountable?(i("grass"))).to be(true) end it "returns false when word is not present in list" do expect(subject.uncountable?(i("user"))).to be(false) end it "returns true when word is present in list but in different case" do expect(subject.uncountable?(i("FiSH"))).to be(true) end end end dry-inflector-0.2.1/spec/unit/dry/inflector/underscore_spec.rb000066400000000000000000000031001406702704200244730ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do describe "#underscore" do it "underscores DataMapper as data_mapper" do expect(subject.underscore(i("DataMapper"))).to eq("data_mapper") end it "underscores Merb as merb" do expect(subject.underscore(i("Merb"))).to eq("merb") end it "underscores DataMapper::Resource as data_mapper/resource" do expect(subject.underscore(i("DataMapper::Resource"))).to eq("data_mapper/resource") end it "underscores Merb::BootLoader::Rackup as merb/boot_loader/rackup" do expect(subject.underscore(i("Merb::BootLoader::Rackup"))).to eq("merb/boot_loader/rackup") end it "underscores data-mapper as data_mapper" do expect(subject.underscore(i("data-mapper"))).to eq("data_mapper") end it "underscores CLI as cli" do expect(subject.underscore(i("CLI"))).to eq("cli") end it "underscores castleKing as castle_king" do expect(subject.underscore(i("castleKing"))).to eq("castle_king") end it "underscores CLIRunner as cli_runner" do expect(subject.underscore(i("CLIRunner"))).to eq("cli_runner") end it "accepts symbols" do expect(subject.underscore(:DataMapper)).to eq("data_mapper") end it "handles acronyms" do expect(subject.underscore(i("JSON"))).to eql("json") expect(subject.underscore(i("HTTPError"))).to eql("http_error") expect(subject.underscore(i("OpenSSL::HMAC"))).to eql("openssl/hmac") expect(subject.underscore(i("OpenSSL::Digest"))).to eql("openssl/digest") end end end dry-inflector-0.2.1/spec/unit/dry/inflector_spec.rb000066400000000000000000000005371406702704200223350ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Dry::Inflector do subject(:inflector) { described_class.new } describe "#to_s" do specify do expect(inflector.to_s).to eql("#") end end describe "#inspect" do specify do expect(inflector.method(:inspect)).to eql(inflector.method(:to_s)) end end end