varar-runner 0.7.0 → 0.8.0

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: 7ae12821737b62647a5de4a1110d369489c88609a2ccb7fa7415b37aa1ad8af2
4
- data.tar.gz: 8756dbd8aaa0524aa5951e36f0702eda6fdd5968383ec33d82b579df60dfa10e
3
+ metadata.gz: 46298c6e8b7301ae6a5853dec7ffd596f5a6d9025536eb8932af54bac545944d
4
+ data.tar.gz: 67beb4b0519aece1442ab3ec0972eb6a5f41d6f5a68b72db022732f795a084bf
5
5
  SHA512:
6
- metadata.gz: f935803abd5a035507875613e97491b981f06c65ee8b8e8d46720b9d1e85f80ddfb1bb54406e9d6efb880f7d0d8e8b2adcceef9b8269173de6919de2408b1196
7
- data.tar.gz: cb62488852e40a160950a716ca3690a3e874443f8678fbd6c7c312e8558343ef01078910662c062ed29245e2a3363c27f2509fa2c976cce05d9441be6b8e4946
6
+ metadata.gz: f5c0baf64a0643451fd6b0f70e482818086d609e8ff9168c5e9654e061ac7452d55a576301da196a5b6654731e19d47c953ff25c388f34267eb642d90f2afef6
7
+ data.tar.gz: e701f85184c8738acd5dda28eda4a9b37db06c667c5e839224bc292c556bb9ef173095899fbe395e393f3691a9325e663411c69f971a1170c005832ba4bf0e42
@@ -6,27 +6,35 @@ module Varar
6
6
  module Runner
7
7
  # The `var` command-line entry point (exposed by the `exe/var`
8
8
  # executable). Today it offers a single sub-command, `varar init`, which
9
- # scaffolds a new project: a `varar.config.json`, one Markdown spec, its
10
- # step definitions, and a framework bridge that turns the specs into
9
+ # scaffolds a new project: a `varar.config.json`, one Markdown oath, its
10
+ # step definitions, and a framework bridge that turns the oaths into
11
11
  # RSpec examples or Minitest tests.
12
12
  #
13
- # The config, spec and steps mirror the TypeScript CLI (`@varar/cli`)
13
+ # The config, oath and steps mirror the TypeScript CLI (`@varar/cli`)
14
14
  # so a project started with `varar init` looks the same in every language;
15
15
  # only the bridge is Ruby-specific, because RSpec/Minitest — unlike
16
- # pytest — need an explicit generator call to discover the specs.
16
+ # pytest — need an explicit generator call to discover the oaths.
17
17
  module CLI
18
- CONFIG = <<~JSON
19
- {
20
- "docs": { "include": ["varar-examples/**/*.md"], "exclude": [] },
21
- "steps": ["varar-examples/**/*.steps.rb"]
22
- }
23
- JSON
18
+ # The steps live under the framework's conventional root (spec/ for
19
+ # RSpec, test/ for Minitest), so the config depends on the framework.
20
+ def self.config_for(framework)
21
+ root = framework == :minitest ? 'test' : 'spec'
22
+ <<~JSON
23
+ {
24
+ "docs": { "include": ["varar/**/*.md"], "exclude": [] },
25
+ "steps": ["#{root}/varar/**/*.steps.rb"]
26
+ }
27
+ JSON
28
+ end
24
29
 
25
30
  EXAMPLE_MD = <<~MARKDOWN
26
- # Hello, BDD
31
+ # Deep Thought
32
+
33
+ You're really not going to like it.
34
+
35
+ The answer to the great question of life, the universe and everything is 42.
27
36
 
28
- Given I greet "world"
29
- Then the greeting is "Hello, world!"
37
+ It was a tough assignment.
30
38
  MARKDOWN
31
39
 
32
40
  EXAMPLE_STEPS = <<~RUBY
@@ -34,16 +42,15 @@ module Varar
34
42
 
35
43
  require 'varar'
36
44
 
37
- steps(-> { { greeting: '' } }) do
38
- stimulus('I greet {string}') { |_state, name| { greeting: "Hello, \#{name}!" } }
39
- sensor('the greeting is {string}') { |state, _expected| state[:greeting] }
45
+ steps do
46
+ sensor('life, the universe and everything is {int}') { 42 }
40
47
  end
