loading
Generated 2024-11-07T21:54:45+00:00

All Files ( 83.47% covered at 0.98 hits/line )

19 files in total.
121 relevant lines, 101 lines covered and 20 lines missed. ( 83.47% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
app/channels/application_cable/channel.rb 100.00 % 4 2 2 0 1.00
app/channels/application_cable/connection.rb 100.00 % 4 2 2 0 1.00
app/controllers/application_controller.rb 100.00 % 2 1 1 0 1.00
app/controllers/gods_controller.rb 66.67 % 5 3 2 1 0.67
app/controllers/mythologies_controller.rb 66.67 % 5 3 2 1 0.67
app/controllers/stories_controller.rb 81.82 % 60 33 27 6 1.12
app/controllers/story_gods_controller.rb 66.67 % 43 21 14 7 0.67
app/helpers/application_helper.rb 100.00 % 2 1 1 0 1.00
app/helpers/gods_helper.rb 100.00 % 2 1 1 0 1.00
app/helpers/story_gods_helper.rb 100.00 % 2 1 1 0 1.00
app/jobs/application_job.rb 100.00 % 7 1 1 0 1.00
app/jobs/story_create_job.rb 82.35 % 31 17 14 3 1.00
app/mailers/application_mailer.rb 100.00 % 4 3 3 0 1.00
app/models/application_record.rb 100.00 % 3 2 2 0 1.00
app/models/god.rb 100.00 % 6 4 4 0 1.00
app/models/mythology.rb 100.00 % 2 1 1 0 1.00
app/models/pantheon.rb 100.00 % 2 1 1 0 1.00
app/models/story.rb 93.33 % 32 15 14 1 1.20
app/models/story_god.rb 88.89 % 27 9 8 1 0.89

Controllers ( 75.41% covered at 0.92 hits/line )

5 files in total.
61 relevant lines, 46 lines covered and 15 lines missed. ( 75.41% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
app/controllers/application_controller.rb 100.00 % 2 1 1 0 1.00
app/controllers/gods_controller.rb 66.67 % 5 3 2 1 0.67
app/controllers/mythologies_controller.rb 66.67 % 5 3 2 1 0.67
app/controllers/stories_controller.rb 81.82 % 60 33 27 6 1.12
app/controllers/story_gods_controller.rb 66.67 % 43 21 14 7 0.67

Channels ( 100.0% covered at 1.0 hits/line )

2 files in total.
4 relevant lines, 4 lines covered and 0 lines missed. ( 100.0% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
app/channels/application_cable/channel.rb 100.00 % 4 2 2 0 1.00
app/channels/application_cable/connection.rb 100.00 % 4 2 2 0 1.00

Models ( 93.75% covered at 1.06 hits/line )

6 files in total.
32 relevant lines, 30 lines covered and 2 lines missed. ( 93.75% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
app/models/application_record.rb 100.00 % 3 2 2 0 1.00
app/models/god.rb 100.00 % 6 4 4 0 1.00
app/models/mythology.rb 100.00 % 2 1 1 0 1.00
app/models/pantheon.rb 100.00 % 2 1 1 0 1.00
app/models/story.rb 93.33 % 32 15 14 1 1.20
app/models/story_god.rb 88.89 % 27 9 8 1 0.89

Mailers ( 100.0% covered at 1.0 hits/line )

1 files in total.
3 relevant lines, 3 lines covered and 0 lines missed. ( 100.0% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
app/mailers/application_mailer.rb 100.00 % 4 3 3 0 1.00

Helpers ( 100.0% covered at 1.0 hits/line )

3 files in total.
3 relevant lines, 3 lines covered and 0 lines missed. ( 100.0% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
app/helpers/application_helper.rb 100.00 % 2 1 1 0 1.00
app/helpers/gods_helper.rb 100.00 % 2 1 1 0 1.00
app/helpers/story_gods_helper.rb 100.00 % 2 1 1 0 1.00

Jobs ( 83.33% covered at 1.0 hits/line )

2 files in total.
18 relevant lines, 15 lines covered and 3 lines missed. ( 83.33% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
app/jobs/application_job.rb 100.00 % 7 1 1 0 1.00
app/jobs/story_create_job.rb 82.35 % 31 17 14 3 1.00

Libraries ( 100.0% covered at 0.0 hits/line )

0 files in total.
0 relevant lines, 0 lines covered and 0 lines missed. ( 100.0% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line

app/channels/application_cable/channel.rb

100.0% lines covered

2 relevant lines. 2 lines covered and 0 lines missed.
    
  1. 1 module ApplicationCable
  2. 1 class Channel < ActionCable::Channel::Base
  3. end
  4. end

app/channels/application_cable/connection.rb

100.0% lines covered

2 relevant lines. 2 lines covered and 0 lines missed.
    
  1. 1 module ApplicationCable
  2. 1 class Connection < ActionCable::Connection::Base
  3. end
  4. end

app/controllers/application_controller.rb

100.0% lines covered

1 relevant lines. 1 lines covered and 0 lines missed.
    
  1. 1 class ApplicationController < ActionController::Base
  2. end

app/controllers/gods_controller.rb

66.67% lines covered

3 relevant lines. 2 lines covered and 1 lines missed.
    
  1. 1 class GodsController < ApplicationController
  2. 1 def index
  3. @gods = God.all
  4. end
  5. end

app/controllers/mythologies_controller.rb

66.67% lines covered

3 relevant lines. 2 lines covered and 1 lines missed.
    
  1. 1 class MythologiesController < ApplicationController
  2. 1 def index
  3. @mythologies = Mythology.all
  4. end
  5. end

app/controllers/stories_controller.rb

81.82% lines covered

33 relevant lines. 27 lines covered and 6 lines missed.
    
  1. 1 class StoriesController < ApplicationController
  2. 1 before_action :set_story, only: [:show, :edit, :update, :destroy]
  3. 1 def index
  4. 3 @stories = Story.all
  5. end
  6. 1 def show
  7. rescue ActiveRecord::RecordNotFound
  8. redirect_to stories_path
  9. end
  10. 1 def new
  11. 2 @mythologies = Mythology.all
  12. 2 @gods = God.where(mythology_id: @mythologies.first.id)
  13. 2 @storygod = StoryGod.new
  14. 2 @story = Story.new(storygods: [@storygod])
  15. end
  16. 1 def edit
  17. end
  18. 1 def create
  19. 2 @story = Story.new(story_params)
  20. 2 @story.content = "Generating. Story should appear here. Wait a bit..."
  21. 2 if @story.save
  22. 1 StoryCreateJob.perform_later(@story.id)
  23. 1 redirect_to @story
  24. else
  25. 1 @mythologies = Mythology.all
  26. 1 @gods = God.where(mythology_id: @mythologies.first.id)
  27. 1 render :new, status: :unprocessable_entity
  28. end
  29. end
  30. 1 def update
  31. if @story.update(story_params)
  32. redirect_to stories_path, notice: "Story was successfully updated."
  33. else
  34. render :show
  35. end
  36. end
  37. 1 def destroy
  38. @story.destroy
  39. redirect_to stories_path, notice: "Story was successfully destroyed."
  40. end
  41. 1 private
  42. 1 def set_story
  43. 1 @story = Story.find(params[:id])
  44. end
  45. 1 def story_params
  46. 2 params.require(:story).permit(:title, :mythology_id, :content, :creativity, :llm_name, :instructions,
  47. storygods_attributes: [:id, :_destroy, :god_id, :role])
  48. end
  49. end

app/controllers/story_gods_controller.rb

66.67% lines covered

21 relevant lines. 14 lines covered and 7 lines missed.
    
  1. 1 class StoryGodsController < ApplicationController
  2. 1 before_action :get_story
  3. 1 before_action :set_storygod, only: [:show, :edit, :update, :destroy]
  4. 1 def index
  5. @storygods = @story.storygods
  6. end
  7. 1 def show
  8. end
  9. 1 def new
  10. @storygod = @story.storygods.build
  11. end
  12. 1 def edit
  13. end
  14. 1 def create
  15. @storygod = @story.storygods.build(storygod_params)
  16. end
  17. 1 def update
  18. end
  19. 1 def destroy
  20. @storygod.destroy
  21. end
  22. 1 private
  23. 1 def get_story
  24. @story = Story.find(params[:story_id])
  25. end
  26. 1 def set_storygod
  27. @storygod = @story.storygods.find(params[:id])
  28. end
  29. 1 def storygod_params
  30. params.require(:storygod).permit(:story_id)
  31. end
  32. end

app/helpers/application_helper.rb

100.0% lines covered

1 relevant lines. 1 lines covered and 0 lines missed.
    
  1. 1 module ApplicationHelper
  2. end

app/helpers/gods_helper.rb

100.0% lines covered

1 relevant lines. 1 lines covered and 0 lines missed.
    
  1. 1 module GodsHelper
  2. end

app/helpers/story_gods_helper.rb

100.0% lines covered

1 relevant lines. 1 lines covered and 0 lines missed.
    
  1. 1 module StoryGodsHelper
  2. end

app/jobs/application_job.rb

100.0% lines covered

1 relevant lines. 1 lines covered and 0 lines missed.
    
  1. 1 class ApplicationJob < ActiveJob::Base
  2. # Automatically retry jobs that encountered a deadlock
  3. # retry_on ActiveRecord::Deadlocked
  4. # Most jobs are safe to ignore if the underlying records are no longer available
  5. # discard_on ActiveJob::DeserializationError
  6. end

app/jobs/story_create_job.rb

82.35% lines covered

17 relevant lines. 14 lines covered and 3 lines missed.
    
  1. 1 class StoryCreateJob < ApplicationJob
  2. 1 queue_as :default
  3. 1 def perform(*args)
  4. 2 story = Story.find(args[0])
  5. 2 case story.llm_name
  6. when "openai"
  7. 2 llm = Langchain::LLM::OpenAI.new(api_key: ENV["OPENAI_API_KEY"], llm_options: {temperature: story.creativity_temp})
  8. when "google"
  9. llm = Langchain::LLM::GooglePalm.new(api_key: ENV["GOOGLE_PALM_API_KEY"], default_options: {temperature: story.creativity_temp})
  10. else
  11. logger.error "Unknown LLM: #{story.llm_name}"
  12. end
  13. 1 story_template = Langchain::Prompt.load_from_path(file_path: "app/prompts/story_create_template.yaml")
  14. 1 prompt_text = story_template.format(mythology_name: story.mythology.name, title: story.title)
  15. 1 role_template = Langchain::Prompt.load_from_path(file_path: "app/prompts/story_role_template.yaml")
  16. 1 StoryGod.where(story_id: args[0]).find_each do |g|
  17. prompt_text += " " + role_template.format(god: g.god.name, role: g.role)
  18. end
  19. 1 instructions = story.instructions
  20. 1 if instructions
  21. 1 prompt = prompt_text + " Additional instructions for generating the story are " + instructions
  22. end
  23. 1 story.update(content: llm.complete(prompt: prompt).completion)
  24. end
  25. end

app/mailers/application_mailer.rb

100.0% lines covered

3 relevant lines. 3 lines covered and 0 lines missed.
    
  1. 1 class ApplicationMailer < ActionMailer::Base
  2. 1 default from: "from@example.com"
  3. 1 layout "mailer"
  4. end

app/models/application_record.rb

100.0% lines covered

2 relevant lines. 2 lines covered and 0 lines missed.
    
  1. 1 class ApplicationRecord < ActiveRecord::Base
  2. 1 primary_abstract_class
  3. end

app/models/god.rb

100.0% lines covered

4 relevant lines. 4 lines covered and 0 lines missed.
    
  1. 1 class God < ApplicationRecord
  2. 1 belongs_to :mythology # , dependent: :restrict_with_error <- gives error on db:setup
  3. 1 belongs_to :pantheon
  4. 1 has_many :storygods, dependent: :destroy
  5. end

app/models/mythology.rb

100.0% lines covered

1 relevant lines. 1 lines covered and 0 lines missed.
    
  1. 1 class Mythology < ApplicationRecord
  2. end

app/models/pantheon.rb

100.0% lines covered

1 relevant lines. 1 lines covered and 0 lines missed.
    
  1. 1 class Pantheon < ApplicationRecord
  2. end

app/models/story.rb

93.33% lines covered

15 relevant lines. 14 lines covered and 1 lines missed.
    
  1. 1 class Story < ApplicationRecord
  2. 1 belongs_to :mythology
  3. 1 validates :title, presence: true
  4. # validates :body, presence: true
  5. 1 has_rich_text :content
  6. 1 has_many :storygods, dependent: :destroy, class_name: "StoryGod"
  7. 1 accepts_nested_attributes_for :storygods, reject_if: :all_blank, allow_destroy: true
  8. 1 has_many :gods, through: :storygod
  9. 1 CREATIVITY_TEMPS = {
  10. "Conservative" => 0.2,
  11. "Balanced" => 0.5,
  12. "Inventive" => 0.8
  13. }.freeze
  14. 1 validates :creativity, presence: true, inclusion: {in: CREATIVITY_TEMPS.keys}
  15. 1 validates :llm_name, presence: true, inclusion: {in: LLMS}
  16. 1 def creativity_temp
  17. 3 CREATIVITY_TEMPS[creativity]
  18. end
  19. 1 after_update -> {
  20. begin
  21. 3 broadcast_replace_to "stories"
  22. rescue => e
  23. logger.error "Error occurred during broadcast_replace_to: #{e.message}"
  24. end
  25. }
  26. end

app/models/story_god.rb

88.89% lines covered

9 relevant lines. 8 lines covered and 1 lines missed.
    
  1. 1 class StoryGod < ApplicationRecord
  2. 1 belongs_to :story
  3. 1 belongs_to :god
  4. # validates :story, presence: true
  5. # validates :god, presence: true
  6. 1 validates :story, uniqueness: {scope: :god}
  7. 1 validates :god, uniqueness: {scope: :story}
  8. 1 def get_name
  9. god[:name]
  10. end
  11. ROLES = [
  12. 1 "Protagonist",
  13. "Antagonist",
  14. "Deuteragonist",
  15. "Love Interest",
  16. "Confidant",
  17. "Foil",
  18. "Mentor",
  19. "Sidekick",
  20. "Tertiary Character"
  21. ]
  22. 1 validates :role, inclusion: {in: ROLES}
  23. # enum role: {"Protagonist" => 0, "Antagonist" => 1, "Deuteragonist" => 2, "Love Interest" => 3, "Confidant" => 4, "Foil" => 5, "Mentor" => 6, "Sidekick" => 7, "Tertiary Character" => 8}
  24. end