Class: Dommy::FetchFn

Inherits:
Object
  • Object
show all
Defined in:
lib/dommy/fetch.rb

Overview

‘fetch` polyfill. No real network — instead consults `JS.global[:fetchy_stub]` (a Hash=> entry) installed by the test. Mirrors the same fixture protocol that `test_fetchy.rb`’s JavaScript installer uses, so tests don’t need a JS engine to drive the stub.

Each entry in the stub hash supports:

"status" / "statusText" / "body" / "contentType" /
"headers" (Hash) / "delay" (ms)

plus AbortController signal propagation when ‘init` is passed.

Instance Method Summary collapse

Constructor Details

#initialize(window) ⇒ FetchFn

Returns a new instance of FetchFn.



18
19
20
# File 'lib/dommy/fetch.rb', line 18

def initialize(window)
  @window = window
end

Instance Method Details

#__js_call__(_method, args) ⇒ Object

JS calls ‘fetch(url, init)` end up here via either Window-level `js_call(“fetch”, …)` or as a callable handle. Both routes delegate to `call(args)` so behavior is identical.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/dommy/fetch.rb', line 25

def __js_call__(_method, args)
  url = args[0].to_s
  init = normalize_init(args[1] || {})

  # Each spec file installs its stub under its own global name.
  # `test_fetchy.rb` uses `__fetchy_stub__`; `test_resource*.rb`
  # use `__resource_fetch_stub__` and `__inject_fetch_stub__`.
  # Check them in order — only one should be set at a time.
  stub_map = @window.globals["__fetchy_stub__"] ||
    @window.globals["__resource_fetch_stub__"] ||
    @window.globals["__inject_fetch_stub__"] ||
    {}
  # `js_eval`'s JS installer increments these globals; mirror so
  # specs that probe `__fetch_count__` / `__last_url__` / etc.
  # observe the same state shape they'd see from a real injector.
  @window.globals["__fetch_count__"] = (@window.globals["__fetch_count__"] || 0).to_i + 1
  @window.globals["__last_url__"] = url
  @window.globals["__last_init__"] = init
  @window.globals["__last_body__"] = init["body"] if init.is_a?(Hash)

  entry = stub_map[url] if stub_map.is_a?(Hash)
  promise = PromiseValue.new(@window)

  if entry.nil?
    response = Response.new(@window, body: "not found", status: 404, status_text: "Not Found")
    promise.fulfill(response)
    return promise
  end

  body = entry["body"]
  status = (entry["status"] || 200).to_i
  status_text = entry["statusText"] || ""
  content_type = entry["contentType"] || "text/plain"
  headers = entry["headers"] || {"Content-Type" => content_type}

  delay = entry["delay"]
  if delay
    install_delayed_resolve(promise, body, status, status_text, headers, init, delay)
  else
    promise.fulfill(
      Response.new(@window, body: body, status: status, status_text: status_text, headers: headers, url: url)
    )
  end

  promise
end