<commit_before># coding=utf-8
# Copyright 2019 The TensorFlow GAN Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests for TF-GAN tfgan.eval."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tempfile

import tensorflow as tf
import tensorflow_gan as tfgan
from tensorflow.python import tf2  # pylint:disable=g-direct-tensorflow-import

def generator_model(inputs):
  return tf.compat.v1.get_variable('dummy_g', initializer=2.0) * inputs

def discriminator_model(inputs, _):
  return tf.compat.v1.get_variable('dummy_d', initializer=2.0) * inputs

def stargan_generator_model(inputs, _):
  return generator_model(inputs)

def get_gan_model():
  # TODO(joelshor): Find a better way of creating a variable scope.
  with tf.compat.v1.variable_scope('generator') as gen_scope:
    pass
  with tf.compat.v1.variable_scope('discriminator') as dis_scope:
    pass
  return tfgan.GANModel(
      generator_inputs=tf.zeros([4, 32, 32, 3]),
      generated_data=tf.zeros([4, 32, 32, 3]),
      generator_variables=[tf.Variable(0), tf.Variable(1)],
      generator_scope=gen_scope,
      generator_fn=generator_model,
      real_data=tf.ones([4, 32, 32, 3]),
      discriminator_real_outputs=tf.ones([1, 2, 3]),
      discriminator_gen_outputs=tf.ones([1, 2, 3]),
      discriminator_variables=[tf.Variable(0)],
      discriminator_scope=dis_scope,
      discriminator_fn=discriminator_model)

def get_stargan_model():
  """Similar to get_gan_model()."""
  # TODO(joelshor): Find a better way of creating a variable scope.
  with tf.compat.v1.variable_scope('discriminator') as dis_scope:
    pass
  with tf.compat.v1.variable_scope('generator') as gen_scope:
    return tfgan.StarGANModel(
        input_data=tf.ones([1, 2, 2, 3]),
        input_data_domain_label=tf.ones([1, 2]),
        generated_data=stargan_generator_model(
            tf.ones([1, 2, 2, 3]), None),
        generated_data_domain_target=tf.ones([1, 2]),
        reconstructed_data=tf.ones([1, 2, 2, 3]),
        discriminator_input_data_source_predication=tf.ones([1]),
        discriminator_generated_data_source_predication=tf.ones([1]),
        discriminator_input_data_domain_predication=tf.ones([1, 2]),
        discriminator_generated_data_domain_predication=tf.ones([1, 2]),
        generator_variables=None,
        generator_scope=gen_scope,
        generator_fn=stargan_generator_model,
        discriminator_variables=None,
        discriminator_scope=dis_scope,
        discriminator_fn=discriminator_model)

def get_cyclegan_model():
  with tf.compat.v1.variable_scope('x2y'):
    model_x2y = get_gan_model()
  with tf.compat.v1.variable_scope('y2x'):
    model_y2x = get_gan_model()
  return tfgan.CycleGANModel(
      model_x2y=model_x2y,
      model_y2x=model_y2x,
      reconstructed_x=tf.zeros([4, 32, 32, 3]),
      reconstructed_y=tf.zeros([4, 32, 32, 3]))

