lluminary 0.1.4 → 0.2.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.
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+ require_relative "../../examples/character_profiler"
4
+
5
+ RSpec.describe CharacterProfiler do
6
+ let(:sample_text) { <<~TEXT }
7
+ Eliza Montenegro was not the kind of person who made a grand entrance, despite her striking appearance.
8
+ At 5'9" with curly auburn hair that framed an angular face, she preferred tailored blazers and vintage boots that had seen better days.
9
+
10
+ Her colleagues at the research lab respected her brilliant mind but found her difficult to read. She spoke rarely in meetings,
11
+ but when she did, everyone listened. The only time she seemed to lower her guard was around Dr. Chen, her mentor of fifteen years,
12
+ or when discussing her passion project: developing affordable water filtration systems for remote villages like the one her grandmother grew up in.
13
+ TEXT
14
+
15
+ describe "input validation" do
16
+ it "accepts valid text input" do
17
+ expect { described_class.call!(text: sample_text) }.not_to raise_error
18
+ end
19
+
20
+ it "requires text to be present" do
21
+ expect do described_class.call!(text: "") end.to raise_error(
22
+ Lluminary::ValidationError
23
+ )
24
+ end
25
+ end
26
+
27
+ describe "output validation" do
28
+ let(:result) { described_class.call(text: sample_text) }
29
+
30
+ it "returns a character profile hash" do
31
+ character_profile = result.output.character_profile
32
+
33
+ expect(character_profile).to be_a(Hash)
34
+ end
35
+
36
+ it "includes basic profile fields" do
37
+ profile = result.output.character_profile
38
+
39
+ expect(profile["name"]).to be_a(String)
40
+ expect(profile["personality"]).to be_a(String)
41
+ expect(profile["complexity_score"]).to be_a(Float)
42
+ end
43
+
44
+ it "includes an appearance hash with required fields" do
45
+ appearance = result.output.character_profile["appearance"]
46
+
47
+ expect(appearance).to be_a(Hash)
48
+ expect(appearance["physical_traits"]).to be_a(String)
49
+ expect(appearance["style"]).to be_a(String)
50
+ end
51
+
52
+ it "includes an array of motivations" do
53
+ motivations = result.output.character_profile["motivations"]
54
+
55
+ expect(motivations).to be_an(Array)
56
+ expect(motivations).to all(be_a(String)) unless motivations.empty?
57
+ end
58
+
59
+ it "includes a relationships hash with allies and adversaries" do
60
+ relationships = result.output.character_profile["relationships"]
61
+
62
+ expect(relationships).to be_a(Hash)
63
+
64
+ expect(relationships["allies"]).to be_an(Array)
65
+ expect(relationships["allies"]).to all(be_a(String))
66
+
67
+ expect(relationships["adversaries"]).to be_an(Array)
68
+ expect(relationships["adversaries"]).to be_empty
69
+ end
70
+
71
+ it "has a complexity score between 0 and 1" do
72
+ score = result.output.character_profile["complexity_score"]
73
+ expect(score).to be >= 0.0
74
+ expect(score).to be <= 1.0
75
+ end
76
+ end
77
+
78
+ describe "prompt generation" do
79
+ let(:result) { described_class.call(text: sample_text) }
80
+
81
+ it "includes the text in the prompt" do
82
+ expect(result.prompt).to include(sample_text)
83
+ end
84
+ end
85
+ end