pokepaste 0.0 → 0.1

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: 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