Skip to content

Commit 01a78c8

Browse files
committed
Add specs
1 parent c733b15 commit 01a78c8

File tree

7 files changed

+143
-5
lines changed

7 files changed

+143
-5
lines changed

.rubocop.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
plugins:
2+
- rubocop-rake
3+
- rubocop-rspec
4+
15
AllCops:
26
TargetRubyVersion: 3.1
7+
NewCops: enable
38

49
Lint/MissingSuper:
510
Enabled: false

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ gem "rake", "~> 13.0"
1111
gem "rspec", "~> 3.0"
1212

1313
gem "rubocop", "~> 1.21"
14+
gem "rubocop-rake", "~> 0.7"
15+
gem "rubocop-rspec", "~> 3.7"

lib/mars.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# frozen_string_literal: true
22

33
require_relative "mars/version"
4+
require_relative "mars/runnable"
5+
require_relative "mars/workflows/sequential"
46

57
module Mars
68
class Error < StandardError; end

mars.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
1919
spec.metadata["homepage_uri"] = spec.homepage
2020
spec.metadata["source_code_uri"] = "https://github.com/rootstrap/mars"
2121
spec.metadata["changelog_uri"] = "https://github.com/rootstrap/mars/releases"
22+
spec.metadata["rubygems_mfa_required"] = "true"
2223

2324
# Specify which files should be added to the gem when it is released.
2425
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.

spec/mars/runnable_spec.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe Mars::Runnable do
4+
describe "#run" do
5+
context "when called directly on the base class" do
6+
let(:runnable) { described_class.new }
7+
8+
it "raises NotImplementedError" do
9+
expect { runnable.run("any input") }.to raise_error(NotImplementedError)
10+
end
11+
end
12+
13+
context "when implemented in a subclass" do
14+
let(:test_runnable_class) do
15+
Class.new(Mars::Runnable) do
16+
def run(input)
17+
"processed: #{input}"
18+
end
19+
end
20+
end
21+
22+
let(:runnable) { test_runnable_class.new }
23+
24+
it "can be successfully overridden" do
25+
result = runnable.run("test input")
26+
expect(result).to eq("processed: test input")
27+
end
28+
end
29+
30+
context "when subclass doesn't override run method" do
31+
let(:incomplete_runnable_class) do
32+
Class.new(Mars::Runnable) do
33+
# Intentionally not overriding run method
34+
end
35+
end
36+
37+
let(:runnable) { incomplete_runnable_class.new }
38+
39+
it "still raises NotImplementedError" do
40+
expect { runnable.run("input") }.to raise_error(NotImplementedError)
41+
end
42+
end
43+
end
44+
45+
describe "inheritance" do
46+
it "can be inherited" do
47+
subclass = Class.new(described_class)
48+
expect(subclass.ancestors).to include(described_class)
49+
end
50+
end
51+
end
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe Mars::Workflows::Sequential do
4+
let(:add_step_class) do
5+
Class.new do
6+
def initialize(value)
7+
@value = value
8+
end
9+
10+
def run(input)
11+
input + @value
12+
end
13+
end
14+
end
15+
16+
let(:multiply_step_class) do
17+
Class.new do
18+
def initialize(multiplier)
19+
@multiplier = multiplier
20+
end
21+
22+
def run(input)
23+
input * @multiplier
24+
end
25+
end
26+
end
27+
28+
let(:error_step_class) do
29+
Class.new do
30+
def initialize(message)
31+
@message = message
32+
end
33+
34+
def run(_input)
35+
raise StandardError, @message
36+
end
37+
end
38+
end
39+
40+
describe "#run" do
41+
it "executes steps sequentially" do
42+
add_five = add_step_class.new(5)
43+
multiply_three = multiply_step_class.new(3)
44+
add_two = add_step_class.new(2)
45+
46+
workflow = described_class.new("math_workflow", steps: [add_five, multiply_three, add_two])
47+
48+
# 10 + 5 = 15, 15 * 3 = 45, 45 + 2 = 47
49+
expect(workflow.run(10)).to eq(47)
50+
end
51+
52+
it "handles single step" do
53+
multiply_step = multiply_step_class.new(7)
54+
workflow = described_class.new("single_step", steps: [multiply_step])
55+
56+
expect(workflow.run(6)).to eq(42)
57+
end
58+
59+
it "returns input unchanged when no steps" do
60+
workflow = described_class.new("empty", steps: [])
61+
62+
expect(workflow.run(42)).to eq(42)
63+
end
64+
65+
it "propagates errors from steps" do
66+
add_step = add_step_class.new(5)
67+
error_step = error_step_class.new("Step failed")
68+
69+
workflow = described_class.new("error_workflow", steps: [add_step, error_step])
70+
71+
expect { workflow.run(10) }.to raise_error(StandardError, "Step failed")
72+
end
73+
end
74+
75+
describe "inheritance" do
76+
it "inherits from Mars::Runnable" do
77+
workflow = described_class.new("test", steps: [])
78+
expect(workflow).to be_a(Mars::Runnable)
79+
end
80+
end
81+
end

spec/mars_spec.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
RSpec.describe Mars do
44
it "has a version number" do
5-
expect(Mars::VERSION).not_to be nil
6-
end
7-
8-
it "does something useful" do
9-
expect(true).to eq(true)
5+
expect(Mars::VERSION).not_to be_nil
106
end
117
end

0 commit comments

Comments
 (0)