aoc_generator 0.1.3 → 0.1.5

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: 1ae6b1d2734c4a21d5608955e4bc5c36d6a2226644834eebbade401de59ebe87
4
+ data.tar.gz: fc64a51413098fc34a5b33a5ab7d6df042bef03800a134b9ab06c3c950e289d4
5
5
  SHA512:
6
- metadata.gz: 0fad21368f7c4033a73670fdb2dece5a1ed468de3e0075d50426b821d65a3e15ae840bf2c8f6e20f5e8070f836ffe21bb72eb7abd100162bed5ee60101ca8821
7
- data.tar.gz: 1ec320f03139f386435f78e21f3922e840a36433795f7e34421ff4d464b53073497c7c742da1998a025b15e31c1c34e719a5f008cd049a8ad65d2351f1ad8234
6
+ metadata.gz: a6165ed4974b4f84a8500530ca257e757bf61ccb932233e8d34e7237ab36f5e0208bc89b592e09844252e86b4253659197d5322799ff184224ab292c97d93c0a
7
+ data.tar.gz: 44620d63c9fcf49970148ae4ae4335bc1e9d97a942c33310df4a0dc860c353322ad229981dbbb9f6bcba2e0e7de7a2ac904d32ca283ba9ef45e45ae3c968a7b6
data/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Changelog
2
2
 
3
- ## [0.1.3] - 2024-11-28
3
+ ## [0.1.5] - 2024-11-28
4
+
5
+ - Generate main file with class methods, rather than instance methods
6
+
7
+ ## [0.1.4]
8
+
9
+ - Add test data to spec file
10
+
11
+ ## [0.1.3]
4
12
 
5
13
  - Allow to read a AOC_SESSION environment variable
6
14
  - 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.5)
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
@@ -65,15 +65,11 @@ module AdventOfCodeGenerator
65
65
  module #{@username.capitalize}
66
66
  module Year#{@year}
67
67
  class Day#{@day}
68
- def initialize(input)
69
- @input = input
70
- end
71
-
72
- def part_one
68
+ def self.part_one(input)
73
69
  raise NotImplementedError
74
70
  end
75
71
 
76
- def part_two
72
+ def self.part_two(input)
77
73
  raise NotImplementedError
78
74
  end
79
75
  end
@@ -86,22 +82,28 @@ module AdventOfCodeGenerator
86
82
 
87
83
  def spec_file
88
84
  path = "#{daily_directory}/day_#{@day}_spec.rb"
85
+ input, expectations = @scraped_data.values_at(:test_input, :test_expectations)
86
+ input ||= ["", ""]
89
87
  content = <<~RUBY
90
88
  # frozen_string_literal: true
91
89
 
92
90
  require_relative "day_#{@day}"
93
91
 
94
92
  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
93
  it "solves Part One" do
100
- expect(puzzle.part_one).to eq("")
94
+ input = <<~INPUT
95
+ #{input[0]&.gsub("\n", "\n ")}
96
+ INPUT
97
+
98
+ expect(described_class.part_one(input)).to eq(#{expectations[0]})
101
99
  end
102
100
 
103
- xit "solves Part Two" do
104
- expect(puzzle.part_two).to eq("some other value")
101
+ it "solves Part Two", skip: "not implemented yet" do
102
+ input = <<~INPUT
103
+ #{input[1]&.gsub("\n", "\n ")}
104
+ INPUT
105
+
106
+ expect(described_class.part_two(input)).to eq(#{expectations[1]})
105
107
  end
106
108
  end
107
109
  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.5"
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.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Nguyen