Skip to content

Commit e4d46ec

Browse files
authored
Merge pull request #68 from envato/rbs
Add RBS type signatures for improved type safety
2 parents 435697f + 7b339e8 commit e4d46ec

24 files changed

+409
-12
lines changed

.github/workflows/ci.yml

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,42 @@
11
name: CI
22
on: [push, pull_request]
33
jobs:
4-
test:
4+
rspec:
5+
name: RSpec (Ruby ${{ matrix.ruby }})
56
strategy:
67
fail-fast: false
78
matrix:
8-
ruby: ['2.5', '2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', '4.0']
9+
ruby: ['4.0', '3.4', '3.3', '3.2', '3.1', '3.0', '2.7', '2.6', '2.5']
910
runs-on: ubuntu-latest
1011
steps:
11-
- name: Checkout
12-
uses: actions/checkout@v4
13-
- name: Set up Ruby
14-
uses: ruby/setup-ruby@v1
12+
- uses: actions/checkout@v6
13+
- uses: ruby/setup-ruby@v1
1514
with:
1615
ruby-version: ${{ matrix.ruby }}
1716
bundler-cache: true
18-
- run: bundle exec rake
17+
- name: Run RSpec
18+
run: bundle exec rake spec
19+
20+
rubocop:
21+
name: RuboCop
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@v6
25+
- uses: ruby/setup-ruby@v1
26+
with:
27+
ruby-version: '4.0'
28+
bundler-cache: true
29+
- name: Run RuboCop
30+
run: bundle exec rake rubocop
31+
32+
rbs:
33+
name: RBS
34+
runs-on: ubuntu-latest
35+
steps:
36+
- uses: actions/checkout@v6
37+
- uses: ruby/setup-ruby@v1
38+
with:
39+
ruby-version: '4.0'
40+
bundler-cache: true
41+
- name: Validate RBS signatures
42+
run: bundle exec rake rbs:validate

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ spec/reports
1515
test/tmp
1616
test/version_tmp
1717
tmp
18-
bin/
18+
bin/
19+
20+
# RBS
21+
.gem_rbs_collection

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
[Unreleased]: https://github.com/envato/zxcvbn-ruby/compare/v1.4.0...HEAD
10+
11+
## [1.4.0] - 2026-01-15
12+
13+
### Added
14+
- RBS type signatures for improved type checking and IDE support ([#68])
15+
916
### Changed
1017
- Minor fixups in gem metadata ([#67]).
1118

12-
[Unreleased]: https://github.com/envato/zxcvbn-ruby/compare/v1.3.0...HEAD
19+
[1.4.0]: https://github.com/envato/zxcvbn-ruby/compare/v1.3.0...v1.4.0
1320
[#67]: https://github.com/envato/zxcvbn-ruby/pull/67
21+
[#68]: https://github.com/envato/zxcvbn-ruby/pull/68
1422

1523
## [1.3.0] - 2026-01-02
1624

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ group :development do
1010
gem 'guard-bundler', require: false
1111
gem 'guard-rspec', require: false
1212
gem 'rake'
13+
gem 'rbs'
1314
end
1415

1516
group :test do

Rakefile

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,35 @@ require 'rubocop/rake_task'
88
RSpec::Core::RakeTask.new('spec')
99
RuboCop::RakeTask.new('rubocop')
1010

11-
task default: %i[spec rubocop]
11+
begin
12+
require 'rbs/cli'
13+
14+
namespace :rbs do
15+
desc 'Validate RBS type signatures'
16+
task :validate do
17+
sh 'rbs -I sig validate'
18+
end
19+
20+
desc 'Run RBS runtime type checker with RSpec'
21+
task :test do
22+
sh "rbs -I sig test --target 'Zxcvbn::*' rspec"
23+
end
24+
25+
desc 'List RBS types'
26+
task :list do
27+
sh 'rbs -I sig list | grep Zxcvbn'
28+
end
29+
30+
desc 'Check RBS syntax'
31+
task :parse do
32+
sh 'rbs -I sig parse sig/**/*.rbs'
33+
end
34+
end
35+
rescue LoadError
36+
# RBS is not available
37+
end
38+
39+
task default: %i[spec rubocop rbs:validate]
1240

1341
task :console do
1442
require 'zxcvbn'

lib/zxcvbn/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module Zxcvbn
4-
VERSION = '1.3.0'
4+
VERSION = '1.4.0'
55
end

rbs_collection.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# RBS collection configuration
2+
# This file specifies which type signature repositories to use
3+
4+
sources:
5+
- type: git
6+
name: ruby/gem_rbs_collection
7+
remote: https://github.com/ruby/gem_rbs_collection.git
8+
revision: main
9+
repo_dir: gems
10+
11+
path: .gem_rbs_collection

sig/README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# RBS Type Signatures
2+
3+
This directory contains [RBS](https://github.com/ruby/rbs) type signatures for the zxcvbn-ruby gem.
4+
5+
## What is RBS?
6+
7+
RBS is Ruby's type signature language. It provides a way to describe the structure of Ruby programs with:
8+
- Class and module definitions
9+
- Method signatures with parameter and return types
10+
- Instance variables and constants
11+
- Duck typing and union types
12+
13+
## Usage
14+
15+
### Validating Type Signatures
16+
17+
To validate that the RBS files are syntactically correct:
18+
19+
```bash
20+
bundle exec rake rbs:validate
21+
```
22+
23+
### Runtime Type Checking
24+
25+
To run runtime type checking against the actual Ruby code during tests:
26+
27+
```bash
28+
bundle exec rake rbs:test
29+
```
30+
31+
This runs the RSpec test suite with RBS type checking enabled, verifying that method calls match their type signatures at runtime. Note: This takes about 2 minutes to run.
32+
33+
### Other Useful Commands
34+
35+
List all Zxcvbn types:
36+
```bash
37+
bundle exec rake rbs:list
38+
```
39+
40+
Check syntax of RBS files:
41+
```bash
42+
bundle exec rake rbs:parse
43+
```
44+
45+
## File Structure
46+
47+
The signatures mirror the structure of the `lib/` directory:
48+
49+
- `sig/zxcvbn.rbs` - Main Zxcvbn module
50+
- `sig/zxcvbn/*.rbs` - Core classes (Tester, Score, Match, etc.)
51+
- `sig/zxcvbn/matchers/*.rbs` - Pattern matcher classes
52+
53+
## Adding New Signatures
54+
55+
When adding new classes or methods to the codebase, remember to:
56+
57+
1. Create or update the corresponding `.rbs` file in the `sig/` directory
58+
2. Run `bundle exec rake rbs_validate` to ensure the syntax is correct
59+
3. Keep type signatures in sync with the actual implementation
60+
61+
## Resources
62+
63+
- [RBS Documentation](https://github.com/ruby/rbs)
64+
- [RBS Syntax Guide](https://github.com/ruby/rbs/blob/master/docs/syntax.md)
65+
- [Ruby Signature Collection](https://github.com/ruby/gem_rbs_collection)

sig/zxcvbn.rbs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module Zxcvbn
2+
VERSION: String
3+
4+
DATA_PATH: Pathname
5+
6+
type word_list = Hash[String, Array[String]]
7+
type user_inputs = Array[String]
8+
9+
def self.test: (String? password, ?user_inputs user_inputs, ?word_list word_lists) -> Score
10+
end

sig/zxcvbn/crack_time.rbs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module Zxcvbn
2+
module CrackTime
3+
SINGLE_GUESS: Float
4+
NUM_ATTACKERS: Integer
5+
SECONDS_PER_GUESS: Float
6+
7+
def entropy_to_crack_time: (Numeric entropy) -> Float
8+
9+
def crack_time_to_score: (Numeric seconds) -> Integer
10+
11+
def display_time: (Numeric seconds) -> String
12+
end
13+
end

0 commit comments

Comments
 (0)