jumbotron 0.1.1 → 0.1.3

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: 0461cd6ea53300eaf51f0283060767da1ee18a74356d20906bb35f34a369061e
4
- data.tar.gz: 89cf5eec83c074a338b5765225933ae5a3be7480853966239d437ac383f09d0b
3
+ metadata.gz: 70b7fd9c8a5076c1337d2a6cf9e02016fd6cfa28ec64c9cc0a57c82ff3892698
4
+ data.tar.gz: 5051beb14f8770e109f382abd0729952446ecd40a50fbd143ac4e5b5746800b0
5
5
  SHA512:
6
- metadata.gz: de18ce2882fa4b4a450a6541cb7305456b2e820de3cc71d95dede9fbaec654bef2234c1896aaf16e79cd7fcbc7b11163e2d67634dcf83c8d0a8e9921f2ccbdf9
7
- data.tar.gz: b54ecfe4c49d62510fc1ec0ea238858487585171b57d5313f3e297415f834511c74c89a50f05049199addd6c9374fbb8633614d4d95cacc4de7b380248cc5454
6
+ metadata.gz: c684624b00cded82fb1e274b793a5e0c7cca6d0720589192def2ea53357ce933d631e59373728bfb3052343706df6684ddfd082482100aef79160a65fb8b9dbf
7
+ data.tar.gz: 72f5a0934b87a9008e6fc782b377ac166f762119504f646bcf4d964892475c2df66871a3222bdf81c20a8eaba264f3e5c519bbbfc5bf4acd1396ac95a94d308c
data/README.md CHANGED
@@ -2,4 +2,13 @@
2
2
 
3
3
  Jumbotron is a backend sports-truth Rails Engine.
4
4
 
5
- More information is coming later.
5
+ ## Testing
6
+
7
+ Shared factories for hosts:
8
+
9
+ ```ruby
10
+ require "jumbotron/testing"
11
+ Jumbotron::Testing.install!
12
+ ```
13
+
14
+ Details: [Testing with Jumbotron](docs/testing.md).
@@ -51,7 +51,7 @@ module Jumbotron
51
51
 
52
52
  policy :live,
53
53
  type: :live_game_update,
