https://github.com/alexander-senko/magic-support
Utility classes and Ruby extensions beyond Active Support
https://github.com/alexander-senko/magic-support
core-ext rspec ruby rubygems
Last synced: 23 days ago
JSON representation
Utility classes and Ruby extensions beyond Active Support
- Host: GitHub
- URL: https://github.com/alexander-senko/magic-support
- Owner: Alexander-Senko
- License: mit
- Created: 2024-11-24T15:52:55.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2024-12-07T09:18:12.000Z (6 months ago)
- Last Synced: 2025-05-06T19:12:40.098Z (23 days ago)
- Topics: core-ext, rspec, ruby, rubygems
- Language: Ruby
- Homepage:
- Size: 24.4 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# ✨ Magic Support


Magic Support is a collection of utility classes and standard library extensions
that were found useful for my pet projects.It’s inspired by [Active Support](
https://github.com/rails/rails/tree/main/activesupport
).## Installation
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
Install the gem and add to the application's Gemfile by executing:
```bash
bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
```If bundler is not being used to manage dependencies, install the gem by executing:
```bash
gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
```## Core extensions
### Loading
Magic Support is broken into small pieces so that only the desired extensions can be loaded.
It also has some convenience entry points to load related extensions in one shot, even all of them.#### Cherry-picking
For every single method defined as a core extension a note says where such a method is defined.
That means that you can `require` it like this:
```ruby
require 'magic/core_ext//'
```Magic Support has been carefully revised so that cherry-picking a file loads only strictly needed dependencies, if any.
#### Loading grouped core extensions
As a rule of thumb, extensions to `SomeClass` are available in
one shot by loading `magic/core_ext/some_class`.Thus, to load all extensions to `Kernel`:
```ruby
require 'magic/core_ext/kernel'
```#### Loading all core extensions
You may prefer just to load all core extensions, there is a file for that:
```ruby
require 'magic/core_ext'
```### Extensions to all objects
#### `#optional`
Yields self to the block and returns the result of the block if it’s truthy, and self otherwise.
```ruby
rand(6) # returns 0–5
.optional { it + 1 if one_based? } # returns 1–6 if 1-based, or
# the original 0–5 otherwise
```It can be considered as a conditional `#then`.
Good usage for `#optional` is value piping in method chains with conditional processing:
```ruby
@people = Person
.optional { it.where created_at: (1.hour.ago...) if new? }
.optional { anonymize it if gdpr? }
.optional { try :decorate }
```Defined in `core_ext/kernel/optional`.
## Gems
### Author
It holds authors info to be used primarily in gem specs.
#### Loading
> [!NOTE]
> If you plan to use `Gem::Author` in your gemspec, it should be loaded before the gemspec.Add Magic Support as a plugin to the application’s Gemfile.
```ruby
plugin 'magic-support'
gem 'magic-support'
```> [!IMPORTANT]
> This will work with `bundle install`, but not with every Bundler command.
> E.g., `bundle lock` used by GitHub with Bundler cache will fail.If bundler is not being used or fails to load, pre-install the gem by executing:
```bash
gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
```#### Usage
1. Inherit `Gem::Author` inside your gem and add the authors’ info.
```ruby
require 'rubygems/author'
module MyLib
class Author < Gem::Author
new(
name: 'Your Name',
email: '[email protected]',
github: 'Your-GitHub-Username',
)
end
end
```2. You can call some helper methods now.
```ruby
Gem::Specification.new do |spec|
spec.name = 'my_lib'
spec.version = MyLib::VERSION
spec.authors = MyLib::Author.names
spec.email = MyLib::Author.emails
spec.homepage = "#{MyLib::Author.github_url}/#{spec.name}"
end
```## RSpec
### Method specs
Enables one to write specs for single methods.
> [!WARNING]
> Planed for extraction into a separate gem.#### Loading
Require it in `spec_helper.rb`:
```ruby
require 'rspec/method'
```#### Usage
Include a method reference into the description.
The reference should start with either
- `.` for class methods or
- `#` for instance ones.```ruby
RSpec.describe MyClass do
describe '.class_method' do
its([arg1, arg2]) { is_expected.to be return_value }
enddescribe '#instance_method' do
its([arg1, arg2]) { is_expected.to be return_value }
end
end
```> [!NOTE]
> Though `rspec/its` is not needed, it could come useful (see [the article on method testing](
> https://zverok.space/blog/2017-11-01-rspec-method-call.html
> )).Within examples, `subject` is set to the corresponding `Method` instance.
In cases when the method couldn’t be found (e.g., due to delegation via `method_missing`), it’s set to a `Proc` instance
instead.
Anyway, one may treat it as something _callable_.A method name is exposed as a `Symbol` via `method_name`.
> [!NOTE]
> `subject.name` may be undefined, use `method_name` instead.##### Delegated methods
One can use `it_behaves_like :delegated` for delegated methods.
This will ensure that calling the method calls the one of the same name on a delegate under the hood passing it the arguments.```ruby
RSpec.describe MyClass do
describe '#method_with_arguments' do
it_behaves_like :delegated, to: delegate, with: [arg1, arg2]
enddescribe '#method_without_arguments' do
it_behaves_like :delegated, to: delegate
end
end
```##### Module specs
It’s recommended to use class method notation, when writing specs for module functions.
```ruby
RSpec.describe MyModule do
describe '.module_function' do
# put the examples here
end
end
```## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/Alexander-Senko/magic-support. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/Alexander-Senko/magic-support/blob/main/CODE_OF_CONDUCT.md).
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
## Code of Conduct
Everyone interacting in the Magic::Support project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Alexander-Senko/magic-support/blob/main/CODE_OF_CONDUCT.md).