flutter 0.2.0 → 0.2.2
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 +4 -4
- data/.yardopts +2 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +5 -0
- data/Guardfile +3 -3
- data/README.md +39 -30
- data/Rakefile +6 -7
- data/TODO.md +2 -2
- data/lib/flutter/minitest.rb +1 -1
- data/lib/flutter/parser.rb +11 -5
- data/lib/flutter/rspec.rb +2 -1
- data/lib/flutter/tracker.rb +6 -2
- data/lib/flutter/version.rb +1 -1
- data/lib/flutter.rb +0 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3929d7a4586b20232226e254f271162bba4ee4a8212bd65a59b1a06c371d9f3
|
4
|
+
data.tar.gz: ed09b644a323dd8fc4dccb380a6212d272fb283708e9edbdc42487cd82728513
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d696e398b4e0130b48ffa9f36b5fc7371ab62b9b37670a652e736f56c202df95ca0bef74c934cc8d2c802818b10d90e80b99c902e04b3ebdcf12601d14c0a752
|
7
|
+
data.tar.gz: fc2e7556e864e626b9670344ef44c5d12c62321b63a48be5637082fc1213422184ee54d53ad42c9f0f7852420f1ce923d58bf2fdbfebeac6104a2307b7668f93
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
7
|
## Unreleased
|
8
|
+
## 0.2.2 - 2022-10-03
|
9
|
+
### Added
|
10
|
+
- Document configuration options in README
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
- Delay requiring source files explicitely and only in the case where
|
14
|
+
- Ensure the previous test->coverage mapping is merged with current
|
15
|
+
|
16
|
+
## 0.2.1
|
17
|
+
### Fixed
|
18
|
+
- Corrected integration examples for guard in README
|
19
|
+
|
8
20
|
## 0.2.0
|
9
21
|
### Added
|
10
22
|
- CI Recipe in README
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
guard :minitest, test_folders: ["test"] do
|
4
|
-
watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { "test" }
|
4
|
+
watch(%r{^(test|lib)/(.*/)?([^/]+)\.rb$}) { "test" }
|
5
5
|
end
|
6
6
|
|
7
|
-
guard :rspec, cmd: "rspec" do
|
8
|
-
watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { "spec" }
|
7
|
+
guard :rspec, cmd: "rspec", all_on_start: true do
|
8
|
+
watch(%r{^(spec|lib)/(.*/)?([^/]+)\.rb$}) { "spec" }
|
9
9
|
end
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
[](https://github.com/indydevs/flutter/actions/workflows/main.yml)
|
4
4
|
[](https://codecov.io/github/indydevs/flutter)
|
5
5
|
[](https://rubygems.org/gems/flutter)
|
6
|
+
[](https://flutter.indydevs.org)
|
6
7
|
|
7
8
|
```
|
8
9
|
__ __
|
@@ -22,7 +23,7 @@ or in continuous integration environments to only run the subset of tests affect
|
|
22
23
|
## How?
|
23
24
|
Flutter tracks each method call within the context of each test case in your test suite and persists this mapping along with
|
24
25
|
a signature for all the methods that were exercised. On subsequent runs Flutter intercepts test enumeration and skips any test if
|
25
|
-
|
26
|
+
**ALL** the following conditions are true:
|
26
27
|
|
27
28
|
- The test was seen before
|
28
29
|
- The source of the test has not changed
|
@@ -42,30 +43,26 @@ all the following conditions are true:
|
|
42
43
|
```ruby
|
43
44
|
require 'flutter'
|
44
45
|
```
|
45
|
-
- Enable & configure it in your `test_helper.rb
|
46
|
+
- Enable & configure it in your `test_helper.rb` (See [Configuration options](#configuration-options) for available options):
|
46
47
|
|
47
48
|
```ruby
|
48
49
|
Flutter.configure do |config|
|
49
50
|
config.enabled = true
|
50
|
-
# Paths to consider when tracking test -> source mappings. Default: Dir.pwd/*
|
51
|
-
config.sources = ["./app/*", "./test/*"]
|
52
|
-
# Paths to ignore for tracking test -> source. Default: ./vendor
|
53
|
-
config.exclusions = ["./vendor/*"]
|
54
|
-
# Storage type. Default: Flutter::Persistence::Marshal
|
55
|
-
config.storage_class = Flutter::Persistence::Marshal
|
56
|
-
# Where to store the state. Default: ./.flutter
|
57
|
-
config.storage_options = {path: "./.flutter"}
|
58
|
-
# Whether to reset the stored state before the test run. Default: false
|
59
|
-
config.reset_storage = false
|
60
51
|
end
|
61
52
|
```
|
53
|
+
- Run your test suite the way you normally would (for example: `bundle exec rake test`). The first run will run all
|
54
|
+
tests. After the test run has completed the mapping of test cases to exercised code will be persisted in the `./.flutter`
|
55
|
+
folder.
|
56
|
+
- Now make changes and run the test suite again. Only the relevant tests will be executed.
|
62
57
|
|
63
58
|
#### With guard
|
64
|
-
|
59
|
+
Using the same configuration as above (and assuming that the application
|
60
|
+
sources are in the `./lib` folder while the tests are in the `./test` folder)
|
61
|
+
add the following to your `Guardfile`:
|
65
62
|
|
66
63
|
```ruby
|
67
64
|
guard :minitest, test_folders: ["test"] do
|
68
|
-
watch(%r{^
|
65
|
+
watch(%r{^(test|lib)/(.*/)?([^/]+)\.rb$}) { "test" }
|
69
66
|
end
|
70
67
|
```
|
71
68
|
|
@@ -81,31 +78,43 @@ end
|
|
81
78
|
```ruby
|
82
79
|
require 'flutter'
|
83
80
|
```
|
84
|
-
- Enable & configure it in your `spec_helper.rb
|
81
|
+
- Enable & configure it in your `spec_helper.rb` (See [Configuration options](#configuration-options) for available options):
|
85
82
|
|
86
83
|
```ruby
|
87
84
|
Flutter.configure do |config|
|
88
85
|
config.enabled = true
|
89
|
-
# Paths to consider when tracking test -> source mappings. Default: Dir.pwd/*
|
90
|
-
config.sources = ["./app/*", "./test/*"]
|
91
|
-
# Paths to ignore for tracking test -> source. Default: ./vendor
|
92
|
-
config.exclusions = ["./vendor/*"]
|
93
|
-
# Storage type. Default: Flutter::Persistence::Marshal
|
94
|
-
config.storage_class = Flutter::Persistence::Marshal
|
95
|
-
# Where to store the state. Default: ./.flutter
|
96
|
-
config.storage_options = {path: "./.flutter"}
|
97
|
-
# Whether to reset the stored state before the test run. Default: false
|
98
|
-
config.reset_storage = false
|
99
86
|
end
|
100
87
|
```
|
88
|
+
- Run your specs the way you normally would (for example: `bundle exec rspec`). The first run will run all
|
89
|
+
tests. After the test run has completed the mapping of test cases to exercised code will be persisted in the `./.flutter`
|
90
|
+
folder.
|
91
|
+
- Now make changes and run rspec again. Only the relevant examples will be executed.
|
92
|
+
|
101
93
|
#### With guard
|
102
|
-
Using the same configuration as above
|
94
|
+
Using the same configuration as above (and assuming that the application
|
95
|
+
sources are in the `./app` & `./lib` folders while the specs are in the `./spec` folder)
|
96
|
+
add the following to your `Guardfile`:
|
103
97
|
|
104
98
|
```ruby
|
105
99
|
guard :rspec, cmd: "rspec" do
|
106
|
-
watch(%r{^
|
100
|
+
watch(%r{^(spec|app|lib)/(.*/)?([^/]+)\.rb$}) { "spec" }
|
107
101
|
end
|
108
102
|
```
|
103
|
+
|
104
|
+
### Configuration options
|
105
|
+
| option | Description | Type | Default |
|
106
|
+
|:-----------------:|:---------------------------------------------------------------|:---------------------------------------:|:-------------------------------:|
|
107
|
+
| `enabled` | Whether flutter is enabled | `TrueClass, FalseClass` | `true` |
|
108
|
+
| `sources` | List of glob style expressions to select source files to track | `Set` | `["#{Dir.pwd}/*"]` |
|
109
|
+
| `exclusions` | List of glob style expressions to exclude sources files | `Set` | `["#{Dir.pwd}/vendor}/*"]` |
|
110
|
+
| `storage_class` | The storage class to use for persisting the state | `Flutter::Persistence::AbstractStorage` | `Flutter::Persistence::Marshal` |
|
111
|
+
| `storage_options` | Additional options to pass to the storage class | `Hash` | `{path: './.flutter'}` |
|
112
|
+
| `reset_storage` | Whether to clear the persisted state on initialization | `TrueClass, FalseClass` | `false` |
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
|
109
118
|
## Configuring flutter in continuous integration
|
110
119
|
|
111
120
|
Flutter can be used in continuous integration environments to speed up the turn
|
@@ -174,9 +183,9 @@ To install this gem onto your local machine, run `bundle exec rake install`.
|
|
174
183
|
and contains useful details.
|
175
184
|
- Create a new release using the `release` rake task as follows (for more details about specifying the version change
|
176
185
|
run `gem bump --help` which is the command used by the task):
|
177
|
-
- Patch release `bundle exec rake release["
|
178
|
-
- Minor release `bundle exec rake release["
|
179
|
-
- Major release `bundle exec rake release["
|
186
|
+
- Patch release `bundle exec rake release["patch"]`
|
187
|
+
- Minor release `bundle exec rake release["minor"]`
|
188
|
+
- Major release `bundle exec rake release["major"]`
|
180
189
|
> **Note**
|
181
190
|
> The `release` rake task automates updating the changelog & version, committing the changes & creating a new tag
|
182
191
|
- Push the tag. The CI workflow for tag pushes will take care of publishing the gem & creating a github release.
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "date"
|
3
4
|
require "rake/testtask"
|
4
5
|
require "keepachangelog"
|
5
6
|
|
@@ -27,11 +28,11 @@ desc "Increment the version, update changelog and create a tag for the release"
|
|
27
28
|
task :release, [:version] do |_t, args|
|
28
29
|
parser = Keepachangelog::MarkdownParser.load("CHANGELOG.md")
|
29
30
|
log = parser.parsed_content["versions"].delete("Unreleased")
|
30
|
-
sh("gem bump --pretend #{args[:version]}") do |ok, _|
|
31
|
+
sh("gem bump --pretend -v #{args[:version]}") do |ok, _|
|
31
32
|
if ok
|
32
|
-
new_version = %x(gem bump --no-commit #{args[:version]} | awk '{print $4}' | uniq).chomp
|
33
|
+
new_version = %x(gem bump --no-commit -v #{args[:version]} | awk '{print $4}' | uniq).chomp
|
33
34
|
parser.parsed_content["versions"]["Unreleased"] = { "url" => nil, "date" => nil, "changes" => {} }
|
34
|
-
parser.parsed_content["versions"][new_version] = log
|
35
|
+
parser.parsed_content["versions"]["#{new_version} - #{Date.today}"] = log
|
35
36
|
File.open("CHANGELOG.md", "w") do |file|
|
36
37
|
file.write(parser.to_md)
|
37
38
|
end
|
@@ -49,10 +50,8 @@ task :release_notes, [:version] do |_t, args|
|
|
49
50
|
parser = Keepachangelog::MarkdownParser.load("CHANGELOG.md")
|
50
51
|
parser.parsed_content.delete("intro")
|
51
52
|
parser.parsed_content.delete("title")
|
52
|
-
parser.parsed_content["versions"] = parser.parsed_content["versions"].select { |k, _v| k
|
53
|
+
parser.parsed_content["versions"] = parser.parsed_content["versions"].select { |k, _v| k.start_with?(version) }
|
53
54
|
lines = parser.to_md.split("\n")
|
54
|
-
chunk =
|
55
|
-
lines.slice_after { |line| line.include?("## #{version}") }.to_a[1] || []
|
56
|
-
)
|
55
|
+
chunk = lines.slice_after { |line| line.include?("## #{version}") }.to_a[1] || []
|
57
56
|
puts chunk.join("\n")
|
58
57
|
end
|
data/TODO.md
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
## Code quality
|
10
10
|
- [ ] Separate public/private API
|
11
|
-
- [
|
11
|
+
- [x] Add rdoc / yard documentation
|
12
12
|
|
13
13
|
## Testing
|
14
14
|
- [x] Improve test coverage
|
@@ -26,5 +26,5 @@
|
|
26
26
|
## Usability
|
27
27
|
- [x] Quick start guide
|
28
28
|
- [x] Recipes for guard
|
29
|
-
- [
|
29
|
+
- [x] Recipes for CI
|
30
30
|
|
data/lib/flutter/minitest.rb
CHANGED
data/lib/flutter/parser.rb
CHANGED
@@ -51,9 +51,14 @@ module Flutter
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def build_signatures
|
54
|
-
require_relative @file
|
55
54
|
@targets.each do |container|
|
56
|
-
|
55
|
+
begin
|
56
|
+
instance = Kernel.const_get(container)
|
57
|
+
rescue NameError
|
58
|
+
require_relative @file
|
59
|
+
instance = Kernel.const_get(container)
|
60
|
+
end
|
61
|
+
|
57
62
|
class_methods = instance.methods + instance.private_methods
|
58
63
|
instance_methods = instance.instance_methods + instance.private_instance_methods
|
59
64
|
|
@@ -65,11 +70,12 @@ module Flutter
|
|
65
70
|
hash = source_hash(instance.instance_method(method))
|
66
71
|
["#{container}:#{method}", hash] if hash
|
67
72
|
end.compact.to_h)
|
68
|
-
rescue
|
69
|
-
|
73
|
+
rescue
|
74
|
+
warn("Failed to parse #{@file}")
|
75
|
+
break
|
70
76
|
end
|
71
77
|
rescue LoadError
|
72
|
-
|
78
|
+
warn("Failed to inspect #{@file}")
|
73
79
|
end
|
74
80
|
|
75
81
|
def source_hash(callable)
|
data/lib/flutter/rspec.rb
CHANGED
@@ -52,7 +52,8 @@ if defined?(RSpec.configure)
|
|
52
52
|
config.around(:each) do |example|
|
53
53
|
Flutter::RSpec.tracker.start(example.full_description) if Flutter.enabled
|
54
54
|
example.run
|
55
|
-
Flutter::RSpec.tracker.stop
|
55
|
+
Flutter::RSpec.tracker.stop(example.full_description,
|
56
|
+
example.execution_result.exception.nil?) if Flutter.enabled
|
56
57
|
end
|
57
58
|
|
58
59
|
config.after(:suite) do
|
data/lib/flutter/tracker.rb
CHANGED
@@ -26,6 +26,7 @@ module Flutter
|
|
26
26
|
@exclusions = exclusions.map { |s| File.absolute_path(s) }
|
27
27
|
@storage = storage_class.new(**storage_options)
|
28
28
|
@test_mapping = @storage.test_mapping
|
29
|
+
@previous_test_mapping = {}
|
29
30
|
@test_source_mapping = {}
|
30
31
|
@source_mapping = @storage.source_mapping
|
31
32
|
@current_source_mapping = {}
|
@@ -39,7 +40,7 @@ module Flutter
|
|
39
40
|
def start(test)
|
40
41
|
# Delete test from the in-memory mapping to allow each new test run
|
41
42
|
# to store all the functions that the test calls into
|
42
|
-
@test_mapping.delete(test)
|
43
|
+
@previous_test_mapping[test] = @test_mapping.delete(test)
|
43
44
|
@current_tracepoint = TracePoint.new(:call) do |tp|
|
44
45
|
hit!(test, tp)
|
45
46
|
end
|
@@ -47,8 +48,11 @@ module Flutter
|
|
47
48
|
end
|
48
49
|
|
49
50
|
# End tracking (should be called after a call to {#start})
|
50
|
-
|
51
|
+
# @param [String] test A unique identifier for the test
|
52
|
+
# @param [TrueClass, FalseClass] success Whether the test succeeded
|
53
|
+
def stop(test, success)
|
51
54
|
@current_tracepoint&.disable
|
55
|
+
@test_mapping[test].merge!(@previous_test_mapping.delete(test) || {}) { |_, old, new| old + new } unless success
|
52
56
|
end
|
53
57
|
|
54
58
|
##
|
data/lib/flutter/version.rb
CHANGED
data/lib/flutter.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flutter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ali-Akber Saifee
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-10-
|
12
|
+
date: 2022-10-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: deep_merge
|
@@ -65,6 +65,7 @@ extra_rdoc_files: []
|
|
65
65
|
files:
|
66
66
|
- ".overcommit.yml"
|
67
67
|
- ".rubocop.yml"
|
68
|
+
- ".yardopts"
|
68
69
|
- CHANGELOG.md
|
69
70
|
- CODE_OF_CONDUCT.md
|
70
71
|
- Gemfile
|
@@ -84,13 +85,15 @@ files:
|
|
84
85
|
- lib/flutter/version.rb
|
85
86
|
- lib/minitest/flutter_plugin.rb
|
86
87
|
- sig/flutter.rbs
|
87
|
-
homepage: https://
|
88
|
+
homepage: https://flutter.indydevs.org
|
88
89
|
licenses:
|
89
90
|
- MIT
|
90
91
|
metadata:
|
91
|
-
homepage_uri: https://
|
92
|
+
homepage_uri: https://flutter.indydevs.org
|
92
93
|
source_code_uri: https://github.com/indydevs/flutter
|
94
|
+
bug_tracker_uri: https://github.com/indydevs/flutter/issues
|
93
95
|
changelog_uri: https://github.com/indydevs/flutter/blob/master/CHANGELOG.md
|
96
|
+
ducmentation_uri: https://flutter.indydevs.org
|
94
97
|
post_install_message:
|
95
98
|
rdoc_options: []
|
96
99
|
require_paths:
|