54
- cadence: Cadence.new(every: 2, unit: :minute),
54
+ cadence: Cadence.new(every: 1, unit: :minute),
55
55
  eligible: lambda { |game, now:|
56
56
  return false if TERMINAL_LIFECYCLES.include?(game.lifecycle)
57
57
  return false if INTERRUPTED_LIFECYCLES.include?(game.lifecycle)
data/docs/testing.md ADDED
@@ -0,0 +1,62 @@
1
+ # Testing with Jumbotron
2
+
3
+ Jumbotron ships FactoryBot definitions for engine-owned models. Hosts load
4
+ them explicitly in the test suite — there is no production Railtie and
5
+ FactoryBot is not a runtime gem dependency.
6
+
7
+ Back to [README](../README.md).
8
+
9
+ ## Setup
10
+
11
+ ```ruby
12
+ # spec/rails_helper.rb (after Rails is loaded)
13
+ require "jumbotron/testing"
14
+
15
+ Jumbotron::Testing.install! # preferred
16
+ # Jumbotron::Testing.load_factories! # factories-only / advanced
17
+ ```
18
+
19
+ Call `install!` **before** any host `FactoryBot.modify` blocks so shared
20
+ factories exist when you extend them.
21
+
22
+ ## Extending factories
23
+
24
+ Hosts must not redefine Jumbotron base factories. Use `FactoryBot.modify`:
25
+
26
+ ```ruby
27
+ FactoryBot.modify do
28
+ factory :jumbotron_game do
29
+ trait :completed do
30
+ lifecycle { "completed" }
31
+ end
32
+ end
33
+ end
34
+ ```
35
+
36
+ ## Packaging and evolution
37
+
38
+ Factory files live under `spec/factories/**` inside the gem and are included in
39
+ the gemspec. Adding or changing a shared factory is a normal Jumbotron gem
40
+ bump — hosts pick it up on upgrade.
41
+
42
+ `Jumbotron::Testing.load_factories!` is idempotent (safe to call more than
43
+ once). It loads each factory file under `Jumbotron::Engine.root/spec/factories`
44
+ explicitly; it does not append to global `FactoryBot.definition_file_paths`.
45
+
46
+ ## Responsibilities
47
+
48
+ | Owner | Responsibility |
49
+ |-------|----------------|
50
+ | Jumbotron | Base factories for Jumbotron-owned models; Testing API; packaging |
51
+ | Host | `install!` in the test boot path; product traits via `FactoryBot.modify` |
52
+
53
+ ## Factory invariant
54
+
55
+ Base factories construct **persistent model state only**. They must not invoke
56
+ Services, Workflows, ApplicationWorkflows, or external adapters.
57
+
58
+ ## Contributors vs hosts
59
+
60
+ This guide is the **host Testing API**. Contributors working inside the Jumbotron
61
+ repository also follow workspace test standards and architecture guards under
62
+ `spec/architecture/`.
@@ -0,0 +1,29 @@
1
+ # Upgrade: Jumbotron 0.1.2
2
+
3
+ **From:** `0.1.1`
4
+ **To:** `0.1.2`
5
+
6
+ Additive host Testing API. No runtime or public consumer contract break.
7
+
8
+ ## Host-facing change
9
+
10
+ | Change | Host impact |
11
+ |--------|-------------|
12
+ | `Jumbotron::Testing.install!` | Preferred host entry to load shared FactoryBot definitions |
13
+ | Factories packaged in the gem | `spec/factories/**` is included in the gemspec (was missing in 0.1.1) |
14
+
15
+ ## Setup
16
+
17
+ ```ruby
18
+ # spec/rails_helper.rb (after Rails is loaded)
19
+ require "jumbotron/testing"
20
+ Jumbotron::Testing.install!
21
+ ```
22
+
23
+ Details: [Testing with Jumbotron](../testing.md).
24
+
25
+ ## Upgrade checklist
26
+
27
+ 1. Bump gem to `0.1.2` (or `>= 0.1.2`).
28
+ 2. Replace any host glob of `Jumbotron::Engine.root.join("spec/factories/**/*.rb")` with `Jumbotron::Testing.install!`.
29
+ 3. Ensure `factory_bot` or `factory_bot_rails` remains in the host test group.
@@ -0,0 +1,19 @@
1
+ # Upgrade: Jumbotron 0.1.3
2
+
3
+ **From:** `0.1.2`
4
+ **To:** `0.1.3`
5
+
6
+ No public consumer contract break. Hosts must already run CommandTower `>= 0.12`.
7
+
8
+ ## Host-facing change
9
+
10
+ | Change | Host impact |
11
+ |--------|-------------|
12
+ | `command_tower` gemspec floor | `>= 0.12` (was `>= 0.11`). Lockfile consumes RubyGems `0.12.0`. |
13
+ | ESPN NFL `live` game cadence | Scoreboard refresh every **1 minute** (was 2). Still one week-scoped scoreboard call per tick, not one call per live game. |
14
+
15
+ ## Upgrade checklist
16
+
17
+ 1. Bump gem to `0.1.3` (or `>= 0.1.3`).
18
+ 2. Ensure the host Gemfile satisfies `command_tower >= 0.12`.
19
+ 3. Rematerialize Jumbotron recurring schedules so the live job uses `every minute`.
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jumbotron
4
+ # Explicit host/test entry for shared FactoryBot definitions and related
5
+ # testing bootstrap. Not loaded in production via Railtie.
6
+ module Testing
7
+ class << self
8
+ # Preferred host entry. Currently loads factories; reserved for future
9
+ # shared testing setup (helpers, config checks).
10
+ def install!
11
+ load_factories!
12
+ end
13
+
14
+ # Load Jumbotron FactoryBot definitions exactly once.
15
+ # Loads files under Engine.root/spec/factories explicitly (does not mutate
16
+ # global definition_file_paths / find_definitions).
17
+ def load_factories!
18
+ return if factories_loaded?
19
+
20
+ require_factory_bot!
21
+ factory_files.each { |path| Kernel.load(path) }
22
+ @factories_loaded = true
23
+ true
24
+ end
25
+
26
+ def factories_loaded?
27
+ @factories_loaded == true
28
+ end
29
+
30
+ # Reset loader state (specs only). Does not undefine FactoryBot factories.
31
+ def reset_factories_loaded_flag!
32
+ @factories_loaded = false
33
+ end
34
+
35
+ def factories_path
36
+ Jumbotron::Engine.root.join("spec/factories")
37
+ end
38
+
39
+ private
40
+
41
+ def require_factory_bot!
42
+ require "factory_bot"
43
+ rescue LoadError
44
+ raise LoadError,
45
+ "Jumbotron::Testing requires the factory_bot gem. " \
46
+ "Add `factory_bot` or `factory_bot_rails` to your host test group."
47
+ end
48
+
49
+ def factory_files
50
+ Dir[factories_path.join("**/*.rb").to_s]
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jumbotron
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_bookmaker, class: "Jumbotron::Bookmaker" do
5
+ sequence(:name) { |n| "Bookmaker #{n}" }
6
+ observed_at { Time.current }
7
+ changed_at { Time.current }
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_game, class: "Jumbotron::Game" do
5
+ league { association :jumbotron_league }
6
+ season { association :jumbotron_season, league: league }
7
+ observed_at { Time.current }
8
+ changed_at { Time.current }
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_game_participant, class: "Jumbotron::GameParticipant" do
5
+ association :game, factory: :jumbotron_game
6
+ association :team, factory: :jumbotron_team
7
+ observed_at { Time.current }
8
+ changed_at { Time.current }
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_league, class: "Jumbotron::League" do
5
+ association :sport, factory: :jumbotron_sport
6
+ sequence(:name) { |n| "League #{n}" }
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_line_observation, class: "Jumbotron::LineObservation" do
5
+ association :game, factory: :jumbotron_game
6
+ association :bookmaker, factory: :jumbotron_bookmaker
7
+ association :observation_batch, factory: :jumbotron_observation_batch
8
+ market { "spread" }
9
+ outcome { "home" }
10
+ source { "observed" }
11
+ line_value { BigDecimal("-3.5") }
12
+ price_american { -110 }
13
+ observed_at { Time.current }
14
+ changed_at { Time.current }
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_observation_batch, class: "Jumbotron::ObservationBatch" do
5
+ provider { "espn" }
6
+ adapter_scope { "espn_nfl" }
7
+ observed_at { Time.current }
8
+ metadata { {} }
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_provider_identity, class: "Jumbotron::ProviderIdentity" do
5
+ association :target, factory: :jumbotron_sport
6
+ provider { "espn" }
7
+ object_namespace { "sport" }
8
+ sequence(:provider_id) { |n| "ext-#{n}" }
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_schedule_group, class: "Jumbotron::ScheduleGroup" do
5
+ association :season, factory: :jumbotron_season
6
+ season_phase { association :jumbotron_season_phase, season: season }
7
+ kind { "week" }
8
+ sequence(:number) { |n| n }
9
+ name { "Week #{number}" }
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_season, class: "Jumbotron::Season" do
5
+ association :league, factory: :jumbotron_league
6
+ sequence(:name) { |n| "Season #{n}" }
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_season_phase, class: "Jumbotron::SeasonPhase" do
5
+ association :season, factory: :jumbotron_season
6
+ sequence(:name) { |n| "Phase #{n}" }
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_sport, class: "Jumbotron::Sport" do
5
+ sequence(:name) { |n| "Sport #{n}" }
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_team, class: "Jumbotron::Team" do
5
+ sequence(:name) { |n| "Team #{n}" }
6
+ observed_at { Time.current }
7
+ changed_at { Time.current }
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :jumbotron_venue, class: "Jumbotron::Venue" do
5
+ sequence(:name) { |n| "Venue #{n}" }
6
+ observed_at { Time.current }
7
+ changed_at { Time.current }
8
+ end
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jumbotron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - matt-taylor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-21 00:00:00.000000000 Z
11
+ date: 2026-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: command_tower
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0.11'
19
+ version: '0.12'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0.11'
26
+ version: '0.12'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -205,11 +205,28 @@ files:
205
205
  - db/migrate/20260813000001_create_jumbotron_schedule_groups.rb
206
206
  - db/migrate/20260814000001_create_jumbotron_line_observations.rb
207
207
  - db/migrate/20260820000001_add_progress_to_jumbotron_games.rb
208
+ - docs/testing.md
209
+ - docs/upgrades/0.1.2.md
210
+ - docs/upgrades/0.1.3.md
208
211
  - lib/jumbotron.rb
209
212
  - lib/jumbotron/client.rb
210
213
  - lib/jumbotron/engine.rb
214
+ - lib/jumbotron/testing.rb
211
215
  - lib/jumbotron/version.rb
212
216
  - lib/tasks/jumbotron_schedules.rake
217
+ - spec/factories/jumbotron/bookmaker.rb
218
+ - spec/factories/jumbotron/game.rb
219
+ - spec/factories/jumbotron/game_participant.rb
220
+ - spec/factories/jumbotron/league.rb
221
+ - spec/factories/jumbotron/line_observation.rb
222
+ - spec/factories/jumbotron/observation_batch.rb
223
+ - spec/factories/jumbotron/provider_identity.rb
224
+ - spec/factories/jumbotron/schedule_group.rb
225
+ - spec/factories/jumbotron/season.rb
226
+ - spec/factories/jumbotron/season_phase.rb
227
+ - spec/factories/jumbotron/sport.rb
228
+ - spec/factories/jumbotron/team.rb
229
+ - spec/factories/jumbotron/venue.rb
213
230
  homepage: https://github.com/matt-taylor/jumbotron
214
231
  licenses:
215
232
  - MIT