aoc_generator 0.1.3 → 0.1.4

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: 4b769226917de985f62166b06a18ac48433df5e5ca362fdfc7248338d368ce39
4
- data.tar.gz: 9f1be6d33fe107041e8ebcbc90c9dc67b05d5ad27506a84ee2ebe5239cf4920b
3
+ metadata.gz: 4c2e50281fb4c3f191cbe11ca0417cb2ca969178f87a124572a5b34e07e01b17
4
+ data.tar.gz: b00f142cd08f4ca55e651974c7d923f2c62515a49a4f07c4d3443f5584f24e4d
5
5
  SHA512:
6
- metadata.gz: 0fad21368f7c4033a73670fdb2dece5a1ed468de3e0075d50426b821d65a3e15ae840bf2c8f6e20f5e8070f836ffe21bb72eb7abd100162bed5ee60101ca8821
7
- data.tar.gz: 1ec320f03139f386435f78e21f3922e840a36433795f7e34421ff4d464b53073497c7c742da1998a025b15e31c1c34e719a5f008cd049a8ad65d2351f1ad8234
6
+ metadata.gz: ce6d572095bf2acc47c429e5ece1fee0c335ed0403c94c47f33063a996193d0848deacf49a981fa18546b418d05c2425a553317f1677c5fb714d3de9163caf18
7
+ data.tar.gz: 93ccfd82a61cb9ea1eb8b096cfa1c0a922a002abb923c93f06c25796a5af6d4356be28e06a88d9b62d4e489f04328e15d37569c24a7480cec366c57560bdd0ab
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Changelog
2
2
 
3
- ## [0.1.3] - 2024-11-28
3
+ ## [0.1.4] - 2024-11-28
4
+
5
+ - Add test data to spec file
6
+
7
+ ## [0.1.3]
4
8
 
5
9
  - Allow to read a AOC_SESSION environment variable
6
10
  - Change file names
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- aoc_generator (0.1.3)
4
+ aoc_generator (0.1.4)
5
5
  fileutils (~> 1.7)
6
6
  nokogiri (~> 1.16)
7
7
  thor (~> 1.3)
@@ -38,8 +38,7 @@ module AdventOfCodeGenerator
38
38
  default: ENV.fetch("AOC_SESSION", nil)
39
39
 
40
40
  def generate
41
- scraper = AdventOfCodeGenerator::Scraper.new(options)
42
- generator = AdventOfCodeGenerator::Generator.new(options, scraper)
41
+ generator = AdventOfCodeGenerator::Generator.new(options, content)
43
42
 
44
43
  generator.call
45
44
  end
@@ -47,5 +46,14 @@ module AdventOfCodeGenerator
47
46
  def self.exit_on_failure?
48
47
  true
49
48
  end
49
+
50
+ private
51
+
52
+ def content
53
+ scraped_data = AdventOfCodeGenerator::Scraper.new(options).call
54
+ parsed_data = AdventOfCodeGenerator::HTMLParser.new(scraped_data[:puzzle_description]).call
55
+
56
+ scraped_data.merge(parsed_data)
57
+ end
50
58
  end
51
59
  end
@@ -20,11 +20,11 @@ module AdventOfCodeGenerator
20
20
  class Generator
21
21
  FileData = Struct.new(:path, :content)
22
22
 
23
- def initialize(options, scraper)
23
+ def initialize(options, scraped_data)
24
24
  @year = options[:year].to_s
25
25
  @day = options[:day].to_s.rjust(2, "0") # Ensures day is two digits (e.g., "01" instead of "1")
26
26
  @username = options[:username].gsub(/[_\-\.\s]/, "")
27
- @scraper = scraper
27
+ @scraped_data = scraped_data
28
28
  end
29
29
 
30
30
  def call
@@ -45,14 +45,14 @@ module AdventOfCodeGenerator
45
45
 
46
46
  def readme
47
47
  path = "#{daily_directory}/README.md"
48
- content = @scraper.puzzle_description
48
+ content = @scraped_data[:puzzle_description]
49
49
 
50
50
  FileData.new(path, content)
51
51
  end
52
52
 
53
53
  def data_file
54
54
  path = "#{daily_directory}/data.txt"
55
- content = @scraper.input_data
55
+ content = @scraped_data[:input_data]
56
56
 
57
57
  FileData.new(path, content)
58
58
  end
@@ -86,22 +86,28 @@ module AdventOfCodeGenerator
86
86
 
87
87
  def spec_file
88
88
  path = "#{daily_directory}/day_#{@day}_spec.rb"
89
+ input, expectations = @scraped_data.values_at(:test_input, :test_expectations)
90
+ input ||= ["", ""]
89
91
  content = <<~RUBY