class SummariesTest(tf.test.TestCase):

  def _test_add_gan_model_image_summaries_impl(
      self, get_model_fn, expected_num_summary_ops, model_summaries):
    if tf2.enabled():
      tmpfile = tempfile.NamedTemporaryFile().name
      with tf.summary.create_file_writer(tmpfile).as_default():
        tfgan.eval.add_gan_model_image_summaries(
            get_model_fn(), grid_size=2, model_summaries=model_summaries)
    else:
      tfgan.eval.add_gan_model_image_summaries(
          get_model_fn(), grid_size=2, model_summaries=model_summaries)
      self.assertEqual(
          expected_num_summary_ops,
          len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
      with self.cached_session() as sess:
        sess.run(tf.compat.v1.global_variables_initializer())
        sess.run(tf.compat.v1.summary.merge_all())

  def test_add_gan_model_image_summaries(self):
    self._test_add_gan_model_image_summaries_impl(get_gan_model, 5, True)

  def test_add_gan_model_image_summaries_no_model(self):
    self._test_add_gan_model_image_summaries_impl(get_gan_model, 2, False)

  def test_cyclegan_image_summaries_dont_work(self):
    with self.assertRaises(ValueError):
      tfgan.eval.add_gan_model_image_summaries(get_cyclegan_model())

  def _test_add_gan_model_summaries_impl(self, get_model_fn,
                                         expected_num_summary_ops):
    if tf2.enabled():
      tmpfile = tempfile.NamedTemporaryFile().name
      with tf.summary.create_file_writer(tmpfile).as_default():
        tfgan.eval.add_gan_model_summaries(get_model_fn())
    else:
      tfgan.eval.add_gan_model_summaries(get_model_fn())
      self.assertEqual(
          expected_num_summary_ops,
          len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
      with self.cached_session() as sess:
        sess.run(tf.compat.v1.global_variables_initializer())
        sess.run(tf.compat.v1.summary.merge_all())

  def test_add_gan_model_summaries(self):
    self._test_add_gan_model_summaries_impl(get_gan_model, 3)

  def test_add_gan_model_summaries_for_cyclegan(self):
    self._test_add_gan_model_summaries_impl(get_cyclegan_model, 6)

  def _test_add_regularization_loss_summaries_impl(self, get_model_fn,
                                                   expected_num_summary_ops):
    if tf2.enabled():
      tmpfile = tempfile.NamedTemporaryFile().name
      with tf.summary.create_file_writer(tmpfile).as_default():
        tfgan.eval.add_regularization_loss_summaries(get_model_fn())
    else:
      tfgan.eval.add_regularization_loss_summaries(get_model_fn())
      self.assertEqual(
          expected_num_summary_ops,
          len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
      with self.cached_session() as sess:
        sess.run(tf.compat.v1.summary.merge_all())

  def test_add_regularization_loss_summaries(self):
    self._test_add_regularization_loss_summaries_impl(get_gan_model, 2)

  def test_add_regularization_loss_summaries_for_cyclegan(self):
    self._test_add_regularization_loss_summaries_impl(get_cyclegan_model, 4)

  # TODO(joelshor): Add correctness test.
  def _test_add_image_comparison_summaries_impl(self, get_model_fn,
                                                expected_num_summary_ops):
    if tf2.enabled():
      tmpfile = tempfile.NamedTemporaryFile().name
      with tf.summary.create_file_writer(tmpfile).as_default():
        tfgan.eval.add_image_comparison_summaries(
            get_model_fn(), display_diffs=True)
    else:
      tfgan.eval.add_image_comparison_summaries(
          get_model_fn(), display_diffs=True)

      self.assertEqual(
          expected_num_summary_ops,
          len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
      with self.cached_session() as sess:
        sess.run(tf.compat.v1.summary.merge_all())

  def test_add_image_comparison_summaries(self):
    self._test_add_image_comparison_summaries_impl(get_gan_model, 1)

  def test_add_image_comparison_summaries_for_cyclegan(self):
    if tf2.enabled():
      tmpfile = tempfile.NamedTemporaryFile().name
      with tf.summary.create_file_writer(tmpfile).as_default():
        tfgan.eval.add_cyclegan_image_summaries(get_cyclegan_model())
    else:
      tfgan.eval.add_cyclegan_image_summaries(get_cyclegan_model())

      self.assertEqual(
          2, len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
      with self.cached_session() as sess:
        sess.run(tf.compat.v1.summary.merge_all())

  def test_add_image_comparison_summaries_for_stargan(self):
    if tf2.enabled():
      tmpfile = tempfile.NamedTemporaryFile().name
      with tf.summary.create_file_writer(tmpfile).as_default():
        tfgan.eval.add_stargan_image_summaries(get_stargan_model())
    else:
      tfgan.eval.add_stargan_image_summaries(get_stargan_model())

      self.assertEqual(
          1, len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))

      with self.cached_session() as sess:
        sess.run(tf.compat.v1.global_variables_initializer())
        sess.run(tf.compat.v1.summary.merge_all())

if __name__ == '__main__':
  tf.test.main()
<commit_msg>Disable summaries tests in eager mode.<commit_after># coding=utf-8
# Copyright 2019 The TensorFlow GAN Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests for TF-GAN tfgan.eval."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
import tensorflow_gan as tfgan

def generator_model(inputs):
  return tf.compat.v1.get_variable('dummy_g', initializer=2.0) * inputs

def discriminator_model(inputs, _):
  return tf.compat.v1.get_variable('dummy_d', initializer=2.0) * inputs

def stargan_generator_model(inputs, _):
  return generator_model(inputs)

def get_gan_model():
  # TODO(joelshor): Find a better way of creating a variable scope.
  with tf.compat.v1.variable_scope('generator') as gen_scope:
    pass
  with tf.compat.v1.variable_scope('discriminator') as dis_scope:
    pass
  return tfgan.GANModel(
      generator_inputs=tf.zeros([4, 32, 32, 3]),
      generated_data=tf.zeros([4, 32, 32, 3]),
      generator_variables=[tf.Variable(0), tf.Variable(1)],
      generator_scope=gen_scope,
      generator_fn=generator_model,
      real_data=tf.ones([4, 32, 32, 3]),
      discriminator_real_outputs=tf.ones([1, 2, 3]),
      discriminator_gen_outputs=tf.ones([1, 2, 3]),
      discriminator_variables=[tf.Variable(0)],
      discriminator_scope=dis_scope,
      discriminator_fn=discriminator_model)

def get_stargan_model():
  """Similar to get_gan_model()."""
  # TODO(joelshor): Find a better way of creating a variable scope.
  with tf.compat.v1.variable_scope('discriminator') as dis_scope:
    pass
  with tf.compat.v1.variable_scope('generator') as gen_scope:
    return tfgan.StarGANModel(
        input_data=tf.ones([1, 2, 2, 3]),
        input_data_domain_label=tf.ones([1, 2]),
        generated_data=stargan_generator_model(
            tf.ones([1, 2, 2, 3]), None),
        generated_data_domain_target=tf.ones([1, 2]),
        reconstructed_data=tf.ones([1, 2, 2, 3]),
        discriminator_input_data_source_predication=tf.ones([1]),
        discriminator_generated_data_source_predication=tf.ones([1]),
        discriminator_input_data_domain_predication=tf.ones([1, 2]),
        discriminator_generated_data_domain_predication=tf.ones([1, 2]),
        generator_variables=None,
        generator_scope=gen_scope,
        generator_fn=stargan_generator_model,
        discriminator_variables=None,
        discriminator_scope=dis_scope,
        discriminator_fn=discriminator_model)

def get_cyclegan_model():
  with tf.compat.v1.variable_scope('x2y'):
    model_x2y = get_gan_model()
  with tf.compat.v1.variable_scope('y2x'):
    model_y2x = get_gan_model()
  return tfgan.CycleGANModel(
      model_x2y=model_x2y,
      model_y2x=model_y2x,
      reconstructed_x=tf.zeros([4, 32, 32, 3]),
      reconstructed_y=tf.zeros([4, 32, 32, 3]))

class SummariesTest(tf.test.TestCase):

  def _test_add_gan_model_image_summaries_impl(
      self, get_model_fn, expected_num_summary_ops, model_summaries):
    if tf.executing_eagerly():
      return
    tfgan.eval.add_gan_model_image_summaries(
        get_model_fn(), grid_size=2, model_summaries=model_summaries)
    self.assertEqual(
        expected_num_summary_ops,
        len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
    with self.cached_session() as sess:
      sess.run(tf.compat.v1.global_variables_initializer())
      sess.run(tf.compat.v1.summary.merge_all())

  def test_add_gan_model_image_summaries(self):
    self._test_add_gan_model_image_summaries_impl(get_gan_model, 5, True)

  def test_add_gan_model_image_summaries_no_model(self):
    self._test_add_gan_model_image_summaries_impl(get_gan_model, 2, False)

  def test_cyclegan_image_summaries_dont_work(self):
    with self.assertRaises(ValueError):
      tfgan.eval.add_gan_model_image_summaries(get_cyclegan_model())

  def _test_add_gan_model_summaries_impl(self, get_model_fn,
                                         expected_num_summary_ops):
    if tf.executing_eagerly():
      return
    tfgan.eval.add_gan_model_summaries(get_model_fn())
    self.assertEqual(
        expected_num_summary_ops,
        len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
    with self.cached_session() as sess:
      sess.run(tf.compat.v1.global_variables_initializer())
      sess.run(tf.compat.v1.summary.merge_all())

  def test_add_gan_model_summaries(self):
    self._test_add_gan_model_summaries_impl(get_gan_model, 3)

  def test_add_gan_model_summaries_for_cyclegan(self):
    self._test_add_gan_model_summaries_impl(get_cyclegan_model, 6)

  def _test_add_regularization_loss_summaries_impl(self, get_model_fn,
                                                   expected_num_summary_ops):
    if tf.executing_eagerly():
      return
    tfgan.eval.add_regularization_loss_summaries(get_model_fn())
    self.assertEqual(
        expected_num_summary_ops,
        len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
    with self.cached_session() as sess:
      sess.run(tf.compat.v1.summary.merge_all())

  def test_add_regularization_loss_summaries(self):
    self._test_add_regularization_loss_summaries_impl(get_gan_model, 2)

  def test_add_regularization_loss_summaries_for_cyclegan(self):
    self._test_add_regularization_loss_summaries_impl(get_cyclegan_model, 4)

  # TODO(joelshor): Add correctness test.
  def _test_add_image_comparison_summaries_impl(self, get_model_fn,
                                                expected_num_summary_ops):
    if tf.executing_eagerly():
      return
    tfgan.eval.add_image_comparison_summaries(
        get_model_fn(), display_diffs=True)

    self.assertEqual(
        expected_num_summary_ops,
        len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
    with self.cached_session() as sess:
      sess.run(tf.compat.v1.summary.merge_all())

  def test_add_image_comparison_summaries(self):
    self._test_add_image_comparison_summaries_impl(get_gan_model, 1)

  def test_add_image_comparison_summaries_for_cyclegan(self):
    if tf.executing_eagerly():
      return
    tfgan.eval.add_cyclegan_image_summaries(get_cyclegan_model())

    self.assertEqual(
        2, len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))
    with self.cached_session() as sess:
      sess.run(tf.compat.v1.summary.merge_all())

  def test_add_image_comparison_summaries_for_stargan(self):
    if tf.executing_eagerly():
      return
    tfgan.eval.add_stargan_image_summaries(get_stargan_model())

    self.assertEqual(
        1, len(tf.compat.v1.get_collection(tf.compat.v1.GraphKeys.SUMMARIES)))

    with self.cached_session() as sess:
      sess.run(tf.compat.v1.global_variables_initializer())
      sess.run(tf.compat.v1.summary.merge_all())

if __name__ == '__main__':
  tf.test.main()
<|endoftext|>


<commit_before>"""
Copyright (C) 2017 Open Source Robotics Foundation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from shapely.geometry import Polygon
from geometry.point import Point

from models.city import City
from models.street import Street
from models.trunk import Trunk
from models.block import Block
from models.building import Building
from models.ground_plane import GroundPlane

from builders.abstract_city_builder import AbstractCityBuilder

from procedural_city.vertex import *
from procedural_city.polygon2d import Polygon2D, Edge
from procedural_city.vertex_graph_to_roads_converter \
    import VertexGraphToRoadsConverter
from procedural_city.polygons_to_blocks_converter \
    import PolygonsToBlocksConverter
from procedural_city.pcg_runner import PcgRunner

import pickle

class ProceduralCityBuilder(AbstractCityBuilder):
    def __init__(self, verticesFilename=None, polygonsFilename=None, size=1500, pcg_runner=None):
        if pcg_runner is None:
            # Default runner
            self.pcg_runner = PcgRunner()
        else:
            self.pcg_runner = pcg_runner
        self.verticesFilename = verticesFilename
        self.polygonsFilename = polygonsFilename
        self.ratio = 100  # ratio between pcg and gazebo (1unit = 100m)
        self.pcg_runner.set_size(size / self.ratio)

    def get_city(self):
        city = City()

        # If no verticesFilename or polygonsFilename is specified,
        # generate new ones using procedural_city_generation
        if self.verticesFilename is None or self.polygonsFilename is None:
            self.pcg_runner.run()
            self.verticesFilename = self.pcg_runner.get_vertices_filename()
            self.polygonsFilename = self.pcg_runner.get_polygons_filename()

        vertices = self._parse_vertices_file()
        self._build_roads(city, vertices)

        polygons = self._parse_polygons_file()
        for block in self._build_blocks(polygons):
            city.add_block(block)

        city.set_ground_plane(GroundPlane(100, Point(0, 0, 0)))
        return city

    def _build_roads(self, city, vertex_list):
        vertex_mapping = {}
        for vertex in vertex_list:
            vertex_mapping[vertex] = GraphNode.from_vertex(vertex, self.ratio)
        for vertex, node in vertex_mapping.iteritems():
            node_neighbours = map(lambda vertex_neighbour: vertex_mapping[vertex_neighbour],
                                  vertex.neighbours)
            node.set_neighbours(node_neighbours)

        # 0.79 rad ~ 45 deg
        converter = VertexGraphToRoadsConverter(city, 0.79, vertex_mapping.values())
        converter.run()

    def _build_blocks(self, polygon_list):
        lot_polygons = filter(lambda polygon: polygon.is_lot(), polygon_list)
        block_polygons = []
        # Make sure the polygons overlap, as sometimes merging two polygons
        # leave holes due to rounding. We should later change this to initially
        # make a small buffer (e.g. 0.1) for merging purposes and then do the
        # final buffering to tweak overlapping with the street before building
        # the block.
        buffer_size = self.ratio * 0.06

        for polygon in lot_polygons:
            points = polygon.get_vertices_as_points(self.ratio)
            poly = Polygon(points).buffer(buffer_size, 16, 1, 1, 2)
            block_polygons.append(poly)

        converter = PolygonsToBlocksConverter(block_polygons)
        return converter.get_blocks()

    def _parse_vertices_file(self):
        original = 'procedural_city_generation.roadmap.Vertex'
        replace = 'builders.procedural_city.vertex'
        return self._parse_replacing(self.verticesFilename, original, replace)

    def _parse_polygons_file(self):
        original = 'procedural_city_generation.polygons.Polygon2D'
        replace = 'builders.procedural_city.polygon2d'
        return self._parse_replacing(self.polygonsFilename, original, replace)

    def _parse_replacing(self, filename, original_name, replace_name):
        with open(filename, 'rb') as f:
            # TODO: We should read/pre-process this lazily, no point in loading
            # the whole thing in memory.
            # Here we do the hacky conversion, from the Vertex class dumped in
            # procedural_city_generation package to our Vertex class use by
            # this builder.
            contents = f.read().replace(original_name, replace_name)
            return pickle.loads(contents)
<commit_msg>Give PCG a constant order<commit_after>"""
Copyright (C) 2017 Open Source Robotics Foundation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from shapely.geometry import Polygon
from geometry.point import Point

from models.city import City
from models.street import Street
from models.trunk import Trunk
from models.block import Block
from models.building import Building
from models.ground_plane import GroundPlane

from builders.abstract_city_builder import AbstractCityBuilder

from procedural_city.vertex import *
from procedural_city.polygon2d import Polygon2D, Edge
from procedural_city.vertex_graph_to_roads_converter \
    import VertexGraphToRoadsConverter
from procedural_city.polygons_to_blocks_converter \
    import PolygonsToBlocksConverter
from procedural_city.pcg_runner import PcgRunner

import pickle

class ProceduralCityBuilder(AbstractCityBuilder):
    def __init__(self, verticesFilename=None, polygonsFilename=None, size=1500, pcg_runner=None):
        if pcg_runner is None:
            # Default runner
            self.pcg_runner = PcgRunner()
        else:
            self.pcg_runner = pcg_runner
        self.verticesFilename = verticesFilename
        self.polygonsFilename = polygonsFilename
        self.ratio = 100  # ratio between pcg and gazebo (1unit = 100m)
        self.pcg_runner.set_size(size / self.ratio)

    def get_city(self):
        city = City()

        # If no verticesFilename or polygonsFilename is specified,
        # generate new ones using procedural_city_generation
        if self.verticesFilename is None or self.polygonsFilename is None:
            self.pcg_runner.run()
            self.verticesFilename = self.pcg_runner.get_vertices_filename()
            self.polygonsFilename = self.pcg_runner.get_polygons_filename()

        vertices = self._parse_vertices_file()
        self._build_roads(city, vertices)

        polygons = self._parse_polygons_file()
        for block in self._build_blocks(polygons):
            city.add_block(block)

        city.set_ground_plane(GroundPlane(100, Point(0, 0, 0)))
        return city

    def _build_roads(self, city, vertex_list):
        origin = Point(0, 0)
        vertex_mapping = {}
        for vertex in vertex_list:
            vertex_mapping[vertex] = GraphNode.from_vertex(vertex, self.ratio)
        for vertex, node in vertex_mapping.iteritems():
            node_neighbours = map(lambda vertex_neighbour: vertex_mapping[vertex_neighbour],
                                  vertex.neighbours)
            node_neighbours = sorted(node_neighbours,
                                     key=lambda node: node.location.distance_to(origin))
            node.set_neighbours(node_neighbours)

        nodes = sorted(vertex_mapping.values(),
                       key=lambda node: node.location.distance_to(origin))

        # 0.79 rad ~ 45 deg
        converter = VertexGraphToRoadsConverter(city, 0.79, nodes)
        converter.run()

    def _build_blocks(self, polygon_list):
        lot_polygons = filter(lambda polygon: polygon.is_lot(), polygon_list)
        block_polygons = []
        # Make sure the polygons overlap, as sometimes merging two polygons
        # leave holes due to rounding. We should later change this to initially
        # make a small buffer (e.g. 0.1) for merging purposes and then do the
        # final buffering to tweak overlapping with the street before building
        # the block.
        buffer_size = self.ratio * 0.06

        for polygon in lot_polygons:
            points = polygon.get_vertices_as_points(self.ratio)
            poly = Polygon(points).buffer(buffer_size, 16, 1, 1, 2)
            block_polygons.append(poly)

        converter = PolygonsToBlocksConverter(block_polygons)
        return converter.get_blocks()

    def _parse_vertices_file(self):
        original = 'procedural_city_generation.roadmap.Vertex'
        replace = 'builders.procedural_city.vertex'
        return self._parse_replacing(self.verticesFilename, original, replace)

    def _parse_polygons_file(self):
        original = 'procedural_city_generation.polygons.Polygon2D'
        replace = 'builders.procedural_city.polygon2d'
        return self._parse_replacing(self.polygonsFilename, original, replace)

    def _parse_replacing(self, filename, original_name, replace_name):
        with open(filename, 'rb') as f:
            # TODO: We should read/pre-process this lazily, no point in loading
            # the whole thing in memory.
            # Here we do the hacky conversion, from the Vertex class dumped in
            # procedural_city_generation package to our Vertex class use by
            # this builder.
            contents = f.read().replace(original_name, replace_name)
            return pickle.loads(contents)
<|endoftext|>


<commit_before>import json
import mock
import time
import unittest

import validation_api
import validations

def json_response(response, code=200):
    assert response.status_code == code
    return json.loads(response.data)

def passing_validation(*args):
    return { 'hostname': { 'success': True } }

def failing_validation(*args):
    return { 'hostname': { 'success': False } }

def running_validation(*args):
    time.sleep(0.1)
    return {}

def wait_for_request_to_be_processed(sleep_time=0.002):
    # Wait for a previous request to be processes
    # This is an ugly hack to deal with concurency issues
    time.sleep(sleep_time)

class ValidationAPITestCase(unittest.TestCase):

    def setUp(self):
        validation_api.app.config['TESTING'] = True
        self.app = validation_api.app.test_client()
        validation_api.prepare_database()

    def tearDown(self):
        # Ensure we run tests in isolation
        validation_api.DB_VALIDATIONS = validation_api.DB['validations']

class ValidationsTestCase(ValidationAPITestCase):

    def test_root(self):
        rv = self.app.get('/')
        self.assertIn('Print the API routes.', rv.data)

    def test_list_validations(self):
        rv = self.app.get('/v1/validations/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(len(json_response(rv)), 3)

    def test_list_validations_content(self):
        rv = self.app.get('/v1/validations/')
        json = json_response(rv)[0]
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'name': 'Basic connectivity',
                'description': 'A simple ping test',
            }, json)

    def test_list_validations_missing_metadata(self):
        rv = self.app.get('/v1/validations/')
        json = json_response(rv)[2]
        self.assertDictContainsSubset(
            {
                'uuid': '2',
                'name': 'Unnamed',
                'description': 'No description',
            }, json)

    def test_get_validation(self):
        rv = self.app.get('/v1/validations/1/')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv)

    def test_get_unknown_validation(self):
        rv = self.app.get('/v1/validations/100/')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv, 404)

    def test_get_new_validation_content(self):
        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'new',
                'latest_result': None,
                'results': [],
            }, json_response(rv))

    def test_validation_run(self):
        validations.run = mock.Mock(side_effect=passing_validation)
        rv = self.app.put('/v1/validations/1/run')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 204)
        wait_for_request_to_be_processed()
        self.assertEqual(validations.run.call_count, 1)

    def test_run_unknown_validation(self):
        rv = self.app.put('/v1/validations/100/run')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv, 404)

    def test_get_running_validation_content(self):
        validations.run = mock.Mock(side_effect=running_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'running',
            }, json_response(rv))

    def test_get_successful_validation_content(self):
        validations.run = mock.Mock(side_effect=passing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'success',
            }, json_response(rv))

    def test_get_failed_validation_content(self):
        validations.run = mock.Mock(side_effect=failing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'failed',
            }, json_response(rv))

    def test_validation_stop_running(self):
        validations.run = mock.Mock(side_effect=running_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        rv = self.app.put('/v1/validations/1/stop')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 204)
        wait_for_request_to_be_processed()
        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'canceled',
            }, json_response(rv))

    def test_validation_stop_non_running(self):
        rv = self.app.put('/v1/validations/1/stop')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 400)

    def test_validation_stop_unknown(self):
        rv = self.app.put('/v1/validations/100/stop')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 404)

