be-let-it-be 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a90cf24bfc3bff9e7fae3cf454c213cb9e98d2e75f7fa2a0461579de14ae9f55
4
- data.tar.gz: bb50797917fcf5dd15d3bf51b4a71d7353a9425341e15fd6ab5a052192c98e39
3
+ metadata.gz: a7d99f9f4833b5a845a011636240c7021580144ae51712caa303fed93889a562
4
+ data.tar.gz: 4bb51c1083cb8a269e37d5da677efdd68bba8f8ba163c7619586b3f80ef65ea0
5
5
  SHA512:
6
- metadata.gz: 17c94400b69be02e85c41769ab2ac214d6c38ca56f9d86748158589a06d0d65f7c17774573b61086e0e557a7a485fdbce8008c584b115d551221f15fffe347f1
7
- data.tar.gz: 790225081995f8772b01b8ae08273d6fceddd6907a15c09e14bc8e8164db3fdfd0b1062195d12aa752705a12ad8e5473c84316b5d4c0d613c4b6bdeb3b0d644d
6
+ metadata.gz: '09327031b5cb63a160b6f43eed9bc15fc7d8416d5aefdd9aa5e90849c7f7f277838e1d5147999e0fdeb541008337cd5edb9056a61949c50210128534c8ecf049'
7
+ data.tar.gz: 646cbf8d1740b56d924214b174831ccd872e2c74401b618367de4f85d22cf7050be0ecb117e20adb195ac3d45e76951e3b7e18a9636605dfac50ab33359e3f9e
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # be-let-it-be
2
2
 