90
92
  # frozen_string_literal: true
91
93
 
92
94
  require_relative "day_#{@day}"
93
95
 
94
96
  RSpec.describe #{@username.capitalize}::Year#{@year}::Day#{@day} do
95
- subject(:puzzle) { described_class.new(input) }
96
-
97
- let(:input) { File.read("\#{__dir__}/data.txt") }
98
-
99
97
  it "solves Part One" do
100
- expect(puzzle.part_one).to eq("")
98
+ input = <<~INPUT
99
+ #{input[0]&.gsub("\n", "\n ")}
100
+ INPUT
101
+
102
+ expect(described_class.part_one(input)).to eq(#{expectations[0]})
101
103
  end
102
104
 
103
- xit "solves Part Two" do
104
- expect(puzzle.part_two).to eq("some other value")
105
+ it "solves Part Two", skip: "not implemented yet" do
106
+ input = <<~INPUT
107
+ #{input[1]&.gsub("\n", "\n ")}
108
+ INPUT
109
+
110
+ expect(described_class.part_two(input)).to eq(#{expectations[1]})
105
111
  end
106
112
  end
107
113
  RUBY
@@ -5,20 +5,41 @@ require "nokogiri"
5
5
  module AdventOfCodeGenerator
6
6
  # Converts HTML puzzle descriptions from adventofcode.com into markdown format.
7
7
  class HTMLParser
8
- def initialize(input)
9
- @input = input
8
+ def initialize(html_content)
9
+ @html_content = html_content
10
10
  end
11
11
 
12
12
  def call
13
- articles.map do |node|
14
- process_article(node)
15
- end.join("\n").strip
13
+ {
14
+ puzzle_description: part_descriptions.join("\n"),
15
+ test_input:,
16
+ test_expectations:
17
+ }
16
18
  end
17
19
 
18
20
  private
19
21
 
22
+ def part_descriptions
23
+ @part_descriptions ||= articles.map do |node|
24
+ process_article(node).join("\n")
25
+ end
26
+ end
27
+
28
+ def test_input
29
+ part_descriptions.map { |desc| desc.scan(/```sh\n(.*?)\n```/m) }.flatten
30
+ end
31
+
32
+ def test_expectations
33
+ part_descriptions
34
+ .flat_map { |desc| desc.scan(/\*\*`(.*?)`\*\*/) }
35
+ .map do |matches|
36
+ match = matches.first
37
+ match&.match?(/\A\d+\z/) ? match.to_i : match
38
+ end.compact
39
+ end
40
+
20
41
  def articles
21
- doc = Nokogiri::HTML(@input)
42
+ doc = Nokogiri::HTML(@html_content)
22
43
  doc.css("article")
23
44
  end
24
45
 
@@ -6,11 +6,25 @@ require_relative "html_parser"
6
6
  module AdventOfCodeGenerator
7
7
  # Fetches puzzle descriptions and input data from adventofcode.com.
8
8
  class Scraper
9
- def initialize(options, parser = AdventOfCodeGenerator::HTMLParser)
9
+ def initialize(options)
10
10
  @year = options[:year]
11
11
  @day = options[:day]
12
12
  @session_key = options[:session]
13
- @parser = parser
13
+ end
14
+
15
+ def call
16
+ {
17
+ puzzle_description:,
18
+ input_data:
19
+ }
20
+ end
21
+
22
+ private
23
+
24
+ def headers
25
+ return {} unless @session_key
26
+
27
+ @headers ||= { cookie: "session=#{@session_key}" }
14
28
  end
15
29
 
16
30
  def puzzle_description
@@ -19,24 +33,16 @@ module AdventOfCodeGenerator
19
33
  uri = URI("https://adventofcode.com/#{@year}/day/#{@day}")
20
34
  response = Net::HTTP.get_response(uri, headers)
21
35
 
22
- @parser.new(response.body).call
36
+ response.body
23
37
  end
24
38
 
25
39
  def input_data
26
- return @input_data if @input_data
27
40
  return warn "No session key provided; unable to download data file." unless @session_key
28
41
 
29
42
  uri = URI("https://adventofcode.com/#{@year}/day/#{@day}/input")
30
43
  response = Net::HTTP.get_response(uri, headers)
31
- @input_data ||= response.body
32
- end
33
-
34
- private
35
44
 
36
- def headers
37
- return {} unless @session_key
38
-
39
- @headers ||= { cookie: "session=#{@session_key}" }
45
+ response.body
40
46
  end
41
47
  end
42
48
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AdventOfCodeGenerator
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.4"
5
5
 
6
6
  class Error < StandardError; end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aoc_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Nguyen