pokepaste 0.0 → 0.1

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: 6d17c57c81b0801cd9628e74eb0a1632fbf0be50fa2a2cec58b3b0bdd10492e4
4
- data.tar.gz: d6b16c078757ff881a8e87341330f10e8c7ac94c36aac2da960ae53db32882fb
3
+ metadata.gz: 00dd0a7de40dd35ecfea44b68923d6670038e9975fea57031d344686eab5be8e
4
+ data.tar.gz: 1dd51398eaa67e92e7c4be23007c3ef551a4ad59be205978404f47f243d6fea3
5
5
  SHA512:
6
- metadata.gz: 142c409f1da71ff043710f94f48a03953fdf26682079a7abc54e3f9a6395e1d43b2164156b6c556f8627904e837ebea114304407af8f78d279b68aecf033fd51
7
- data.tar.gz: b5bd9cb65f42d138aec7b22d8bb496ce8b4980cdda65ae5cff2963357109680a7e156da3040588545aba1e43df723129dc3f48385dbae1ebd08a266b12fe558f
6
+ metadata.gz: 8d373e26fb2be699c0b083ffa5acfda5543514c5373077b762d35cdc2611cfb7effcea61066cb8719e00fba1dfee4bfe5387ccc77726dd186975ab98bc078ca7
7
+ data.tar.gz: 4cdae218a9a99a2294085c1a5aafcdab28615c66e87a810952562e12f8946e32bb1b636653a146519bdba63dd1d90292141b41a77c99026c5523ee4e9312796d
data/README.md CHANGED
@@ -5,7 +5,7 @@ by Pokémon Showdown and various teambuilders.
5
5
 
6
6
  ## Installation
7
7
 
