Class: HttpResource::Simulation::Backend

Inherits:
Object
  • Object
show all
Defined in:
lib/http_resource/simulation/backend.rb

Overview

In-memory stand-in for Client's transport. Same verb surface (signatures including params:/form:/timeouts), same deterministic-bug guards, and it answers with parsed-JSON-shaped Hashes (string keys) or nil, or raises via ApiError.for_status — so every resource proxy, value object and error path above it runs UNCHANGED against seeded in-memory state.

Client gems SUBCLASS Backend and let handlers self-register on the subclass at file load:

class MyGem::Simulation::Backend < HttpResource::Simulation::Backend; end
MyGem::Simulation::Backend.register("api/contacts", ContactsHandler)

Each subclass owns its OWN registry (one gem's handlers can never leak into another's); lookup walks the inheritance chain — the NEAREST class with any matching prefix wins (a subclass registration shadows the parent's wholesale), longest whole-segment prefix within that class. Handlers are HandlerClass.new(store), memoized per backend instance, and receive handler.call(verb, segments, payload:, params:).

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBackend

Returns a new instance of Backend.



49
50
51
52
53
# File 'lib/http_resource/simulation/backend.rb', line 49

def initialize
  @store = Store.new
  @handlers = {}
  @injections = []
end

Instance Attribute Details

#storeObject (readonly)

Returns the value of attribute store.



47
48
49
# File 'lib/http_resource/simulation/backend.rb', line 47

def store
  @store
end

Class Method Details

.register(prefix, handler_class) ⇒ Object



30
31
32
# File 'lib/http_resource/simulation/backend.rb', line 30

def register(prefix, handler_class)
  registry[prefix_segments(prefix)] = handler_class
end

.registryObject

This class's OWN registrations (=> handler_class), NOT including inherited ones — dispatch walks the ancestry explicitly.



36
37
38
# File 'lib/http_resource/simulation/backend.rb', line 36

def registry
  @registry ||= {}
end

Instance Method Details

#delete(path, open_timeout: nil, read_timeout: nil) ⇒ Object



74
75
76
# File 'lib/http_resource/simulation/backend.rb', line 74

def delete(path, open_timeout: nil, read_timeout: nil)
  dispatch(:delete, path)
end

#fail_next(status:, body: nil, on: nil) ⇒ Object

Queue a one-shot failure: the next call whose normalized path contains on: (any call when omitted) raises the mapped ApiError, then the injection is consumed. Non-matching injections are skipped over and STAY queued (FIFO among matches). body: is coerced to the String a real transport error carries (a Hash/Array is JSON-encoded).



88
89
90
91
# File 'lib/http_resource/simulation/backend.rb', line 88

def fail_next(status:, body: nil, on: nil)
  @injections << { status:, body: string_body(body), on: normalize_on(on) }
  nil
end

#get(path, params: nil, open_timeout: nil, read_timeout: nil) ⇒ Object

The timeout kwargs are accepted AND ignored on purpose: the surface must match Client's verbs exactly so calling code runs unchanged. rubocop:disable Lint/UnusedMethodArgument



58
59
60
# File 'lib/http_resource/simulation/backend.rb', line 58

def get(path, params: nil, open_timeout: nil, read_timeout: nil)
  dispatch(:get, path, params: normalize_params(params))
end

#patch(path, payload = nil, form: nil, open_timeout: nil, read_timeout: nil) ⇒ Object



70
71
72
# File 'lib/http_resource/simulation/backend.rb', line 70

def patch(path, payload = nil, form: nil, open_timeout: nil, read_timeout: nil)
  dispatch(:patch, path, payload:, form:)
end

#post(path, payload = nil, form: nil, open_timeout: nil, read_timeout: nil) ⇒ Object



62
63
64
# File 'lib/http_resource/simulation/backend.rb', line 62

def post(path, payload = nil, form: nil, open_timeout: nil, read_timeout: nil)
  dispatch(:post, path, payload:, form:)
end

#put(path, payload = nil, form: nil, open_timeout: nil, read_timeout: nil) ⇒ Object



66
67
68
# File 'lib/http_resource/simulation/backend.rb', line 66

def put(path, payload = nil, form: nil, open_timeout: nil, read_timeout: nil)
  dispatch(:put, path, payload:, form:)
end

#reset!Object



93
94
95
96
97
98
# File 'lib/http_resource/simulation/backend.rb', line 93

def reset!
  @store.reset!
  @handlers.clear
  @injections.clear
  nil
end

#seed(collections) ⇒ Object

rubocop:enable Lint/UnusedMethodArgument



79
80
81
# File 'lib/http_resource/simulation/backend.rb', line 79

def seed(collections)
  @store.seed(collections)
end