41
48
  RUBY
42
49
 
43
50
  RSPEC_BRIDGE = <<~RUBY
44
51
  # frozen_string_literal: true
45
52
 
46
- # Turn every Markdown spec matched by varar.config.json into RSpec examples —
53
+ # Turn every Markdown oath matched by varar.config.json into RSpec examples —
47
54
  # one `it` per Markdown example, discovered when this file loads.
48
55
  require 'varar/rspec'
49
56
 
@@ -57,13 +64,13 @@ module Varar
57
64
  require 'minitest/autorun'
58
65
  require 'varar/minitest'
59
66
 
60
- # Turn every Markdown spec matched by varar.config.json into Minitest tests —
67
+ # Turn every Markdown oath matched by varar.config.json into Minitest tests —
61
68
  # varar.config.json lives at the project root (the parent of test/).
62
69
  Varar::Minitest.generate_tests(Object, root: File.expand_path('..', __dir__))
63
70
  RUBY
64
71
 
65
72
  USAGE = <<~TEXT
66
- varar — scaffold and run Markdown specs
73
+ varar — scaffold and run Markdown oaths
67
74
 
68
75
  Usage:
69
76
  varar init scaffold a new project
@@ -83,15 +90,16 @@ module Varar
83
90
  # The framework bridge matches whichever adapter gem is installed
84
91
  # (RSpec by default).
85
92
  def self.run_init(cwd, out, framework: detect_framework)
93
+ root = framework == :minitest ? 'test' : 'spec'
86
94
  files = [
87
- ['varar.config.json', CONFIG],
88
- ['varar-examples/01-hello.md', EXAMPLE_MD],
89
- ['varar-examples/steps/01-hello.steps.rb', EXAMPLE_STEPS]
95
+ ['varar.config.json', config_for(framework)],
96
+ ['varar/deep-thought.md', EXAMPLE_MD],
97
+ ["#{root}/varar/deep_thought.steps.rb", EXAMPLE_STEPS]
90
98
  ]
91
99
  files << if framework == :minitest
92
- ['test/var_test.rb', MINITEST_BRIDGE]
100
+ ['test/varar_test.rb', MINITEST_BRIDGE]
93
101
  else
94
- ['spec/var_spec.rb', RSPEC_BRIDGE]
102
+ ['spec/varar_spec.rb', RSPEC_BRIDGE]
95
103
  end
96
104
 
97
105
  files.each do |rel, content|
@@ -53,13 +53,13 @@ module Varar
53
53
  end
54
54
 
55
55
  # True iff +path+ matches an include glob and no exclude glob.
56
- def match_spec?(path, include, exclude, root)
56
+ def match_oath?(path, include, exclude, root)
57
57
  rel = rel_posix(path, root)
58
58
  matches_any?(rel, include) && !matches_any?(rel, exclude)
59
59
  end
60
60
 
61
61
  # Existing files under +root+ matching any include glob, minus excludes; sorted.
62
- def find_specs(include, exclude, root)
62
+ def find_oaths(include, exclude, root)
63
63
  out = []
64
64
  include.each do |g|