3
- [![Ruby](https://github.com/moznion/be-let-it-be/actions/workflows/main.yml/badge.svg)](https://github.com/moznion/be-let-it-be/actions/workflows/main.yml)
3
+ [![Ruby](https://github.com/moznion/be-let-it-be/actions/workflows/main.yml/badge.svg)](https://github.com/moznion/be-let-it-be/actions/workflows/main.yml) [![Gem Version](https://badge.fury.io/rb/be-let-it-be.svg?icon=si%3Arubygems)](https://badge.fury.io/rb/be-let-it-be)
4
4
 
5
5
  A command-line tool that automatically converts RSpec's `let` and `let!` declarations to `let_it_be` where it's safe to do so. The tool runs your tests after each conversion to ensure they still pass, making the optimization process safe and reliable.
6
6
 
@@ -1,47 +1,58 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "parser/current"
3
+ require "prism"
4
4
 
5
5
  module BeLetItBe
6
6
  class Analyzer
7
7
  def initialize(file)
8
- @ast = Parser::CurrentRuby.parse(File.read(file))
8
+ file_path = file.respond_to?(:path) ? file.path : file
9
+ @ast = Prism.parse_file(file_path).value
9
10
  end
10
11
 
11
12
  def find_lets
12
- traverse(@ast, [])
13
+ traverse(@ast)
13
14
  end
14
15
 
15
16
  private
16
17
 
17
- def traverse(node, lets)
18
- # FIXME: lets should be immutable
19
- return lets unless node.is_a?(Parser::AST::Node)
18
+ def traverse(node)
19
+ return [] unless node.is_a?(Prism::Node)
20
20
 
21
21
  let_info = extract_let_info(node)
22
- lets << let_info unless let_info.nil?
23
-
24
- node.children.each do |child|
25
- traverse(child, lets) if child.is_a?(Parser::AST::Node)
22
+ current_lets = let_info.nil? ? [] : [let_info]
23
+
24
+ child_lets = case node
25
+ when Prism::ProgramNode
26
+ traverse(node.statements)
27
+ when Prism::StatementsNode
28
+ node.body.flat_map { |child| traverse(child) }
29
+ when Prism::CallNode
30
+ traverse(node.block)
31
+ when Prism::BlockNode
32
+ traverse(node.body)
33
+ else
34
+ []
26
35
  end
27
36
 
28
- lets
37
+ current_lets + child_lets
29
38
  end
30
39
 
31
40
  def extract_let_info(node)
32
- return nil unless node.type == :send
33
- return nil unless node.children[0].nil?
41
+ return nil unless node.is_a?(Prism::CallNode)
42
+ return nil unless node.receiver.nil?
43
+
44
+ method_name = node.name
45
+ return nil unless [:let, :let!].include?(method_name)
34
46
 
35
- method_name = node.children[1]
36
- return nil unless %i[let let!].include?(method_name)
47
+ return nil unless node.arguments && node.arguments.arguments.length > 0
37
48
 
38
- args = node.children[2]
39
- let_name = args.children[0]
40
- return nil unless args && args.type == :sym
49
+ first_arg = node.arguments.arguments[0]
50
+ return nil unless first_arg.is_a?(Prism::SymbolNode)
41
51
 
42
- line = node.location.line
52
+ name = first_arg.value.to_sym
53
+ line = node.location.start_line
43
54
 
44
- {type: method_name, name: let_name, line:, node:}
55
+ {type: method_name, name:, line:, node:}
45
56
  end
46
57
  end
47
58
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "thor"
4
- require "parser/current"
5
- require "unparser"
6
4
  require "open3"
7
5
 
8
6
  module BeLetItBe
@@ -11,6 +9,7 @@ module BeLetItBe
11
9
  option :dryrun, type: :boolean, default: false, desc: "Show what would be converted without modifying files"
12
10
  option :verbose, type: :boolean, default: false, desc: "Show the processing output verboselly"
13
11
  option :rspec_cmd, type: :string, default: "bundle exec rspec", desc: "RSpec command to check the behaviour"
12
+ option :dryrun_exit_code, type: :numeric, default: 1, desc: "Exit code to use in dryrun mode when any convertible declarations are present"
14
13
 
15
14
  def convert(file)
16
15
  @processed_let_lines = []
@@ -36,7 +35,7 @@ module BeLetItBe
36
35
  num_of_lets = lets.length
37
36
 
38
37
  if num_of_lets.zero?
39
- say "no let/let! in the given spec; do nothing"
38
+ say "no let/let! in the given spec; do nothing"
40
39
  exit 0
41
40
  end
42
41
 
@@ -51,11 +50,11 @@ module BeLetItBe
51
50
  say "[#{processed_num}/#{num_of_lets}] Testing conversion of #{let[:type]} :#{let[:name]} at #{file}:#{let[:line]}"
52
51
 
53
52
  if converter.try_conversion_single_let(let, temp_file, -> { run_rspec(temp_file) })
54
- say " Converted to let_it_be"
53
+ say " Converted to let_it_be"
55
54
  converter = Converter.new(temp_file) # pile the converted items
56
55
  converted_count += 1
57
56
  else
58
- say " Keeping original #{let[:type]} (test failed with let_it_be)"
57
+ say " Keeping original #{let[:type]} (test failed with let_it_be)"
59
58
  end
60
59
 
61
60
  @processed_let_lines << let[:line]
@@ -63,14 +62,16 @@ module BeLetItBe
63
62
  end
64
63
 
65
64
  if converted_count > 0
65
+ say "🚀 Successfully converted #{converted_count} out of #{lets.size} definitions to let_it_be"
66
+
66
67
  if options[:dryrun]
67
68
  puts File.read(temp_file)
69
+ exit options[:dryrun_exit_code]
68
70
  else
69
71
  File.write(file, File.read(temp_file))
70
72
  end
71
- say "✅ Successfully converted #{converted_count} out of #{lets.size} definitions to let_it_be"
72
73
  else
73
- say " No conversions were possible (all tests failed with let_it_be)"
74
+ say "❣️ No conversions were possible (all tests failed with let_it_be)"
74
75
  end
75
76
  ensure
76
77
  File.unlink(temp_file) if File.exist?(temp_file)
@@ -1,22 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "parser/current"
4
- require "unparser"
3
+ require "prism"
5
4
  require "tempfile"
6
5
 
7
6
  module BeLetItBe
8
7
  class Converter
9
8
  def initialize(file)
10
- @file = file
9
+ @file = file.respond_to?(:path) ? file.path : file
11
10
  end
12
11
 
13
12
  def try_conversion_single_let(let_info, output_file, exam)
14
13
  source = File.read(@file)
15
- buffer = Parser::Source::Buffer.new(@file, source:)
16
14
 
17
- temp_rewriter = Parser::Source::TreeRewriter.new(buffer)
18
- apply_single_conversion(let_info, temp_rewriter)
19
- File.write(output_file, temp_rewriter.process)
15
+ File.write(output_file, apply_single_conversion(let_info, source))
20
16
 
21
17
  passed = exam.call
22
18
  unless passed
@@ -27,11 +23,16 @@ module BeLetItBe
27
23
 
28
24
  private
29
25
 
30
- def apply_single_conversion(let_info, rewriter)
26
+ def apply_single_conversion(let_info, source)
31
27
  node = let_info[:node]
32
- method_range = node.loc.selector
33
28
 
34
- rewriter.replace(method_range, "let_it_be")
29
+ start_offset = node.message_loc.start_offset
30
+ end_offset = node.message_loc.end_offset
31
+
32
+ new_source = source.dup
33
+ new_source[start_offset...end_offset] = "let_it_be"
34
+
35
+ new_source
35
36
  end
36
37
  end
37
38
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BeLetItBe
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.3"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: be-let-it-be
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - moznion
@@ -10,33 +10,19 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: parser
13
+ name: prism
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '3.3'
18
+ version: '1.4'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '3.3'
26
- - !ruby/object:Gem::Dependency
27
- name: unparser
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: '0.7'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '0.7'
25
+ version: '1.4'
40
26
  - !ruby/object:Gem::Dependency
41
27
  name: thor
42
28
  requirement: !ruby/object:Gem::Requirement
@@ -51,8 +37,8 @@ dependencies:
51
37
  - - "~>"
52
38
  - !ruby/object:Gem::Version
53
39
  version: '1.3'
54
- description: A command-line tool that analyzes RSpec files and converts let/let! to
55
- let_it_be where tests still pass
40
+ description: A command-line tool that automatically converts RSpec's `let` and `let!`
41
+ declarations to `let_it_be` where it's safe to do so.
56
42
  email:
57
43
  - moznion@mail.moznion.net
58
44
  executables:
@@ -61,7 +47,6 @@ extensions: []
61
47
  extra_rdoc_files: []
62
48
  files:
63
49
  - ".standard.yml"
64
- - CHANGELOG.md
65
50
  - CODE_OF_CONDUCT.md
66
51
  - LICENSE.txt
67
52
  - README.md
@@ -82,7 +67,7 @@ licenses:
82
67
  metadata:
83
68
  homepage_uri: https://github.com/moznion/be-let-it-be
84
69
  source_code_uri: https://github.com/moznion/be-let-it-be
85
- changelog_uri: https://github.com/moznion/be-let-it-be/blob/main/CHANGELOG.md
70
+ changelog_uri: https://github.com/moznion/be-let-it-be/releases
86
71
  rdoc_options: []
87
72
  require_paths:
88
73
  - lib
data/CHANGELOG.md DELETED
@@ -1,5 +0,0 @@
1
- ## [Unreleased]
2
-
3
- ## [0.1.0] - 2025-06-08
4
-
5
- - Initial release