8
- Install with RubyGems:
8
+ Install with [RubyGems](https://rubygems.org/gems/pokepaste):
9
9
 
10
10
  ```bash
11
11
  gem install pokepaste
@@ -40,17 +40,17 @@ team = PokePaste::fetch("https://pokepast.es/5c46f9ec443664cb")
40
40
  team = PokePaste::fetch("5c46f9ec443664cb") # full URL optional
41
41
  ```
42
42
 
43
- Once you have it parsed, you have an instance of `PokePaste::Team`, an
44
- Enumerable containing an instance of `PokePaste::Pokemon` for each Pokémon on
43
+ These methods return an instance of `PokePaste::Team`, an Enumerable
44
+ containing an instance of `PokePaste::Pokemon` for each Pokémon on
45
45
  the team. You can loop over the team as with any Enumerable, and access the
46
46
  data like so:
47
47
 
48
48
  ```ruby
49
49
  team.each do |pkmn|
50
50
  pkmn.species # required
51
- pkmn.nickname # default null
52
- pkmn.gender # default null
53
- pkmn.item # default null
51
+ pkmn.nickname # default nil
52
+ pkmn.gender # default nil
53
+ pkmn.item # default nil
54
54
 
55
55
  # EVs and IVs are hashes with the stat as the key
56
56
  # (:hp, :atk, :def, :spa, :spd, or :spe)
@@ -58,7 +58,8 @@ team.each do |pkmn|
58
58
  pkmn.ivs[:spa] # default 31
59
59
 
60
60
  pkmn.shiny? # default is false
61
- pkmn.ability # default is null
61
+ pkmn.ability # default is nil
62
+ pkmn.tera_type # default is nil
62
63
  pkmn.level # default is 50
63
64
  pkmn.happiness # default is 255
64
65
  pkmn.nature # default is :hardy (neutral nature)
@@ -87,6 +88,7 @@ team << PokePaste::Pokemon.new(
87
88
  species: "Bulbasaur",
88
89
  nickname: "Bud",
89
90
  ivs: {atk: 0},
91
+ shiny: true,
90
92
  moves: %w[Tackle Growl]
91
93
  )
92
94
 
@@ -100,9 +102,18 @@ a paste on [pokepast.es](https://pokepast.es/), you could:
100
102
  raw_paste = PokePaste.fetch(url_or_id).to_s
101
103
  ```
102
104
 
105
+ This library is purely a parser for the PokéPaste format, it does not contain
106
+ any data about the Pokémon, whether or not the moves are valid, their
107
+ abilities, anything like that. You could enter nonsense into any of the given
108
+ fields and they will be parsed to and from the PokéPaste format happily.
109
+ Validating anything beyond the syntax of the PokéPaste is left up to the user.
110
+
103
111
  ## License
104
112
 
105
113
  This library is released under the MIT license. See the
106
- [`LICENSE.md`](https://github.com/vinnydiehl/pokepaste-ruby/blob/master/LICENSE.md)
114
+ [`LICENSE.md`](https://github.com/vinnydiehl/pokepaste-ruby/blob/develop/LICENSE.md)
107
115
  file included with this code or
108
116
  [the official page on OSI](http://opensource.org/licenses/MIT) for more information.
117
+
118
+ I am not affiliated with Nintendo, Game Freak, The Pokémon Company, or any of
119
+ their subsidiaries. This is a free fan-made project. Pokémon is © and ™ Nintendo.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0
1
+ 0.1
@@ -1,9 +1,136 @@
1
1
  module PokePaste
2
2
  class Pokemon
3
- def initialize
3
+ attr_accessor *%i[species nickname gender item evs ivs shiny
4
+ ability tera_type level happiness nature moves]
5
+
6
+ @gender_abbrs = {m: :male, f: :female}
7
+ class << self
8
+ attr_accessor :gender_abbrs
9
+ end
10
+
11
+ def initialize(**attrs)
12
+ unless attrs[:species]
13
+ raise ArgumentError, "species required to initialize a PokePaste::Pokemon"
14
+ end
15
+
16
+ # Check types for things expected to be other than strings... everything else will
17
+ # at worst get coverted with #to_s and so will be allowed. It is not the job of
18
+ # this library to enforce legality, only to parse the PokéPaste format
19
+ [[:evs, Hash],
20
+ [:ivs, Hash],
21
+ [:level, Integer],
22
+ [:happiness, Integer],
23
+ [:moves, Array]].each do |attr, type|
24
+ unless attrs[attr].nil? || attrs[attr].is_a?(type)
25
+ raise TypeError, "expected type #{type} for :#{attr}, received #{attrs[attr].class}"
26
+ end
27
+ end
28
+
29
+ unless attrs[:shiny].nil? || [true, false].include?(attrs[:shiny])
30
+ raise TypeError, "expected (true|false|nil) for :shiny, received #{attrs[:shiny]}"
31
+ end
32
+
33
+ # Process and set defaults for EVs and IVs
34
+ %i[evs ivs].each do |attr|
35
+ # Pluck the relevant value out of the attrs Hash if there is one
36
+ input_attr = attrs.delete(attr) || {}
37
+
38
+ # Error if this isn't a Hash
39
+ unless input_attr.is_a?(Hash)
40
+ raise ArgumentError, "expected a Hash for :#{attr}, received #{input_attr.class}"
41
+ end
42
+
43
+ stats = %i[hp atk def spa spd spe]
44
+
45
+ # Error if an invalid stat is specified
46
+ input_attr.each do |key, value|
47
+ unless stats.include?(key)
48
+ raise ArgumentError, "invalid :#{attr} key :#{key}, expected one of #{stats.keys}"
49
+ end
50
+ end
51
+
52
+ # Set default for any stat that hasn't been specified
53
+ stats.each do |stat|
54
+ input_attr[stat] ||= attr == :evs ? 0 : 31
55
+ end
56
+
57
+ send "#{attr}=", input_attr
58
+ end
59
+
60
+ # Copy the attributes from the constructor to instance variables
61
+ attrs.each { |key, value| send "#{key}=", value }
62
+
63
+ # Both first letter and full word, string and symbol are supported for gender
64
+ if attrs[:gender]
65
+ gender = attrs[:gender].downcase.to_sym
66
+ if self.class.gender_abbrs.flatten.include?(gender)
67
+ # Either it's the key, or the value; this will find the value either way
68
+ @gender = self.class.gender_abbrs[gender] || gender
69
+ else
70
+ raise TypeError,
71
+ "expected nil or one of #{self.class.gender_abbrs.flatten} for :gender, received #{attrs[:gender]}"
72
+ end
73
+ end
74
+
75
+ if attrs[:nature]
76
+ begin
77
+ @nature = attrs[:nature].is_a?(Integer) ? attrs[:nature] : attrs[:nature].downcase.to_sym
78
+ rescue NoMethodError
79
+ raise TypeError,
80
+ "expected a (String|Symbol|Integer) for :nature, received #{attrs[:nature].class}"
81
+ end
82
+ end
83
+
84
+ @shiny ||= false
85
+ @level ||= 50
86
+ @happiness ||= 255
87
+ @nature ||= :hardy
88
+ @moves ||= []
4
89
  end
5
90
 
6
91
  def to_s
92
+ # Build first line
93
+ str = @nickname ? "#{@nickname} (#{@species})" : @species.dup
94
+ str << " (#{@gender.to_s[0].upcase})" if @gender
95
+ str << " @ #{@item}" if @item
96
+
97
+ str << "\nAbility: #{@ability}" if @ability
98
+ str << "\nLevel: #{@level}" if @level != 50
99
+ str << "\nShiny: Yes" if @shiny
100
+ str << "\nTera Type: #{@tera_type.to_s.capitalize}" if @tera_type
101
+ str << "\nEVs: #{stat_string @evs, 0}" if @evs.any? { |_, value| value != 0 }
102
+ # Don't print neutral natures
103
+ unless %i[hardy docile serious bashful quirky].include? @nature
104
+ str << "\n#{@nature.to_s.capitalize} Nature"
105
+ end
106
+ str << "\nIVs: #{stat_string @ivs, 31}" if @ivs.any? { |_, value| value != 31 }
107
+ str << "\nHappiness: #{@happiness}" if @happiness != 255
108
+
109
+ @moves.each do |move|
110
+ str << "\n- #{move.is_a?(Array) ? move.join(" / ") : move}"
111
+ end
112
+
113
+ str
114
+ end
115
+
116
+ def shiny?
117
+ @shiny
118
+ end
119
+
120
+ private
121
+
122
+ @@stat_inflections = {
123
+ hp: "HP",
124
+ atk: "Atk",
125
+ def: "Def",
126
+ spa: "SpA",
127
+ spd: "SpD",
128
+ spe: "Spe"
129
+ }
130
+
131
+ def stat_string(stats, default)
132
+ stats.select { |_, value| value != default}
133
+ .map { |stat, value| "#{value} #{@@stat_inflections[stat]}" }.join(' / ')
7
134
  end
8
135
  end
9
136
  end
@@ -1,10 +1,12 @@
1
+ require "forwardable"
2
+
1
3
  module PokePaste
2
4
  class Team
3
5
  include Enumerable
4
6
  extend Forwardable
5
7
  def_delegators :@team, *%i[size length [] empty? last index]
6
8
 
7
- def initialize(paste)
9
+ def initialize
8
10
  @team = []
9
11
  end
10
12
 
@@ -13,6 +15,15 @@ module PokePaste
13
15
  end
14
16
 
15
17
  def to_s
18
+ map(&:to_s).join("\n\n")
19
+ end
20
+
21
+ def <<(pkmn)
22
+ if pkmn.is_a? PokePaste::Pokemon
23
+ @team << pkmn
24
+ else
25
+ raise TypeError, "invalid type, PokePaste::Pokemon expected"
26
+ end
16
27
  end
17
28
  end
18
29
  end
data/lib/pokepaste.rb CHANGED
@@ -1,10 +1,112 @@
1
- require "pokepaste/paste"
2
1
  require "pokepaste/pokemon"
2
+ require "pokepaste/team"
3
+
4
+ require "open-uri"
3
5
 
4
6
  module PokePaste
5
- def parse(paste)
7
+ def self.parse(paste)
8
+ # Each paragraph is a Pokémon (separated by 1 or more blank lines)
9
+ paragraphs = paste.strip.split(/\n\s*\n/).map { |p| p.split("\n").map &:strip }
10
+
11
+ team = PokePaste::Team.new
12
+
13
+ paragraphs.each do |paragraph|
14
+ # Line 1 can contain species, nickname, gender, and item in format like:
15
+ # Bud (Bulbasaur) (M) @ Life Orb
16
+ # Only the species is required, however
17
+ line1 = paragraph.shift
18
+ before_at, item = line1.split /\s+@\s+/
19
+
20
+ # Now work from right to left, parsing off the parts in parens
21
+
22
+ # Set the gender to nil, :male, or :female
23
+ if gender = before_at.slice!(/\s*\((m(ale)?|f(emale)?)\)$/i)
24
+ # Get rid of the parens
25
+ [/^\s*\(/, /\)$/].each { |regex| gender.slice! regex }
26
+ gender = PokePaste::Pokemon.gender_abbrs[gender.downcase[0].to_sym]
27
+ end
28
+
29
+ # This regex requires a space between the nickname and opening paren
30
+ if species = before_at.slice!(/\s+\([^\)]+\)$/i)
31
+ # We found the species inside parens, which means a nickname is present
32
+ [/^\s*\(/, /\)$/].each { |regex| species.slice! regex }
33
+ nickname = before_at
34
+ else
35
+ # Otherwise all that remains is the species, and there is no nickname
36
+ species = before_at
37
+ nickname = nil
38
+ end
39
+
40
+ pkmn = PokePaste::Pokemon.new species: species, nickname: nickname,
41
+ item: item, gender: gender
42
+
43
+ # Pull the moves out
44
+ pkmn.moves, paragraph = paragraph.partition { |line| line =~ /^\s*-/ }
45
+ if pkmn.moves.any?
46
+ pkmn.moves.map! do |line|
47
+ move_slot = line.sub /^\s*-\s*/, ""
48
+ move_slot.include?("/") ? move_slot.split(/\s*\/\s*/) : move_slot
49
+ end
50
+ end
51
+
52
+ # Pull the nature out. If there are multiple, the first is used
53
+ nature_line, paragraph = paragraph.partition { |line| line =~ /nature\s*$/i }
54
+ if nature_line.any?
55
+ pkmn.nature = nature_line.first.sub(/\s*nature\s*$/i, "").downcase.to_sym
56
+ end
57
+
58
+ # All that we're left with at this point are attributes that are denoted with
59
+ # the syntax "Attribute: Value". Let's loop over them and parse the attribute
60
+ paragraph.each do |line|
61
+ attribute, value = line.split /\s*:\s*/, 2
62
+ attribute = attribute.downcase.gsub(/\s+/, "_").to_sym
63
+
64
+ # At this point attribute will be a symbol with the snake_case approximation
65
+ # of whatever was before the first ":" in the string. If we know what it does,
66
+ # we can manipulate it as desired, otherwise just let it through as a string.
67
+ # This is intended to be a flexible format.
68
+ if %i[evs ivs].include?(attribute)
69
+ data = value.split /\s*\/\s*/
70
+ data.map { |d| d.split /\s+/, 2 }.each do |value, stat|
71
+ current_value = pkmn.send attribute
72
+ current_value[stat.downcase.to_sym] = value.to_i
73
+ pkmn.send "#{attribute}=", current_value
74
+ end
75
+ elsif %i[level happiness].include?(attribute)
76
+ pkmn.send "#{attribute}=", value.to_i
77
+ elsif attribute == :shiny
78
+ pkmn.shiny = %w[yes true].include?(value.downcase)
79
+ else
80
+ pkmn.send "#{attribute}=", value
81
+ end
82
+ end
83
+
84
+ team << pkmn
85
+ end
86
+
87
+ team
6
88
  end
7
89
 
8
- def fetch(str)
90
+ def self.fetch(str)
91
+ input_url = URI.parse(str)
92
+ unless [nil, "pokepast.es"].include? input_url.host
93
+ raise ArgumentError, "invalid URL; must be valid pokepast.es URL or path, received '#{str}'"
94
+ end
95
+
96
+ path = (input_url.host ? input_url.path : str).gsub /^\//, ""
97
+ if path.empty?
98
+ raise ArgumentError, "invalid URL; no paste ID found in '#{str}'"
99
+ end
100
+
101
+ # The paste is in <article> tags
102
+ paste_content = URI.open("https://pokepast.es/#{path}").read.
103
+ slice(/(?<=\<article\>)[\S\s]*(?=\<\/article\>)/)
104
+
105
+ unless paste_content
106
+ raise OpenURI::HTTPError.new "no paste found at '#{str}'", 404
107
+ end
108
+
109
+ # Removing all HTML tags is sufficient to pass the string to the parser
110
+ parse paste_content.gsub(/\<\/?[^\>]+\>/, "")
9
111
  end
10
112
  end
@@ -0,0 +1,57 @@
1
+ require "spec_helper"
2
+
3
+ describe PokePaste do
4
+ let(:paste) { PokePaste::parse TEST_PASTE }
5
+
6
+ describe "#parse" do
7
+ TEST_DATA.each_with_index do |attrs, i|
8
+ attrs.each do |attr, value|
9
+ it "processes :#{attr}#{attr == :shiny ? '?' : ''} correctly" do
10
+ attr = (attr.to_s + "?").to_sym if attr == :shiny
11
+ expect(paste[i].send attr).to eq value
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ describe "#fetch" do
18
+ before :each do
19
+ # stub a PokéPaste request
20
+ end
21
+
22
+ it "works with a full URL" do
23
+ fetch = PokePaste::fetch TEST_PASTE_URL
24
+
25
+ test_paste_equality paste, fetch
26
+ end
27
+
28
+ it "works with a path" do
29
+ fetch = PokePaste::fetch "/#{TEST_PASTE_ID}"
30
+
31
+ test_paste_equality paste, fetch
32
+ end
33
+
34
+ it "works with an ID" do
35
+ fetch = PokePaste::fetch TEST_PASTE_ID
36
+
37
+ test_paste_equality paste, fetch
38
+ end
39
+
40
+ it "fails with an invalid host or no path" do
41
+ ["https://google.com/",
42
+ "https://pokepast.es",
43
+ "http://localhost/test"].each do |input|
44
+ expect { PokePaste::fetch input }.to raise_error ArgumentError
45
+ end
46
+ end
47
+
48
+ it "fails with an invalid input" do
49
+ ["https://pokepast.es/nobodyhome",
50
+ "somerandomtext",
51
+ "https://pokepast.es/syntax.html",
52
+ "syntax.html"].each do |input|
53
+ expect { PokePaste::fetch input }.to raise_error OpenURI::HTTPError
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,92 @@
1
+ require "spec_helper"
2
+
3
+ # For most of these the species doesn't matter, here's a shortcut
4
+ def init_pkmn(**args)
5
+ PokePaste::Pokemon.new species: "Bulbasaur", **args
6
+ end
7
+
8
+ GENDERS = {m: :male, f: :female}
9
+
10
+ describe PokePaste::Pokemon do
11
+ context "when initialized with no species" do
12
+ it "throws an ArgumentError" do
13
+ expect { PokePaste::Pokemon.new }.to raise_error ArgumentError
14
+ end
15
+ end
16
+
17
+ %i[evs ivs shiny level happiness moves].each do |attr|
18
+ context "when initiaized with an invalid type for :#{attr}" do
19
+ it "throws a TypeError" do
20
+ expect { init_pkmn attr => "string" }.to raise_error TypeError
21
+ end
22
+ end
23
+ end
24
+
25
+ GENDERS.each do |shorthand, gender|
26
+ context "when gender :#{shorthand} is used" do
27
+ it "expands it to :#{gender}" do
28
+ expect(init_pkmn(gender: shorthand).gender).to eq gender
29
+ end
30
+ end
31
+
32
+ context "when a string '#{gender}' is used" do
33
+ it "changes it to a symbol" do
34
+ expect(init_pkmn(gender: gender.to_s).gender).to eq gender
35
+ end
36
+ end
37
+
38
+ context "when a string '#{shorthand}' is used" do
39
+ it "changes it to the symbol :#{gender}" do
40
+ expect(init_pkmn(gender: shorthand.to_s).gender).to eq gender
41
+ end
42
+ end
43
+ end
44
+
45
+ context "when a gender unavailable in the Pokémon games is used" do
46
+ it "raises a typeerror" do
47
+ expect { init_pkmn gender: :test }.to raise_error TypeError
48
+ end
49
+ end
50
+
51
+ it "downcases the gender" do
52
+ expect(init_pkmn(gender: "Male").gender).to eq :male
53
+ end
54
+
55
+ context "when you try to pass in a boolean for the nature" do
56
+ it "raises a typeerror" do
57
+ expect { init_pkmn nature: true }.to raise_error TypeError
58
+ end
59
+ end
60
+
61
+ context "when you pass a string in for the nature" do
62
+ it "converts it to a lowercase symbol" do
63
+ expect(init_pkmn(nature: "Bold").nature).to eq :bold
64
+ end
65
+ end
66
+
67
+ %i[evs ivs].each do |attr|
68
+ # n is the default
69
+ n = attr == :evs ? 0 : 31
70
+ attr_title = attr.to_s.chop.upcase
71
+
72
+ context "when given a single #{attr_title}" do
73
+ it "keeps the rest of the #{attr_title}s at their defaults" do
74
+ expect(init_pkmn(attr => {hp: 10}).send attr).to eq({
75
+ hp: 10, atk: n, def: n, spa: n, spd: n, spe: n
76
+ })
77
+ end
78
+ end
79
+ end
80
+
81
+ context "when initialized with only a species" do
82
+ let(:pkmn) { PokePaste::Pokemon.new(species: "Armarouge") }
83
+
84
+ # The second 'mon in the test data is an Armarouge with
85
+ # all default values, nothing set except the species.
86
+ TEST_DATA[1].each do |attr, value|
87
+ it "sets the :#{attr} attribute correctly" do
88
+ expect(pkmn.send attr).to eq value
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,33 @@
1
+ require "spec_helper"
2
+
3
+ describe PokePaste::Team do
4
+ let :team do
5
+ team = PokePaste::Team.new
6
+ TEST_DATA.each { |pkmn| team << PokePaste::Pokemon.new(**pkmn) }
7
+ team
8
+ end
9
+
10
+ describe "#to_s" do
11
+ it "produces the correct PokéPaste" do
12
+ expect(team.to_s).to eq TEST_PASTE
13
+ end
14
+ end
15
+
16
+ describe "#<<" do
17
+ context "when given a PokePaste::Pokemon" do
18
+ it "adds it to the team" do
19
+ orig_size = team.size
20
+ team << PokePaste::Pokemon.new(species: (test_species = "Bulbasaur"))
21
+
22
+ expect(team.size).to eq (orig_size + 1)
23
+ expect(team.last.species).to eq test_species
24
+ end
25
+ end
26
+
27
+ context "when given a string" do
28
+ it "throws a TypeError" do
29
+ expect { team << "string" }.to raise_error TypeError
30
+ end
31
+ end
32
+ end
33
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,13 @@
1
+ require "pokepaste"
2
+
1
3
  # Include all files in spec/support
2
4
  Dir[File.expand_path("../support/**/*.rb", __FILE__)].each { |f| require f }
3
5
 
4
6
  RSpec.configure do |config|
7
+ # Add `focus: true` hash parameter to a describe/context/it block
8
+ # to only run the specs in that block
9
+ config.filter_run_when_matching :focus
10
+
5
11
  # Fuubar
6
12
  config.add_formatter "Fuubar"
7
13
  config.fuubar_progress_bar_options = { format: " %c/%C |%b>%i|%e " }
@@ -0,0 +1,8 @@
1
+ def test_paste_equality(a, b)
2
+ %w[species nickname gender item evs ivs shiny?
3
+ ability tera_type level happiness nature moves].each do |attr|
4
+ a.each_with_index do |pkmn, index|
5
+ expect(pkmn.send attr).to eq b[index].send(attr)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,126 @@
1
+ # These aren't intended to be realistic or legal setups; this is merely to
2
+ # broadly test the features of the parser.
3
+
4
+ TEST_PASTE = <<~EOS.strip
5
+ Mr. Mime-Galar (M) @ Heavy-Duty Boots
6
+ Ability: Vital Spirit
7
+ Modest Nature
8
+ IVs: 0 Atk / 0 Spe
9
+ - Hidden Power [Dark]
10
+ - Freeze-Dry
11
+ - Dragon Hammer
12
+ - Acid
13
+
14
+ Armarouge
15
+
16
+ Manny (Great Tusk)
17
+ Ability: Protosynthesis
18
+ Level: 85
19
+ Shiny: Yes
20
+ Tera Type: Ground
21
+ EVs: 1 HP / 2 Atk / 3 Def / 4 SpA / 5 SpD / 6 Spe
22
+ Jolly Nature
23
+ IVs: 1 HP / 2 Atk / 3 Def / 4 SpA / 5 SpD / 6 Spe
24
+ Happiness: 100
25
+ - Headlong Rush
26
+ - Earthquake
27
+
28
+ Wo-Chien @ Rocky Helmet
29
+ Ability: Tablets of Ruin
30
+ Tera Type: Dark
31
+ - Ruination
32
+ - Zen Headbutt
33
+
34
+ Glimmora (F)
35
+ Shiny: Yes
36
+ EVs: 4 Atk / 252 SpA / 252 Spe
37
+ Naive Nature
38
+ IVs: 0 Atk
39
+ - Dazzling Gleam
40
+ - Flash Cannon
41
+ - Mortal Spin
42
+ - Power Gem / Protect
43
+ EOS
44
+
45
+ # Identical to TEST_PASTE, uploaded to pokepast.es:
46
+ TEST_PASTE_URL = "https://pokepast.es/a979ce56c2109382"
47
+ TEST_PASTE_ID = "a979ce56c2109382"
48
+
49
+ # This paste is expected to be parsed into this data:
50
+ TEST_DATA = [
51
+ {
52
+ species: "Mr. Mime-Galar",
53
+ nickname: nil,
54
+ gender: :male,
55
+ item: "Heavy-Duty Boots",
56
+ evs: {hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0},
57
+ ivs: {hp: 31, atk: 0, def: 31, spa: 31, spd: 31, spe: 0},
58
+ shiny: false,
59
+ ability: "Vital Spirit",
60
+ tera_type: nil,
61
+ level: 50,
62
+ happiness: 255,
63
+ nature: :modest,
64
+ moves: ["Hidden Power [Dark]", "Freeze-Dry", "Dragon Hammer", "Acid"]
65
+ },
66
+ {
67
+ species: "Armarouge",
68
+ nickname: nil,
69
+ gender: nil,
70
+ item: nil,
71
+ evs: {hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0},
72
+ ivs: {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31},
73
+ shiny: false,
74
+ ability: nil,
75
+ tera_type: nil,
76
+ level: 50,
77
+ happiness: 255,
78
+ nature: :hardy,
79
+ moves: []
80
+ },
81
+ {
82
+ species: "Great Tusk",
83
+ nickname: "Manny",
84
+ gender: nil,
85
+ item: nil,
86
+ evs: {hp: 1, atk: 2, def: 3, spa: 4, spd: 5, spe: 6},
87
+ ivs: {hp: 1, atk: 2, def: 3, spa: 4, spd: 5, spe: 6},
88
+ shiny: true,
89
+ ability: "Protosynthesis",
90
+ tera_type: "Ground",
91
+ level: 85,
92
+ happiness: 100,
93
+ nature: :jolly,
94
+ moves: ["Headlong Rush", "Earthquake"]
95
+ },
96
+ {
97
+ species: "Wo-Chien",
98
+ nickname: nil,
99
+ gender: nil,
100
+ item: "Rocky Helmet",
101
+ evs: {hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0},
102
+ ivs: {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31},
103
+ shiny: false,
104
+ ability: "Tablets of Ruin",
105
+ tera_type: "Dark",
106
+ level: 50,
107
+ happiness: 255,
108
+ nature: :hardy,
109
+ moves: ["Ruination", "Zen Headbutt"]
110
+ },
111
+ {
112
+ species: "Glimmora",
113
+ nickname: nil,
114
+ gender: :female,
115
+ item: nil,
116
+ evs: {hp: 0, atk: 4, def: 0, spa: 252, spd: 0, spe: 252},
117
+ ivs: {hp: 31, atk: 0, def: 31, spa: 31, spd: 31, spe: 31},
118
+ shiny: true,
119
+ ability: nil,
120
+ tera_type: nil,
121
+ level: 50,
122
+ happiness: 255,
123
+ nature: :naive,
124
+ moves: ["Dazzling Gleam", "Flash Cannon", "Mortal Spin", ["Power Gem", "Protect"]]
125
+ }
126
+ ]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pokepaste
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.0'
4
+ version: '0.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vinny Diehl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-04 00:00:00.000000000 Z
11
+ date: 2023-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -77,10 +77,15 @@ files:
77
77
  - Rakefile
78
78
  - VERSION
79
79
  - lib/pokepaste.rb
80
- - lib/pokepaste/paste.rb
81
80
  - lib/pokepaste/pokemon.rb
81
+ - lib/pokepaste/team.rb
82
82
  - pokepaste.gemspec
83
+ - spec/pokepaste/parser_spec.rb
84
+ - spec/pokepaste/pokemon_spec.rb
85
+ - spec/pokepaste/team_spec.rb
83
86
  - spec/spec_helper.rb
87
+ - spec/support/paste_equality.rb
88
+ - spec/support/test_paste.rb
84
89
  homepage: https://github.com/vinnydiehl/pokepaste-ruby
85
90
  licenses:
86
91
  - MIT
@@ -105,4 +110,9 @@ signing_key:
105
110
  specification_version: 4
106
111
  summary: PokéPaste parser for Ruby
107
112
  test_files:
113
+ - spec/pokepaste/parser_spec.rb
114
+ - spec/pokepaste/pokemon_spec.rb
115
+ - spec/pokepaste/team_spec.rb
108
116
  - spec/spec_helper.rb
117
+ - spec/support/paste_equality.rb
118
+ - spec/support/test_paste.rb