65
65
  out.concat(Dir.glob(g, base: root).map { |rel| File.join(root, rel) })
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'json'
5
+ require 'varar/core'
6
+
7
+ module Varar
8
+ module Runner
9
+ # Persists run results for the language server (ADR 0014) — the shell half of
10
+ # the contract the core builds the payload for. Writes
11
+ # `<root>/.varar/<oath_path>.json`, which the (language-neutral) LSP reads to
12
+ # turn a failure into an editor diagnostic.
13
+ #
14
+ # Lives in the runner so both adapters — RSpec and Minitest — feed the same
15
+ # collector and cannot drift from each other, or from the TypeScript
16
+ # reporter this is a port of.
17
+ class Results
18
+ def initialize
19
+ @sources = {}
20
+ @examples = {}
21
+ end
22
+
23
+ # `<root>/.varar/<oath_path>.json` — the file the LSP watches.
24
+ def self.result_file_path(root, oath_path)
25
+ File.join(root, '.varar', "#{oath_path}.json")
26
+ end
27
+
28
+ # Writes one oath's results: 2-space indent plus a trailing newline,
29
+ # matching `JSON.stringify(results, null, 2)` in the TypeScript port.
30
+ def self.write(root, results)
31
+ out = result_file_path(root, results.oath_path)
32
+ FileUtils.mkdir_p(File.dirname(out))
33
+ File.write(out, "#{JSON.pretty_generate(Core::Results.to_wire(results))}\n", encoding: 'UTF-8')
34
+ out
35
+ end
36
+
37
+ # Examples in document order.
38
+ #
39
+ # A test framework reports examples in ITS order — minitest randomises by
40
+ # design — so the order they are recorded in is not the order they appear
41
+ # in the oath. The file is a cross-port contract read by tools that diff
42
+ # runs, so it is written in document order everywhere. Name breaks ties
43
+ # for examples sharing a line.
44
+ def self.document_order(examples)
45
+ examples.sort_by { |r| [r.lines.first || 0, r.name] }
46
+ end
47
+
48
+ # Accumulates one example's outcome; the oath's file is written once its
49
+ # examples are in.
50
+ def record(oath_path, source, result)
51
+ @sources[oath_path] = source
52
+ (@examples[oath_path] ||= []) << result
53
+ end
54
+
55
+ # Writes what has been recorded for `oath_path` and forgets it. Passing
56
+ # oaths are written too — a stale file would keep a diagnostic on screen
57
+ # that the run has just cleared.
58
+ def flush(root, oath_path)
59
+ recorded = @examples.delete(oath_path)
60
+ return nil if recorded.nil? || recorded.empty?
61
+
62
+ self.class.write(root, Core::OathResults.new(
63
+ version: 1,
64
+ oath_path: oath_path,
65
+ source_hash: Core::Hash32.hash_source(@sources[oath_path]),
66
+ examples: self.class.document_order(recorded)
67
+ ))
68
+ end
69
+
70
+ # Writes every oath still held — for a runner with no per-file completion hook.
71
+ def flush_all(root)
72
+ @examples.keys.to_a.each { |oath_path| flush(root, oath_path) }
73
+ end
74
+ end
75
+ end
76
+ end
@@ -19,7 +19,7 @@ module Varar
19
19
 
20
20
  module_function
21
21
 
22
- def plan_spec(path, source, registry)
22
+ def plan_oath(path, source, registry)
23
23
  Core::Plan.plan(Core::Parse.parse(path, source), registry)
24
24
  end
25
25
 
data/lib/varar/runner.rb CHANGED
@@ -7,9 +7,9 @@ require 'varar/core'
7
7
  module Varar
8
8
  # The imperative shell: discovery, step loading, planning, failure
9
9
  # rendering, and the filesystem drift baseline store. Depends on the facade
10
- # and config; never on a test framework. Port of var-runner.
10
+ # and config; never on a test framework. Port of varar-runner.
11
11
  module Runner
12
- VERSION = '0.7.0'
12
+ VERSION = '0.8.0'
13
13
  end
14
14
  end
15
15
 
@@ -18,3 +18,4 @@ require 'varar/runner/steps'
18
18
  require 'varar/runner/run'
19
19
  require 'varar/runner/render'
20
20
  require 'varar/runner/baseline_store'
21
+ require 'varar/runner/results'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: varar-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aslak Hellesøy
@@ -15,29 +15,29 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.7.0
18
+ version: 0.8.0
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: 0.7.0
25
+ version: 0.8.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: varar-config
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.7.0
32
+ version: 0.8.0
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.7.0
40
- description: Spec/step discovery, step loading, planning, failure rendering, and the
39
+ version: 0.8.0
40
+ description: Oath/step discovery, step loading, planning, failure rendering, and the
41
41
  drift baseline store.
42
42
  email:
43
43
  - aslak@oselvar.com
@@ -52,6 +52,7 @@ files:
52
52
  - lib/varar/runner/cli.rb
53
53
  - lib/varar/runner/discovery.rb
54
54
  - lib/varar/runner/render.rb
55
+ - lib/varar/runner/results.rb
55
56
  - lib/varar/runner/run.rb
56
57
  - lib/varar/runner/steps.rb
57
58
  homepage: https://varar.dev