flutter 0.2.0 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![CI](https://github.com/indydevs/flutter/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/indydevs/flutter/actions/workflows/main.yml)
|
4
4
|
[![codecov](https://codecov.io/github/indydevs/flutter/branch/main/graph/badge.svg?token=XANF37D9C1)](https://codecov.io/github/indydevs/flutter)
|
5
5
|
[![Gem](https://img.shields.io/gem/v/flutter)](https://rubygems.org/gems/flutter)
|
6
|
+
[![Docs](http://img.shields.io/badge/yard-docs-blue.svg)](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:
|