class ValidationTypesTestCase(ValidationAPITestCase):

    def test_list_validation_types(self):
        rv = self.app.get('/v1/validation_types/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(len(json_response(rv)), 3)

    def test_list_validation_types_content(self):
        rv = self.app.get('/v1/validation_types/')
        json = json_response(rv)[0]
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'name': 'First validation type',
                'description': 'The first validation type',
                'stage': 'discovery',
            }, json)
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'ref': '/v1/validations/1/',
                'name': 'Basic connectivity',
            }, json['validations'][0])

    def test_list_validation_typess_missing_metadata(self):
        rv = self.app.get('/v1/validation_types/')
        json = json_response(rv)[1]
        self.assertDictContainsSubset(
            {
                'uuid': '3',
                'name': 'Unnamed',
                'description': 'No description',
                'stage': 'Default stage',
            }, json)

    def test_get_validation_type(self):
        rv = self.app.get('/v1/validation_types/1/')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv)

    def test_get_unknown_validation_type(self):
        rv = self.app.get('/v1/validation_types/100/')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv, 404)

    def test_get_new_validation_type_content(self):
        rv = self.app.get('/v1/validation_types/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                # 'status': 'new',
            }, json_response(rv))

class ValidationResultsTestCase(ValidationAPITestCase):

    def test_list_validation_results_empty(self):
        rv = self.app.get('/v1/validation_results/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(len(json_response(rv)), 0)

    def test_list_validation_results(self):
        validations.run = mock.Mock(side_effect=passing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        rv = self.app.get('/v1/validation_results/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(len(json_response(rv)), 1)

    def test_passing_validation_result(self):
        validations.run = mock.Mock(side_effect=passing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        validation = json_response(self.app.get('/v1/validations/1/'))

        rv = self.app.get(validation['results'][0])
        json = json_response(rv)
        self.assertIn('date', json)
        self.assertDictContainsSubset(
            {
                'status': 'success',
                'validation': '/v1/validations/1/',
                'detailed_description': passing_validation(),
            }, json)

        self.assertEqual(json, validation['latest_result'])

    def test_failed_validation_result(self):
        validations.run = mock.Mock(side_effect=failing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        validation = json_response(self.app.get('/v1/validations/1/'))

        rv = self.app.get(validation['results'][0])
        json = json_response(rv)
        self.assertIn('date', json)
        self.assertDictContainsSubset(
            {
                'status': 'failed',
                'validation': '/v1/validations/1/',
                'detailed_description': failing_validation(),
            }, json)

        self.assertEqual(json, validation['latest_result'])

    def test_running_validation_result(self):
        validations.run = mock.Mock(side_effect=running_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        validation = json_response(self.app.get('/v1/validations/1/'))

        rv = self.app.get(validation['results'][0])
        json = json_response(rv)
        self.assertIn('date', json)
        self.assertDictContainsSubset(
            {
                'status': 'running',
                'validation': '/v1/validations/1/',
            }, json)

        self.assertEqual(json, validation['latest_result'])

    def test_canceled_validation_result(self):
        validations.run = mock.Mock(side_effect=running_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        rv = self.app.put('/v1/validations/1/stop')
        wait_for_request_to_be_processed()
        validation = json_response(self.app.get('/v1/validations/1/'))

        rv = self.app.get(validation['results'][0])
        json = json_response(rv)
        self.assertIn('date', json)
        self.assertDictContainsSubset(
            {
                'status': 'canceled',
                'validation': '/v1/validations/1/',
            }, json)

        self.assertEqual(json, validation['latest_result'])

    def test_unknown_validation_result(self):
        rv = self.app.get('/v1/validation_results/100/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 404)

if __name__ == '__main__':
    unittest.main()
<commit_msg>Add test for re-run running validation<commit_after>import json
import mock
import time
import unittest

import validation_api
import validations

def json_response(response, code=200):
    assert response.status_code == code
    return json.loads(response.data)

def passing_validation(*args):
    return { 'hostname': { 'success': True } }

def failing_validation(*args):
    return { 'hostname': { 'success': False } }

def running_validation(*args):
    time.sleep(0.1)
    return {}

def wait_for_request_to_be_processed(sleep_time=0.002):
    # Wait for a previous request to be processes
    # This is an ugly hack to deal with concurency issues
    time.sleep(sleep_time)

class ValidationAPITestCase(unittest.TestCase):

    def setUp(self):
        validation_api.app.config['TESTING'] = True
        self.app = validation_api.app.test_client()
        validation_api.prepare_database()

    def tearDown(self):
        # Ensure we run tests in isolation
        validation_api.DB_VALIDATIONS = validation_api.DB['validations']

class ValidationsTestCase(ValidationAPITestCase):

    def test_root(self):
        rv = self.app.get('/')
        self.assertIn('Print the API routes.', rv.data)

    def test_list_validations(self):
        rv = self.app.get('/v1/validations/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(len(json_response(rv)), 3)

    def test_list_validations_content(self):
        rv = self.app.get('/v1/validations/')
        json = json_response(rv)[0]
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'name': 'Basic connectivity',
                'description': 'A simple ping test',
            }, json)

    def test_list_validations_missing_metadata(self):
        rv = self.app.get('/v1/validations/')
        json = json_response(rv)[2]
        self.assertDictContainsSubset(
            {
                'uuid': '2',
                'name': 'Unnamed',
                'description': 'No description',
            }, json)

    def test_get_validation(self):
        rv = self.app.get('/v1/validations/1/')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv)

    def test_get_unknown_validation(self):
        rv = self.app.get('/v1/validations/100/')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv, 404)

    def test_get_new_validation_content(self):
        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'new',
                'latest_result': None,
                'results': [],
            }, json_response(rv))

    def test_validation_run(self):
        validations.run = mock.Mock(side_effect=passing_validation)
        rv = self.app.put('/v1/validations/1/run')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 204)
        wait_for_request_to_be_processed()
        self.assertEqual(validations.run.call_count, 1)

    def test_run_unknown_validation(self):
        rv = self.app.put('/v1/validations/100/run')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv, 404)

    def test_get_running_validation_content(self):
        validations.run = mock.Mock(side_effect=running_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()

        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'running',
            }, json_response(rv))

    def test_get_successful_validation_content(self):
        validations.run = mock.Mock(side_effect=passing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()

        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'success',
            }, json_response(rv))

    def test_get_failed_validation_content(self):
        validations.run = mock.Mock(side_effect=failing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()

        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'failed',
            }, json_response(rv))

    def test_validation_stop_running(self):
        validations.run = mock.Mock(side_effect=running_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()

        rv = self.app.put('/v1/validations/1/stop')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 204)
        wait_for_request_to_be_processed()

        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'canceled',
            }, json_response(rv))

    def test_validation_stop_non_running(self):
        rv = self.app.put('/v1/validations/1/stop')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 400)

    def test_validation_stop_unknown(self):
        rv = self.app.put('/v1/validations/100/stop')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 404)

    def test_validation_rerun_running(self):
        validations.run = mock.Mock(side_effect=running_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()

        rv = self.app.put('/v1/validations/1/run')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 400)

        rv = self.app.get('/v1/validations/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'status': 'running',
            }, json_response(rv))

