diff --git a/README.md b/README.md index 3f2368a..712aee5 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ rails db:migrate ### 1. Define an Operation -Create operation classes that inherit from `ApplicationOperation`: +Generate an operation class by running `rails generate active_operator:operation [name]`. ```ruby class Geocoding::V1 < ApplicationOperation diff --git a/lib/generators/active_operator/operation_generator.rb b/lib/generators/active_operator/operation_generator.rb new file mode 100644 index 0000000..398a7f8 --- /dev/null +++ b/lib/generators/active_operator/operation_generator.rb @@ -0,0 +1,20 @@ +require 'rails/generators' +require 'active_support/inflector' + +module ActiveOperator + module Generators + class OperationGenerator < Rails::Generators::NamedBase + include Rails::Generators::ResourceHelpers + + check_class_collision + + source_root File.expand_path("templates", __dir__) + + desc "Generates an operation with the given NAME." + + def create_operation_file + template "operation.rb.erb", "app/operations/#{file_path}.rb" + end + end + end +end diff --git a/lib/generators/active_operator/templates/operation.rb.erb b/lib/generators/active_operator/templates/operation.rb.erb new file mode 100644 index 0000000..78d5f72 --- /dev/null +++ b/lib/generators/active_operator/templates/operation.rb.erb @@ -0,0 +1,22 @@ +class <%= class_name %> < ApplicationOperation + def request + # faraday.get( + # "https://api.geocod.io/v1.8/geocode", + # { + # q: record.address, + # api_key: Rails.application.credentials.dig(:geocodio, :api_key), + # fields: "timezone" + # } + # ) + end + + def process + # result = response.dig("body", "results", 0) + + # record.update!( + # latitude: result.dig("location", "lat"), + # longitude: result.dig("location", "lng"), + # timezone: result.dig("fields", "timezone", "name") + # ) + end +end diff --git a/test/generators/active_operator/operation_generator_test.rb b/test/generators/active_operator/operation_generator_test.rb new file mode 100644 index 0000000..66b4577 --- /dev/null +++ b/test/generators/active_operator/operation_generator_test.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require "test_helper" + +require "rails/generators" +require "generators/active_operator/operation_generator" + +module ActiveOperator + module Generators + class OperationGeneratorTest < Rails::Generators::TestCase + tests ActiveOperator::Generators::OperationGenerator + + destination File.expand_path("../../tmp", __dir__) + setup :prepare_destination + + def after_teardown + FileUtils.rm_rf destination_root + super + end + + test "should generate operation file with simple name" do + run_generator ["user"] + + assert_file "app/operations/user.rb" + + operation_contents = File.read(File.join(destination_root, "app/operations/user.rb")) + assert_match "class User < ApplicationOperation", operation_contents + assert_match "def request", operation_contents + assert_match "def process", operation_contents + end + + test "should generate operation file with nested directories" do + run_generator ["geocode/v1/pull"] + + assert_file "app/operations/geocode/v1/pull.rb" + + operation_contents = File.read(File.join(destination_root, "app/operations/geocode/v1/pull.rb")) + assert_match "class Geocode::V1::Pull < ApplicationOperation", operation_contents + end + + test "should generate operation file with deeply nested directories" do + run_generator ["api/v2/users/profile/update"] + + assert_file "app/operations/api/v2/users/profile/update.rb" + + operation_contents = File.read(File.join(destination_root, "app/operations/api/v2/users/profile/update.rb")) + assert_match "class Api::V2::Users::Profile::Update < ApplicationOperation", operation_contents + end + + test "should handle operation suffix correctly" do + run_generator ["user_operation"] + + assert_file "app/operations/user_operation.rb" + + operation_contents = File.read(File.join(destination_root, "app/operations/user_operation.rb")) + assert_match "class UserOperation < ApplicationOperation", operation_contents + end + + test "should handle nested operation with operation suffix" do + run_generator ["geocode/v1/pull_operation"] + + assert_file "app/operations/geocode/v1/pull_operation.rb" + + operation_contents = File.read(File.join(destination_root, "app/operations/geocode/v1/pull_operation.rb")) + assert_match "class Geocode::V1::PullOperation < ApplicationOperation", operation_contents + end + end + end +end