Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby-version:
- '3.0'
- '3.1'
- '3.2'
- '3.3'
- '3.4'

name: Ruby ${{ matrix.ruby-version }}
steps:
- uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true

- name: Run tests
run: bundle exec rspec
3 changes: 3 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--require spec_helper
--format documentation
--color
10 changes: 10 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

source "https://rubygems.org"

gemspec

group :development, :test do
gem "rspec", "~> 3.12"
gem "rake", "~> 13.0"
end
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ Typewrite.write(message, 0.05, 0, false)
```
That would result in a message that types a character every 0.05 seconds with no punctuation pauses and no newlines after each message.

## Development

### Running Tests

```bash
bundle install
bundle exec rspec
```

## Versioning

Typewrite follows the [Semantic Versioning](http://semver.org/) standard.
Expand Down
7 changes: 7 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

require "rspec/core/rake_task"

RSpec::Core::RakeTask.new(:spec)

task default: :spec
20 changes: 20 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require "bundler/setup"
require "typewrite"

RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end

config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end

config.shared_context_metadata_behavior = :apply_to_host_groups
config.filter_run_when_matching :focus
config.disable_monkey_patching!
config.order = :random
Kernel.srand config.seed
end
75 changes: 75 additions & 0 deletions spec/typewrite_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# frozen_string_literal: true

RSpec.describe Typewrite do
describe ".write" do
context "output behavior" do
before do
allow_any_instance_of(Object).to receive(:sleep)
end

it "outputs the message with a trailing newline by default" do
expect { described_class.write("hello") }.to output("hello\n").to_stdout
end

it "outputs the message without a trailing newline when line_break is false" do
expect { described_class.write("hello", 0.1, 1.5, false) }.to output("hello").to_stdout
end

it "outputs only a newline for empty string" do
expect { described_class.write("") }.to output("\n").to_stdout
end

it "outputs single character correctly" do
expect { described_class.write("x") }.to output("x\n").to_stdout
end
end

context "timing behavior" do
it "sleeps for type_rate after each character" do
sleep_calls = []
allow_any_instance_of(Object).to receive(:sleep) { |_, duration| sleep_calls << duration }

described_class.write("test", 0.05, 0, false)

expect(sleep_calls.count(0.05)).to eq(4)
end

it "sleeps for punc_rate after period" do
sleep_calls = []
allow_any_instance_of(Object).to receive(:sleep) { |_, duration| sleep_calls << duration }

described_class.write(".", 0.1, 2.0, false)

expect(sleep_calls).to include(2.0)
end

it "sleeps for punc_rate after question mark" do
sleep_calls = []
allow_any_instance_of(Object).to receive(:sleep) { |_, duration| sleep_calls << duration }

described_class.write("?", 0.1, 1.5, false)

expect(sleep_calls).to include(1.5)
end

it "sleeps for punc_rate after exclamation mark" do
sleep_calls = []
allow_any_instance_of(Object).to receive(:sleep) { |_, duration| sleep_calls << duration }

described_class.write("!", 0.1, 1.5, false)

expect(sleep_calls).to include(1.5)
end

it "sleeps for both punc_rate and type_rate on punctuation" do
sleep_calls = []
allow_any_instance_of(Object).to receive(:sleep) { |_, duration| sleep_calls << duration }

described_class.write("Hi.", 0.1, 1.5, false)

expect(sleep_calls.count(0.1)).to eq(3) # H, i, .
expect(sleep_calls.count(1.5)).to eq(1) # pause after .
end
end
end
end