class ValidationTypesTestCase(ValidationAPITestCase):

    def test_list_validation_types(self):
        rv = self.app.get('/v1/validation_types/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(len(json_response(rv)), 3)

    def test_list_validation_types_content(self):
        rv = self.app.get('/v1/validation_types/')
        json = json_response(rv)[0]
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'name': 'First validation type',
                'description': 'The first validation type',
                'stage': 'discovery',
            }, json)
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                'ref': '/v1/validations/1/',
                'name': 'Basic connectivity',
            }, json['validations'][0])

    def test_list_validation_typess_missing_metadata(self):
        rv = self.app.get('/v1/validation_types/')
        json = json_response(rv)[1]
        self.assertDictContainsSubset(
            {
                'uuid': '3',
                'name': 'Unnamed',
                'description': 'No description',
                'stage': 'Default stage',
            }, json)

    def test_get_validation_type(self):
        rv = self.app.get('/v1/validation_types/1/')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv)

    def test_get_unknown_validation_type(self):
        rv = self.app.get('/v1/validation_types/100/')
        self.assertEqual(rv.content_type, 'application/json')
        json_response(rv, 404)

    def test_get_new_validation_type_content(self):
        rv = self.app.get('/v1/validation_types/1/')
        self.assertDictContainsSubset(
            {
                'uuid': '1',
                # 'status': 'new',
            }, json_response(rv))

