pinspec 0.2.0 → 0.3.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.
@@ -1,103 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
-
5
- module Pinspec
6
- module Emit
7
- class Namer
8
- MAX_DESCRIPTION = 120
9
-
10
- Facts = Data.define(:case_id, :origin, :outcome, :method_name, :class_name, :parameters)
11
-
12
- def initialize(target:, enabled: false, client: nil)
13
- @target = target
14
- @enabled = enabled
15
- @client = client
16
- end
17
-
18
- def enabled?
19
- @enabled && !@client.nil?
20
- end
21
-
22
- def describe(cases)
23
- facts = cases.map { |input_case, observation| facts_for(input_case, observation) }
24
- fallback = facts.to_h { |fact| [fact.case_id, deterministic(fact)] }
25
-
26
- return fallback unless enabled?
27
-
28
- improved = request(facts)
29
- fallback.merge(sanitize(improved, fallback))
30
- rescue StandardError
31
- fallback
32
- end
33
-
34
- def payload(facts)
35
- {
36
- "task" => "Describe each characterization test case in one short phrase.",
37
- "constraints" => [
38
- "Describe only the INPUTS and the kind of outcome.",
39
- "Never invent or state a concrete expected value.",
40
- "One phrase per case, at most #{MAX_DESCRIPTION} characters."
41
- ],
42
- "cases" => facts.map do |fact|
43
- {
44
- "id" => fact.case_id,
45
- "origin" => fact.origin.to_s,
46
- "outcome_kind" => fact.outcome.to_s,
47
- "method" => fact.method_name.to_s,
48
- "class" => fact.class_name.to_s,
49
- "parameter_names" => fact.parameters.map(&:to_s)
50
- }
51
- end
52
- }
53
- end
54
-
55
- private
56
-
57
- def facts_for(input_case, observation)
58
- Facts.new(
59
- case_id: input_case.id,
60
- origin: input_case.origin,
61
- outcome: observation["status"] == "raised" ? :raises : :returns,
62
- method_name: @target.method_name,
63
- class_name: @target.class_name,
64
- parameters: @target.input_params.map(&:name)
65
- )
66
- end
67
-
68
- def deterministic(fact)
69
- verb = fact.outcome == :raises ? "raises" : "returns the pinned value"
70
-
71
- "#{fact.method_name} #{verb} (#{fact.case_id}, #{fact.origin})"
72
- end
73
-
74
- def request(facts)
75
- response = @client.call(payload(facts))
76
-
77
- parsed = response.is_a?(String) ? JSON.parse(response) : response
78
- Array(parsed["cases"]).to_h { |entry| [entry["id"], entry["description"]] }
79
- end
80
-
81
- def sanitize(improved, fallback)
82
- improved.each_with_object({}) do |(case_id, description), out|
83
- next unless fallback.key?(case_id)
84
- next unless description.is_a?(String)
85
-
86
- text = description.strip
87
- next if text.empty? || text.length > MAX_DESCRIPTION
88
- next if suspicious?(text)
89
-
90
- out[case_id] = "#{text} (#{case_id})"
91
- end
92
- end
93
-
94
- def suspicious?(text)
95
- return true if text.match?(/=>|\{"t"|\bexpect\b|\beq\(/)
96
- return true if text.match?(/\d{3,}/)
97
- return true if text.count('"') > 2
98
-
99
- false
100
- end
101
- end
102
- end
103
- end