// Path: src/main/java/org/javiermf/features/models/Product.java
// @Entity
// public class Product {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @OneToMany(mappedBy = "product", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
//     Set<Feature> productFeatures = new HashSet<Feature>();
// 
//     @OneToMany(mappedBy = "forProduct", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
//     Set<FeatureConstraint> productFeatureConstraints = new HashSet<FeatureConstraint>();
// 
//     @JsonProperty("features")
//     public Set<Feature> getProductFeatures() {
//         return productFeatures;
//     }
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void addFeature(Feature feature) {
//         productFeatures.add(feature);
//     }
// 
//     public void removeFeature(Feature feature) {
//         productFeatures.remove(feature);
//     }
// 
//     public static Product buildWithFeatures(String... featureNames) {
//         Product product = new Product();
//         for (String featureName : featureNames) {
//             product.addFeature(Feature.withName(product, featureName));
//         }
// 
//         return product;
// 
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     @JsonProperty("constraints")
//     public Set<FeatureConstraint> getProductFeatureConstraints() {
//         return productFeatureConstraints;
//     }
// 
//     public Feature findProductFeatureByName(String featureName) {
//         for (Feature feature : getProductFeatures()) {
//             if (feature.name.equalsIgnoreCase(featureName)) {
//                 return feature;
//             }
//         }
// 
//         throw new ObjectNotFoundException(featureName);
//     }
// 
//     public boolean hasFeatureNamed(String featureName) {
//         for (Feature feature : getProductFeatures()) {
//             if (feature.name.equalsIgnoreCase(featureName)) {
//                 return true;
//             }
//         }
// 
//         return false;
//     }
// 
//     public void addFeatureConstraint(FeatureConstraint constraint) {
//         productFeatureConstraints.add(constraint);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/evaluation/EvaluationResult.java
// public class EvaluationResult {
// 
//     public boolean isValid = true;
// 
//     public Set<String> derivedFeatures = new HashSet<String>();
// 
//     public Set<String> evaluationErrorMessages = new HashSet<String>();
// 
// 
// }


import org.javiermf.features.models.Product;
import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.models.evaluation.EvaluationResult;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
package org.javiermf.features.models.constraints;



public class ConstraintRequiresTests {

    @Test
    public void shouldBeEmptyIfNoAddedFeatures() throws Exception {
        String SOURCE_FEATURE = "SOURCE_FEATURE";
        String REQUIRED_FEATURE = "REQUIRED_FEATURE";

        ConstraintRequires requires = new ConstraintRequires(SOURCE_FEATURE, REQUIRED_FEATURE);

        Product product = Product.buildWithFeatures(SOURCE_FEATURE, REQUIRED_FEATURE);
        product.addFeatureConstraint(requires);

// Path: src/main/java/org/javiermf/features/models/Product.java
// @Entity
// public class Product {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @OneToMany(mappedBy = "product", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
//     Set<Feature> productFeatures = new HashSet<Feature>();
// 
//     @OneToMany(mappedBy = "forProduct", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
//     Set<FeatureConstraint> productFeatureConstraints = new HashSet<FeatureConstraint>();
// 
//     @JsonProperty("features")
//     public Set<Feature> getProductFeatures() {
//         return productFeatures;
//     }
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void addFeature(Feature feature) {
//         productFeatures.add(feature);
//     }
// 
//     public void removeFeature(Feature feature) {
//         productFeatures.remove(feature);
//     }
// 
//     public static Product buildWithFeatures(String... featureNames) {
//         Product product = new Product();
//         for (String featureName : featureNames) {
//             product.addFeature(Feature.withName(product, featureName));
//         }
// 
//         return product;
// 
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     @JsonProperty("constraints")
//     public Set<FeatureConstraint> getProductFeatureConstraints() {
//         return productFeatureConstraints;
//     }
// 
//     public Feature findProductFeatureByName(String featureName) {
//         for (Feature feature : getProductFeatures()) {
//             if (feature.name.equalsIgnoreCase(featureName)) {
//                 return feature;
//             }
//         }
// 
//         throw new ObjectNotFoundException(featureName);
//     }
// 
//     public boolean hasFeatureNamed(String featureName) {
//         for (Feature feature : getProductFeatures()) {
//             if (feature.name.equalsIgnoreCase(featureName)) {
//                 return true;
//             }
//         }
// 
//         return false;
//     }
// 
//     public void addFeatureConstraint(FeatureConstraint constraint) {
//         productFeatureConstraints.add(constraint);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/evaluation/EvaluationResult.java
// public class EvaluationResult {
// 
//     public boolean isValid = true;
// 
//     public Set<String> derivedFeatures = new HashSet<String>();
// 
//     public Set<String> evaluationErrorMessages = new HashSet<String>();
// 
// 
// }


// Path: src/test/java/org/javiermf/features/models/constraints/ConstraintRequiresTests.java
import org.javiermf.features.models.Product;
import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.models.evaluation.EvaluationResult;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

package org.javiermf.features.models.constraints;



public class ConstraintRequiresTests {

    @Test
    public void shouldBeEmptyIfNoAddedFeatures() throws Exception {
        String SOURCE_FEATURE = "SOURCE_FEATURE";
        String REQUIRED_FEATURE = "REQUIRED_FEATURE";

        ConstraintRequires requires = new ConstraintRequires(SOURCE_FEATURE, REQUIRED_FEATURE);

        Product product = Product.buildWithFeatures(SOURCE_FEATURE, REQUIRED_FEATURE);
        product.addFeatureConstraint(requires);

        ProductConfiguration configuration = new ProductConfiguration();