class ValidationResultsTestCase(ValidationAPITestCase):

    def test_list_validation_results_empty(self):
        rv = self.app.get('/v1/validation_results/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(len(json_response(rv)), 0)

    def test_list_validation_results(self):
        validations.run = mock.Mock(side_effect=passing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()

        rv = self.app.get('/v1/validation_results/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(len(json_response(rv)), 1)

    def test_passing_validation_result(self):
        validations.run = mock.Mock(side_effect=passing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        validation = json_response(self.app.get('/v1/validations/1/'))

        rv = self.app.get(validation['results'][0])
        json = json_response(rv)
        self.assertIn('date', json)
        self.assertDictContainsSubset(
            {
                'status': 'success',
                'validation': '/v1/validations/1/',
                'detailed_description': passing_validation(),
            }, json)

        self.assertEqual(json, validation['latest_result'])

    def test_failed_validation_result(self):
        validations.run = mock.Mock(side_effect=failing_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        validation = json_response(self.app.get('/v1/validations/1/'))

        rv = self.app.get(validation['results'][0])
        json = json_response(rv)
        self.assertIn('date', json)
        self.assertDictContainsSubset(
            {
                'status': 'failed',
                'validation': '/v1/validations/1/',
                'detailed_description': failing_validation(),
            }, json)

        self.assertEqual(json, validation['latest_result'])

    def test_running_validation_result(self):
        validations.run = mock.Mock(side_effect=running_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        validation = json_response(self.app.get('/v1/validations/1/'))

        rv = self.app.get(validation['results'][0])
        json = json_response(rv)
        self.assertIn('date', json)
        self.assertDictContainsSubset(
            {
                'status': 'running',
                'validation': '/v1/validations/1/',
            }, json)

        self.assertEqual(json, validation['latest_result'])

    def test_canceled_validation_result(self):
        validations.run = mock.Mock(side_effect=running_validation)
        self.app.put('/v1/validations/1/run')
        wait_for_request_to_be_processed()
        rv = self.app.put('/v1/validations/1/stop')
        wait_for_request_to_be_processed()
        validation = json_response(self.app.get('/v1/validations/1/'))

        rv = self.app.get(validation['results'][0])
        json = json_response(rv)
        self.assertIn('date', json)
        self.assertDictContainsSubset(
            {
                'status': 'canceled',
                'validation': '/v1/validations/1/',
            }, json)

        self.assertEqual(json, validation['latest_result'])

    def test_unknown_validation_result(self):
        rv = self.app.get('/v1/validation_results/100/')
        self.assertEqual(rv.content_type, 'application/json')
        self.assertEqual(rv.status_code, 404)

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before>"""A module containing tests for the library implementation of accessing resources."""
from lxml import etree
import pytest
import six
import iati.core.constants
import iati.core.resources

class TestResources(object):
    """A container for tests relating to resources."""

    @pytest.fixture(params=[None] + iati.core.constants.STANDARD_VERSIONS)
    def standard_version_optional(self, request):
        """Return a list that can be used as variable positional parameters (i.e. `*standard_version_optional`) to test.
        This can then be used in tests which have an optional parameter for the year.

        Returns:
            list: An empty list, or a list containing a string which corresponds to a version of the Standard.

        """
        version = request.param

        if version is None:
            return []
        else:
            return [version]

    @pytest.mark.parametrize('version, expected_version_foldername', [
        ('2.02', '202'),
        ('2.01', '201'),
        ('1.05', '105'),
        ('1.04', '104')
    ])
    def test_get_folder_name_for_version(self, version, expected_version_foldername):
        """Check that expected components are present within folder paths."""
        path = iati.core.resources.get_folder_name_for_version(version)
        assert expected_version_foldername == path

    @pytest.mark.parametrize('version', [
        '1.00',
        '1',
        1,
        1.01,  # A verion must be specified as a string
        'string'
    ])
    def test_get_folder_name_for_version_invalid_version(self, version):
        """Check that an invalid version of the Standard raises a ValueError exception."""
        with pytest.raises(ValueError):
            iati.core.resources.get_folder_name_for_version(version)

    @pytest.mark.parametrize('path_component', [
        'resources',
        'standard'
    ])
    def test_get_folder_path_for_version(self, standard_version_optional, path_component):
        """Check that expected components are present within folder paths."""
        path = iati.core.resources.get_folder_path_for_version(*standard_version_optional)
        assert path_component in path

    def test_codelist_flow_type(self):
        """Check that the FlowType codelist is loaded as a string and contains content.

        Todo:
            Test passing all version numbers to get_codelist_path

        """
        path = iati.core.resources.get_codelist_path('FlowType')

        content = iati.core.resources.load_as_string(path)

        assert len(content) > 3200

    def test_find_codelist_paths(self):
        """Check that all codelist paths are being found.

        Todo:
            Add other tests relating to specific versions of the Standard.

        """
        paths = iati.core.resources.get_all_codelist_paths()

        assert len(paths) == 62
        for path in paths:
            assert path[-4:] == iati.core.resources.FILE_CODELIST_EXTENSION
            assert iati.core.resources.PATH_CODELISTS in path

    def test_get_all_activity_schema_paths(self, standard_version_optional):
        """Check that all activity schema paths are found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        activity_paths = iati.core.resources.get_all_activity_schema_paths(*standard_version_optional)

        assert len(activity_paths) == 1

    def test_get_all_org_schema_paths(self, standard_version_optional):
        """Check that all organisation schema paths are found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        organisation_paths = iati.core.resources.get_all_org_schema_paths(*standard_version_optional)

        assert len(organisation_paths) == 1

    def test_find_schema_paths(self, standard_version_optional):
        """Check that both the activity and organisation schema paths are being found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        paths = iati.core.resources.get_all_schema_paths(*standard_version_optional)

        assert len(paths) == 2

    @pytest.mark.parametrize('get_schema_path_function', [
        iati.core.resources.get_all_schema_paths,
        iati.core.resources.get_all_activity_schema_paths,
        iati.core.resources.get_all_org_schema_paths
    ])
    def test_find_schema_paths_file_extension(self, standard_version_optional, get_schema_path_function):
        """Check that the correct file extension is present within file paths returned by get_all_*schema_paths functions."""
        paths = get_schema_path_function(*standard_version_optional)

        for path in paths:
            assert path[-4:] == iati.core.resources.FILE_SCHEMA_EXTENSION

    @pytest.mark.parametrize('codelist', [
        'Name',
        'Name.xml',
    ])
    def test_get_codelist_path_name(self, standard_version_optional, codelist):
        """Check that a codelist path is found from just a name."""
        path = iati.core.resources.get_codelist_path(codelist, *standard_version_optional)

        assert path[-4:] == iati.core.resources.FILE_CODELIST_EXTENSION
        assert path.count(iati.core.resources.FILE_CODELIST_EXTENSION) == 1
        assert iati.core.resources.PATH_CODELISTS in path

    def test_load_as_bytes(self):
        """Test that resources.load_as_bytes returns a bytes object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('invalid')

        result = iati.core.resources.load_as_bytes(path_test_data)

        assert isinstance(result, bytes)
        assert result == 'This is a string that is not valid XML\n'.encode()

    def test_load_as_dataset(self):
        """Test that resources.load_as_dataset returns a Dataset object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('valid')

        result = iati.core.resources.load_as_dataset(path_test_data)

        assert isinstance(result, iati.core.Dataset)
        assert '<?xml version="1.0"?>\n\n<iati-activities version="2.02">' in result.xml_str

    def test_load_as_string(self):
        """Test that resources.load_as_string returns a string (python3) or unicode (python2) object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('invalid')

        result = iati.core.resources.load_as_string(path_test_data)

        assert isinstance(result, six.string_types)
        assert result == 'This is a string that is not valid XML\n'

    def test_resource_filename(self):
        """Check that resource file names are found correctly.

        Todo:
            Implement better assertions.

        """
        path = iati.core.resources.PATH_SCHEMAS
        filename = iati.core.resources.resource_filename(path)

        assert len(filename) > len(path)
        assert filename.endswith(path)

    def test_schema_activity_string(self):
        """Check that the Activity schema file contains content."""
        path = iati.core.resources.get_schema_path('iati-activities-schema')

        content = iati.core.resources.load_as_string(path)

        assert len(content) > 130000

    def test_schema_activity_tree(self):
        """Check that the Activity schema loads into an XML Tree.

        This additionally involves checking that imported schemas also work.

        """
        path = iati.core.resources.get_schema_path('iati-activities-schema')
        schema = iati.core.resources.load_as_tree(path)

        assert isinstance(schema, etree._ElementTree)  # pylint: disable=protected-access
<commit_msg>Ensure get_*_version fuctions are tested against an expected None pa§rameter<commit_after>"""A module containing tests for the library implementation of accessing resources."""
from lxml import etree
import pytest
import six
import iati.core.constants
import iati.core.resources

class TestResources(object):
    """A container for tests relating to resources."""

    @pytest.fixture(params=['no_arguments', None] + iati.core.constants.STANDARD_VERSIONS)
    def standard_version_optional(self, request):
        """Return a list that can be used as variable positional parameters (i.e. `*standard_version_optional`) to test.
        This can then be used in tests which have an optional parameter for the year.

        Returns:
            list: Either i) an empty list, ii) a list containing None, or iii) a string which corresponds to a version of the Standard.

        """
        arg = request.param

        if arg == 'no_arguments':
            return []
        else:
            return [arg]

    @pytest.mark.parametrize('version, expected_version_foldername', [
        ('2.02', '202'),
        ('2.01', '201'),
        ('1.05', '105'),
        ('1.04', '104')
    ])
    def test_get_folder_name_for_version(self, version, expected_version_foldername):
        """Check that expected components are present within folder paths."""
        path = iati.core.resources.get_folder_name_for_version(version)
        assert expected_version_foldername == path

    @pytest.mark.parametrize('version', [
        '1.00',
        '1',
        1,
        1.01,  # A verion must be specified as a string
        'string'
    ])
    def test_get_folder_name_for_version_invalid_version(self, version):
        """Check that an invalid version of the Standard raises a ValueError exception."""
        with pytest.raises(ValueError):
            iati.core.resources.get_folder_name_for_version(version)

    @pytest.mark.parametrize('path_component', [
        'resources',
        'standard'
    ])
    def test_get_folder_path_for_version(self, standard_version_optional, path_component):
        """Check that expected components are present within folder paths."""
        path = iati.core.resources.get_folder_path_for_version(*standard_version_optional)
        assert path_component in path

    def test_codelist_flow_type(self):
        """Check that the FlowType codelist is loaded as a string and contains content.

        Todo:
            Test passing all version numbers to get_codelist_path

        """
        path = iati.core.resources.get_codelist_path('FlowType')

        content = iati.core.resources.load_as_string(path)

        assert len(content) > 3200

    def test_find_codelist_paths(self):
        """Check that all codelist paths are being found.

        Todo:
            Add other tests relating to specific versions of the Standard.

        """
        paths = iati.core.resources.get_all_codelist_paths()

        assert len(paths) == 62
        for path in paths:
            assert path[-4:] == iati.core.resources.FILE_CODELIST_EXTENSION
            assert iati.core.resources.PATH_CODELISTS in path

    def test_get_all_activity_schema_paths(self, standard_version_optional):
        """Check that all activity schema paths are found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        activity_paths = iati.core.resources.get_all_activity_schema_paths(*standard_version_optional)

        assert len(activity_paths) == 1

    def test_get_all_org_schema_paths(self, standard_version_optional):
        """Check that all organisation schema paths are found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        organisation_paths = iati.core.resources.get_all_org_schema_paths(*standard_version_optional)

        assert len(organisation_paths) == 1

    def test_find_schema_paths(self, standard_version_optional):
        """Check that both the activity and organisation schema paths are being found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        paths = iati.core.resources.get_all_schema_paths(*standard_version_optional)

        assert len(paths) == 2

    @pytest.mark.parametrize('get_schema_path_function', [
        iati.core.resources.get_all_schema_paths,
        iati.core.resources.get_all_activity_schema_paths,
        iati.core.resources.get_all_org_schema_paths
    ])
    def test_find_schema_paths_file_extension(self, standard_version_optional, get_schema_path_function):
        """Check that the correct file extension is present within file paths returned by get_all_*schema_paths functions."""
        paths = get_schema_path_function(*standard_version_optional)

        for path in paths:
            assert path[-4:] == iati.core.resources.FILE_SCHEMA_EXTENSION

    @pytest.mark.parametrize('codelist', [
        'Name',
        'Name.xml',
    ])
    def test_get_codelist_path_name(self, standard_version_optional, codelist):
        """Check that a codelist path is found from just a name."""
        path = iati.core.resources.get_codelist_path(codelist, *standard_version_optional)

        assert path[-4:] == iati.core.resources.FILE_CODELIST_EXTENSION
        assert path.count(iati.core.resources.FILE_CODELIST_EXTENSION) == 1
        assert iati.core.resources.PATH_CODELISTS in path

    def test_load_as_bytes(self):
        """Test that resources.load_as_bytes returns a bytes object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('invalid')

        result = iati.core.resources.load_as_bytes(path_test_data)

        assert isinstance(result, bytes)
        assert result == 'This is a string that is not valid XML\n'.encode()

    def test_load_as_dataset(self):
        """Test that resources.load_as_dataset returns a Dataset object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('valid')

        result = iati.core.resources.load_as_dataset(path_test_data)

        assert isinstance(result, iati.core.Dataset)
        assert '<?xml version="1.0"?>\n\n<iati-activities version="2.02">' in result.xml_str

    def test_load_as_string(self):
        """Test that resources.load_as_string returns a string (python3) or unicode (python2) object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('invalid')

        result = iati.core.resources.load_as_string(path_test_data)

        assert isinstance(result, six.string_types)
        assert result == 'This is a string that is not valid XML\n'

    def test_resource_filename(self):
        """Check that resource file names are found correctly.

        Todo:
            Implement better assertions.

        """
        path = iati.core.resources.PATH_SCHEMAS
        filename = iati.core.resources.resource_filename(path)

        assert len(filename) > len(path)
        assert filename.endswith(path)

    def test_schema_activity_string(self):
        """Check that the Activity schema file contains content."""
        path = iati.core.resources.get_schema_path('iati-activities-schema')

        content = iati.core.resources.load_as_string(path)

        assert len(content) > 130000

    def test_schema_activity_tree(self):
        """Check that the Activity schema loads into an XML Tree.

        This additionally involves checking that imported schemas also work.

        """
        path = iati.core.resources.get_schema_path('iati-activities-schema')
        schema = iati.core.resources.load_as_tree(path)

        assert isinstance(schema, etree._ElementTree)  # pylint: disable=protected-access
<|endoftext|>


<commit_before>"""A module containing tests for the library implementation of accessing resources."""
from lxml import etree
import pytest
import six
import iati.core.constants
import iati.core.resources
from iati.core.tests.utilities import codelist_lengths_by_version, standard_version_optional

class TestResources(object):
    """A container for tests relating to resources."""

    @pytest.mark.parametrize('version, expected_version_foldername', [
        ('2.02', '202'),
        ('2.01', '201'),
        ('1.05', '105'),
        ('1.04', '104')
    ])
    def test_get_folder_name_for_version(self, version, expected_version_foldername):
        """Check that expected components are present within folder paths."""
        path = iati.core.resources.get_folder_name_for_version(version)
        assert expected_version_foldername == path

    @pytest.mark.parametrize('version', [
        '1.00',
        '1',
        1,
        1.01,  # A verion must be specified as a string
        'string'
    ])
    def test_get_folder_name_for_version_invalid_version(self, version):
        """Check that an invalid version of the Standard raises a ValueError exception."""
        with pytest.raises(ValueError):
            iati.core.resources.get_folder_name_for_version(version)

    @pytest.mark.parametrize('path_component', [
        'resources',
        'standard'
    ])
    def test_get_folder_path_for_version(self, standard_version_optional, path_component):
        """Check that expected components are present within folder paths."""
        path = iati.core.resources.get_folder_path_for_version(*standard_version_optional)
        assert path_component in path

    def test_codelist_flow_type(self, standard_version_optional):
        """Check that the FlowType codelist is loaded as a string and contains content."""
        path = iati.core.resources.get_codelist_path('FlowType', *standard_version_optional)

        content = iati.core.resources.load_as_string(path)

        assert len(content) > 3200

    def test_find_codelist_paths(self, codelist_lengths_by_version):
        """Check that all codelist paths are being found."""
        paths = iati.core.resources.get_all_codelist_paths(codelist_lengths_by_version[0])

        assert len(paths) == codelist_lengths_by_version[1]
        for path in paths:
            assert path[-4:] == iati.core.resources.FILE_CODELIST_EXTENSION
            assert iati.core.resources.PATH_CODELISTS in path

    def test_get_all_activity_schema_paths(self, standard_version_optional):
        """Check that all activity schema paths are found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        activity_paths = iati.core.resources.get_all_activity_schema_paths(*standard_version_optional)

        assert len(activity_paths) == 1

    def test_get_all_org_schema_paths(self, standard_version_optional):
        """Check that all organisation schema paths are found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        organisation_paths = iati.core.resources.get_all_org_schema_paths(*standard_version_optional)

        assert len(organisation_paths) == 1

    def test_find_schema_paths(self, standard_version_optional):
        """Check that both the activity and organisation schema paths are being found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        paths = iati.core.resources.get_all_schema_paths(*standard_version_optional)

        assert len(paths) == 2

    @pytest.mark.parametrize('get_schema_path_function', [
        iati.core.resources.get_all_schema_paths,
        iati.core.resources.get_all_activity_schema_paths,
        iati.core.resources.get_all_org_schema_paths
    ])
    def test_find_schema_paths_file_extension(self, standard_version_optional, get_schema_path_function):
        """Check that the correct file extension is present within file paths returned by get_all_*schema_paths functions."""
        paths = get_schema_path_function(*standard_version_optional)

        for path in paths:
            assert path[-4:] == iati.core.resources.FILE_SCHEMA_EXTENSION

    def test_get_test_data_paths_in_folder(self):
        """Check that test data is being found in specified subfolders."""
        paths = iati.core.resources.get_test_data_paths_in_folder('ssot-activity-xml-fail')

        assert len(paths) == 237

    @pytest.mark.parametrize('codelist', [
        'Name',
        'Name.xml',
    ])
    def test_get_codelist_path_name(self, standard_version_optional, codelist):
        """Check that a codelist path is found from just a name."""
        path = iati.core.resources.get_codelist_path(codelist, *standard_version_optional)

        assert path[-4:] == iati.core.resources.FILE_CODELIST_EXTENSION
        assert path.count(iati.core.resources.FILE_CODELIST_EXTENSION) == 1
        assert iati.core.resources.PATH_CODELISTS in path

    def test_load_as_bytes(self):
        """Test that resources.load_as_bytes returns a bytes object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('invalid')

        result = iati.core.resources.load_as_bytes(path_test_data)

        assert isinstance(result, bytes)
        assert result == 'This is a string that is not valid XML\n'.encode()

    def test_load_as_dataset(self):
        """Test that resources.load_as_dataset returns a Dataset object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('valid')

        result = iati.core.resources.load_as_dataset(path_test_data)

        assert isinstance(result, iati.core.Dataset)
        assert '<?xml version="1.0"?>\n\n<iati-activities version="2.02">' in result.xml_str

    def test_load_as_string(self):
        """Test that resources.load_as_string returns a string (python3) or unicode (python2) object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('invalid')

        result = iati.core.resources.load_as_string(path_test_data)

        assert isinstance(result, six.string_types)
        assert result == 'This is a string that is not valid XML\n'

    def test_resource_filename(self):
        """Check that resource file names are found correctly.

        Todo:
            Implement better assertions.

        """
        path = iati.core.resources.PATH_SCHEMAS
        filename = iati.core.resources.resource_filename(path)

        assert len(filename) > len(path)
        assert filename.endswith(path)

    def test_schema_activity_string(self):
        """Check that the Activity schema file contains content."""
        path = iati.core.resources.get_schema_path('iati-activities-schema')

        content = iati.core.resources.load_as_string(path)

        assert len(content) > 130000

    def test_schema_activity_tree(self):
        """Check that the Activity schema loads into an XML Tree.

        This additionally involves checking that imported schemas also work.

        """
        path = iati.core.resources.get_schema_path('iati-activities-schema')
        schema = iati.core.resources.load_as_tree(path)

        assert isinstance(schema, etree._ElementTree)  # pylint: disable=protected-access
<commit_msg>Add a TODO about dealing with multiple versions<commit_after>"""A module containing tests for the library implementation of accessing resources."""
from lxml import etree
import pytest
import six
import iati.core.constants
import iati.core.resources
from iati.core.tests.utilities import codelist_lengths_by_version, standard_version_optional

class TestResources(object):
    """A container for tests relating to resources."""

    @pytest.mark.parametrize('version, expected_version_foldername', [
        ('2.02', '202'),
        ('2.01', '201'),
        ('1.05', '105'),
        ('1.04', '104')
    ])
    def test_get_folder_name_for_version(self, version, expected_version_foldername):
        """Check that expected components are present within folder paths."""
        path = iati.core.resources.get_folder_name_for_version(version)
        assert expected_version_foldername == path

    @pytest.mark.parametrize('version', [
        '1.00',
        '1',
        1,
        1.01,  # A verion must be specified as a string
        'string'
    ])
    def test_get_folder_name_for_version_invalid_version(self, version):
        """Check that an invalid version of the Standard raises a ValueError exception."""
        with pytest.raises(ValueError):
            iati.core.resources.get_folder_name_for_version(version)

    @pytest.mark.parametrize('path_component', [
        'resources',
        'standard'
    ])
    def test_get_folder_path_for_version(self, standard_version_optional, path_component):
        """Check that expected components are present within folder paths."""
        path = iati.core.resources.get_folder_path_for_version(*standard_version_optional)
        assert path_component in path

    def test_codelist_flow_type(self, standard_version_optional):
        """Check that the FlowType codelist is loaded as a string and contains content."""
        path = iati.core.resources.get_codelist_path('FlowType', *standard_version_optional)

        content = iati.core.resources.load_as_string(path)

        assert len(content) > 3200

    def test_find_codelist_paths(self, codelist_lengths_by_version):
        """Check that all codelist paths are being found."""
        paths = iati.core.resources.get_all_codelist_paths(codelist_lengths_by_version[0])

        assert len(paths) == codelist_lengths_by_version[1]
        for path in paths:
            assert path[-4:] == iati.core.resources.FILE_CODELIST_EXTENSION
            assert iati.core.resources.PATH_CODELISTS in path

    def test_get_all_activity_schema_paths(self, standard_version_optional):
        """Check that all activity schema paths are found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        activity_paths = iati.core.resources.get_all_activity_schema_paths(*standard_version_optional)

        assert len(activity_paths) == 1

    def test_get_all_org_schema_paths(self, standard_version_optional):
        """Check that all organisation schema paths are found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        organisation_paths = iati.core.resources.get_all_org_schema_paths(*standard_version_optional)

        assert len(organisation_paths) == 1

    def test_find_schema_paths(self, standard_version_optional):
        """Check that both the activity and organisation schema paths are being found.

        Todo:
            Handle all paths to schemas being found correctly.

        """
        paths = iati.core.resources.get_all_schema_paths(*standard_version_optional)

        assert len(paths) == 2

    @pytest.mark.parametrize('get_schema_path_function', [
        iati.core.resources.get_all_schema_paths,
        iati.core.resources.get_all_activity_schema_paths,
        iati.core.resources.get_all_org_schema_paths
    ])
    def test_find_schema_paths_file_extension(self, standard_version_optional, get_schema_path_function):
        """Check that the correct file extension is present within file paths returned by get_all_*schema_paths functions."""
        paths = get_schema_path_function(*standard_version_optional)

        for path in paths:
            assert path[-4:] == iati.core.resources.FILE_SCHEMA_EXTENSION

    def test_get_test_data_paths_in_folder(self):
        """Check that test data is being found in specified subfolders.

        Todo:
            Deal with multiple versions.

        """
        paths = iati.core.resources.get_test_data_paths_in_folder('ssot-activity-xml-fail')

        assert len(paths) == 237

    @pytest.mark.parametrize('codelist', [
        'Name',
        'Name.xml',
    ])
    def test_get_codelist_path_name(self, standard_version_optional, codelist):
        """Check that a codelist path is found from just a name."""
        path = iati.core.resources.get_codelist_path(codelist, *standard_version_optional)

        assert path[-4:] == iati.core.resources.FILE_CODELIST_EXTENSION
        assert path.count(iati.core.resources.FILE_CODELIST_EXTENSION) == 1
        assert iati.core.resources.PATH_CODELISTS in path

    def test_load_as_bytes(self):
        """Test that resources.load_as_bytes returns a bytes object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('invalid')

        result = iati.core.resources.load_as_bytes(path_test_data)

        assert isinstance(result, bytes)
        assert result == 'This is a string that is not valid XML\n'.encode()

    def test_load_as_dataset(self):
        """Test that resources.load_as_dataset returns a Dataset object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('valid')

        result = iati.core.resources.load_as_dataset(path_test_data)

        assert isinstance(result, iati.core.Dataset)
        assert '<?xml version="1.0"?>\n\n<iati-activities version="2.02">' in result.xml_str

    def test_load_as_string(self):
        """Test that resources.load_as_string returns a string (python3) or unicode (python2) object with the expected content."""
        path_test_data = iati.core.resources.get_test_data_path('invalid')

        result = iati.core.resources.load_as_string(path_test_data)

        assert isinstance(result, six.string_types)
        assert result == 'This is a string that is not valid XML\n'

    def test_resource_filename(self):
        """Check that resource file names are found correctly.

        Todo:
            Implement better assertions.

        """
        path = iati.core.resources.PATH_SCHEMAS
        filename = iati.core.resources.resource_filename(path)

        assert len(filename) > len(path)
        assert filename.endswith(path)

    def test_schema_activity_string(self):
        """Check that the Activity schema file contains content."""
        path = iati.core.resources.get_schema_path('iati-activities-schema')

        content = iati.core.resources.load_as_string(path)

        assert len(content) > 130000

    def test_schema_activity_tree(self):
        """Check that the Activity schema loads into an XML Tree.

        This additionally involves checking that imported schemas also work.

        """
        path = iati.core.resources.get_schema_path('iati-activities-schema')
        schema = iati.core.resources.load_as_tree(path)

        assert isinstance(schema, etree._ElementTree)  # pylint: disable=protected-access
<|endoftext|>


<commit_before>__author__ = 'leif'

#from django.contrib.auth.models import User
from game_models import PlayerAchievement, Achievement #, UserProfile
import logging

class GameAchievement(object):

    def __init__(self, userprofile, highscores, currentgame=None):
        """
        :param userprofile: ifind.models.game_models.UserProfile
        :param highscores: list of highscores for this user
        :return:
        """
        self.userprofile = userprofile
        self.highscores = highscores
        self.currentgame = currentgame
        self.logger = logging.getLogger(__name__)

    def check_achievement_criteria(self):
        pass

class AllCat(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, num_of_cats = 8):
        GameAchievement.__init__(self,userprofile, highscores)
        self.logger.info("AllCats Achievement set to %d cats", num_of_cats)
        self.num_of_cats = num_of_cats

    def check_achievement_criteria(self):
        """
        the number of highscores is a list of the highest_score in each category
        a highest_score is only recorded once they have played a game.
        but we could also check to make sure they have score points in each category, too
        :return:
        """
        self.logger.info("AllCats Achievement check being performed")
        if len(self.highscores) == self.num_of_cats:
            return True
        else:
            return False

    def __str__(self):
        #TODO(leifos): there probably a neat way to return the class name
        return self.__class__.__name__

class HighScorer(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, score_required=10000):
        GameAchievement.__init__(self,userprofile, highscores)
        self.score_required = score_required

    def check_achievement_criteria(self):
        total = 0
        for hs in self.highscores:
            total += hs.highest_score
        if total > self.score_required:
            return True
        else:
            return False

    def __str__(self):
        #TODO(leifos): there probably a neat way to return the class name
        return self.__class__.__name__

class UberSearcher(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, score_required=3000):
        GameAchievement.__init__(self,userprofile, highscores)
        self.score_required = score_required

    def check_achievement_criteria(self):
        total = 0
        #for hs in self.highscores:
        #    total += hs.highest_score
        #if total >= self.score_required:
        return self.currentgame.current_score >= self.score_required

class TenGamesPlayed(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, score_required=10):
        GameAchievement.__init__(self,userprofile, highscores)
        self.score_required = score_required

    def check_achievement_criteria(self):
        if self.userprofile.no_games_played >= self.score_required:
            return True
        return False

class FivePagesInAGame(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, score_required=5):
        GameAchievement.__init__(self,userprofile, highscores)
        self.score_required = score_required

    def check_achievement_criteria(self):
        for hs in self.highscores:
            if hs.most_no_pages_found >= self.score_required:
                return True
        return False

class GameAchievementChecker(object):
    def __init__(self, user):
        """
        :param user:
        :return:
        """
        self.user=user

    def check_and_set_new_achievements(self, userprofile, highscores, currentgame):
        """ test whether the crtieria are met for achievements that have not yet been awarded
        :param userprofile:
        :param highscores:
        :param currentgame:
        :return:
        """
        # get list of the users current player achievements
        cpal = PlayerAchievement.objects.filter(user=self.user)

        # pull out the list of achievements they have obtained.
        pal = []
        for cpa in cpal:
            pal.append(cpa.achievement)

        # get list of possible achievements
        aal = Achievement.objects.all()

        # exclude achievements already obtained
        al = []
        for a in aal:
            if a not in pal:
                al.append(a)

        # create an empty list of new achievements
        nal = []

        # for each achievement, check whether the criteria is met
        for a in al:
            outcome = self._test_achievement(a, userprofile, highscores, currentgame)
            if outcome:
                # if met, create the PlayerAchievement Record
                pa = PlayerAchievement(user=self.user, achievement=a)
                pa.save()
                # add this PlayerAchievement to a list
                nal.append(pa)

        # return list of new achievements
        return nal

    def _test_achievement(self, achievement, userprofile, highscores, currentgame):
        """ For the given achievement (ifind.models.game_models.Achievement),
        instantiate the related class and then check the criteria

        :return: true, if the achievement criteria are met, else false

        """

        #TODO(leifos): use reflection ? or some kind of class inspection to determine if the class has been implemented and then use that class
        # need some reflection in here to inspect whether the achievement class specified exists or not
        outcome = False
        ga =  None

        classes = {'HighScorer': HighScorer, 'AllCat': AllCat,
                   'UberSearcher': UberSearcher,
                   'TenGamesPlayed': TenGamesPlayed,
                   'FivePagesInAGame': FivePagesInAGame}
        if achievement.achievement_class in classes:
            gac = classes[achievement.achievement_class]
            ga = gac(userprofile, highscores, currentgame)
        if ga:
            outcome = ga.check_achievement_criteria()

        return outcome
<commit_msg>fixed game_achievements bug<commit_after>__author__ = 'leif'

#from django.contrib.auth.models import User
from game_models import PlayerAchievement, Achievement #, UserProfile
import logging

class GameAchievement(object):

    def __init__(self, userprofile, highscores, currentgame=None):
        """
        :param userprofile: ifind.models.game_models.UserProfile
        :param highscores: list of highscores for this user
        :return:
        """
        self.userprofile = userprofile
        self.highscores = highscores
        self.currentgame = currentgame
        self.logger = logging.getLogger(__name__)

    def check_achievement_criteria(self):
        pass

class AllCat(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, num_of_cats = 8):
        GameAchievement.__init__(self,userprofile, highscores)
        self.logger.info("AllCats Achievement set to %d cats", num_of_cats)
        self.num_of_cats = num_of_cats

    def check_achievement_criteria(self):
        """
        the number of highscores is a list of the highest_score in each category
        a highest_score is only recorded once they have played a game.
        but we could also check to make sure they have score points in each category, too
        :return:
        """
        self.logger.info("AllCats Achievement check being performed")
        if len(self.highscores) == self.num_of_cats:
            return True
        else:
            return False

    def __str__(self):
        #TODO(leifos): there probably a neat way to return the class name
        return self.__class__.__name__

class HighScorer(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, score_required=10000):
        GameAchievement.__init__(self,userprofile, highscores)
        self.score_required = score_required

    def check_achievement_criteria(self):
        total = 0
        for hs in self.highscores:
            total += hs.highest_score
        if total > self.score_required:
            return True
        else:
            return False

    def __str__(self):
        #TODO(leifos): there probably a neat way to return the class name
        return self.__class__.__name__

class UberSearcher(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, score_required=3000):
        GameAchievement.__init__(self,userprofile, highscores)
        self.score_required = score_required

    def check_achievement_criteria(self):
        for hs in self.highscores:
            if hs.highest_score >= self.score_required:
                return True

class TenGamesPlayed(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, score_required=10):
        GameAchievement.__init__(self,userprofile, highscores)
        self.score_required = score_required

    def check_achievement_criteria(self):
        if self.userprofile.no_games_played >= self.score_required:
            return True
        return False

class FivePagesInAGame(GameAchievement):

    def __init__(self, userprofile, highscores, currentgame=None, score_required=5):
        GameAchievement.__init__(self,userprofile, highscores)
        self.score_required = score_required

    def check_achievement_criteria(self):
        for hs in self.highscores:
            if hs.most_no_pages_found >= self.score_required:
                return True
        return False

class GameAchievementChecker(object):
    def __init__(self, user):
        """
        :param user:
        :return:
        """
        self.user=user

    def check_and_set_new_achievements(self, userprofile, highscores, currentgame):
        """ test whether the crtieria are met for achievements that have not yet been awarded
        :param userprofile:
        :param highscores:
        :param currentgame:
        :return:
        """
        # get list of the users current player achievements
        cpal = PlayerAchievement.objects.filter(user=self.user)

        # pull out the list of achievements they have obtained.
        pal = []
        for cpa in cpal:
            pal.append(cpa.achievement)

        # get list of possible achievements
        aal = Achievement.objects.all()

        # exclude achievements already obtained
        al = []
        for a in aal:
            if a not in pal:
                al.append(a)

        # create an empty list of new achievements
        nal = []

        # for each achievement, check whether the criteria is met
        for a in al:
            outcome = self._test_achievement(a, userprofile, highscores, currentgame)
            if outcome:
                # if met, create the PlayerAchievement Record
                pa = PlayerAchievement(user=self.user, achievement=a)
                pa.save()
                # add this PlayerAchievement to a list
                nal.append(pa)

        # return list of new achievements
        return nal

    def _test_achievement(self, achievement, userprofile, highscores, currentgame):
        """ For the given achievement (ifind.models.game_models.Achievement),
        instantiate the related class and then check the criteria

        :return: true, if the achievement criteria are met, else false

        """

        #TODO(leifos): use reflection ? or some kind of class inspection to determine if the class has been implemented and then use that class
        # need some reflection in here to inspect whether the achievement class specified exists or not
        outcome = False
        ga =  None

        classes = {'HighScorer': HighScorer, 'AllCat': AllCat,
                   'UberSearcher': UberSearcher,
                   'TenGamesPlayed': TenGamesPlayed,
                   'FivePagesInAGame': FivePagesInAGame}
        if achievement.achievement_class in classes:
            gac = classes[achievement.achievement_class]
            ga = gac(userprofile, highscores, currentgame)
        if ga:
            outcome = ga.check_achievement_criteria()

        return outcome
<|endoftext|>


<commit_before>import json
import pandas as pd
from sqlalchemy.sql import column
from igf_data.igfdb.baseadaptor import BaseAdaptor
from igf_data.igfdb.igfTables import Project, Analysis

class AnalysisAdaptor(BaseAdaptor):
  '''
  An adaptor class for Analysis table
  '''
  def store_analysis_data(self, data, autosave=True):
    '''
    A methodd for storing analysis data
    required params:
    data: A dictionary or a dataframe. It sould have following columns
          project_igf_id / project_id
          analysis_type: (RNA_DIFFERENTIAL_EXPRESSION/RNA_TIME_SERIES/CHIP_PEAK_CALL/SOMATIC_VARIANT_CALLING)
          analysis_description
    '''
    try:
      if not isinstance(data, pd.DataFrame):
        data=pd.DataFrame(data)

      if 'project_igf_id' in data.columns:
        project_map_function=lambda x: self.map_foreign_table_and_store_attribute( \
                                                data=x, \
                                                lookup_table=Project, \
                                                lookup_column_name='project_igf_id', \
                                                target_column_name='project_id')       # prepare the function for project id
        new_data=data.apply(project_map_function, axis=1)                              # map project id foreign key id
        data=new_data

      self.store_records(table=Analysis, data=data)
      if autosave:
        self.commit_session()
    except:
      if autosave:
        self.rollback_session()
      raise

  def fetch_analysis_records_project_igf_id(self, project_igf_id='', output_mode='dataframe',):
    '''
    A method for fetching analysis records based on project_igf_id
    required params:
      project_igf_id: default: null
      output_mode:   dataframe / object, default: dataframe
    '''
    session=self.session
    query=session.query(Project.project_igf_id, Analysis.analysis_type, Analysis.analysis_description).join(Analysis)
    if project_igf_id:
      query=query.filter(Project.project_igf_id==project_igf_id)

    try:
      results=self.fetch_records(query=query, output_mode=output_mode)
      return results
    except:
      raise

<commit_msg>updates for analysis adaptor<commit_after>import json
import pandas as pd
from sqlalchemy.sql import column
from igf_data.igfdb.baseadaptor import BaseAdaptor
from igf_data.igfdb.igfTables import Project, Analysis

class AnalysisAdaptor(BaseAdaptor):
  '''
  An adaptor class for Analysis table
  '''
  def store_analysis_data(self, data, autosave=True):
    '''
    A methodd for storing analysis data
    :params data: A dictionary or a dataframe. It sould have following columns

                  * project_igf_id / project_id
                  * analysis_type: (RNA_DIFFERENTIAL_EXPRESSION/RNA_TIME_SERIES/CHIP_PEAK_CALL/SOMATIC_VARIANT_CALLING)
                  * analysis_description
    '''
    try:
      if not isinstance(data, pd.DataFrame):
        data=pd.DataFrame(data)

      if 'project_igf_id' in data.columns:
        project_map_function=\
          lambda x: self.map_foreign_table_and_store_attribute(\
                      data=x,
                      lookup_table=Project,
                      lookup_column_name='project_igf_id',
                      target_column_name='project_id')                          # prepare the function for project id
        new_data=data.apply(project_map_function, axis=1)                              # map project id foreign key id
        data=new_data

      self.store_records(table=Analysis, data=data)
      if autosave:
        self.commit_session()
    except:
      if autosave:
        self.rollback_session()
      raise

  def fetch_analysis_records_project_igf_id(self, project_igf_id='',
                                            output_mode='dataframe'):
    '''
    A method for fetching analysis records based on project_igf_id
    :params project_igf_id: default: null
    :param output_mode:   dataframe / object, default: dataframe
    '''
    try:
      session=self.session
      query=session.\
            query(Project.project_igf_id,
                  Analysis.analysis_type,
                  Analysis.analysis_description).\
            join(Analysis,Project.project_id==Analysis.project_id)
      if project_igf_id:
        query=query.filter(Project.project_igf_id==project_igf_id)

      results=self.fetch_records(query=query, output_mode=output_mode)
      return results
    except:
      raise

<|endoftext|>