aoc_generator 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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