diff --git a/ChangeReqLab_merged.txt b/ChangeReqLab_merged.txt new file mode 100644 index 000000000..279444bbf --- /dev/null +++ b/ChangeReqLab_merged.txt @@ -0,0 +1,224 @@ +[ChangeReqLab] +CASE Study Lab + +Introduction: Software changes are started by creating a change request. A change request can +be a new feature, a bug fix and improvements. +User stories are short and simple descriptions of features written from the perspective of the +person who desires the new capability. +Objectives: +• To write a user story for an existing software feauture. +• Select a user story for your mandatory individual portfolio assignment. +Classwork: +• Each Team creates a GitHub Fork of the project repository [JHotDraw]. +• In future lab exercises, each team member follow [GitHub flow] to collaborate on projects. +• Select an existing feature in JHotDraw and write the user story. See this list of [existing +features] +• Use [GitHub Projects] +• Create a Card for your User Story and put it in the TODO Backlog. +Portfolio Work: +• Write the User Story for your selected JHotDraw feature. Note this is a an artifact for your +portfolio. + +1 + + [CLLab] +Concept Location Lab + +Introduction: Dynamic program analysis is the analysis of computer software that is performed +by executing programs on a real or virtual processor. For dynamic program analysis to be effective, +the target program must be executed with sufficient test inputs to produce interesting behavior. +Use of software testing measures such as code coverage helps ensure that an adequate slice of the +program’s set of possible behaviors has been observed +Objectives: +• Apply the IDE Debugger to locate feature concepts at runtime. +• Create a list of initial set of classes of the concept location results. +Classwork: +• Use the IDE Debugger to localize the classes that involves your Change Request. Features +are often started from the controller classes. Note, if your feature involves a large number of +classes then localize only the domain classes that are related to the to domain concepts. +Portfolio Work: +• Write the initial set of classes in table format as a result of your concept location based on +your selected feature. The table format is as below: +Domain Class + +Responsibility + +1 + + [AnalysisLab] +Impact Analysis Lab + +Introduction: Change impact analysis (IA) can be defined as ”identifying the potential consequences of a change, or estimating what needs to be modified to accomplish a change”. +Objectives: +• Apply static and dynamic analysis to find the estimated impacted set of classes based on +your Change request. +Classwork: +• Find The Estimated Impact Set of classes by following the activities illustrated in Figure 7.9 +in [Raj13]. + +Portfolio Work: Use Table 1 to list the packages and the number of classes you visited after you +located the concept. Write short comments explaining what you have learned about each package +and how they contribute to your feature? + +1 + + Package name + +# of classes + +Comments + +Table 1: The list of all the packages visited during impact analysis. + +2 + + [CILab] +Impact Continues Integration Lab + +Introduction: In software engineering, continuous integration (CI) is the practice of merging +all developers’ working copies to a shared mainline several times a day [Tho]. Grady Booch first +proposed the term CI in his 1991 method although he did not advocate integrating several times +a day [Boo]. Extreme programming (XP) adopted the concept of CI and did advocate integrating +more than once per day – perhaps as many as tens of times per day [Bec99]. +Objectives: +• Understand what CI is. +• Setup a simple CI pipeline. +Classwork: +1. Go to [Building and testing Java with Maven] +2. Add a *.yml file to your repository path /.github/workflows/ to tell +GitHub Actions CI what to do. +3. Configure the *.yml to automatically build your project for each pull request (use maven). +4. To use shared jars from GitHub Packages you need create a .maven-settings.xml file in +the project root folder, see [Working with the Apache Maven registry] +5. Configure the *.yml to execute tests automatically. + +References +[Bec99] Kent Beck. Embracing change with extreme programming, 1999. [HTML]. +[Boo] + +Grady Booch. Object Oriented Design: With Applications. [HTML]. + +[Tho] + +ThoughtWorks. Continues Integration. [HTML]. + +1 + + [RefactLab] +Refactoring Lab +Jan Corfixen Sørensen +Introduction: Refactoring is a disciplined technique for restructuring an existing body of code, +altering its internal structure without changing its external behavior. Its heart is a series of small +behavior preserving transformations. Each transformation (called a ”refactoring”) does little, but a +sequence of these transformations can produce a significant restructuring. Since each refactoring is +small, it’s less likely to go wrong. The system is kept fully working after each refactoring, reducing +the chances that a system can get seriously broken during the restructuring. +Objectives: +• Identify and understand Bad Code Smells. +• Apply refactorings to get rid of Bad Code. +Classwork: +• Make sure you have your own feature branch, using “git checkout -b your-feature development”. +• Please follow the feature branch workflow [GitHub flow]. +• Install [sonarlint]. +• Find Code smells in JHotDraw based on your change request and sonarlint (shouldn’t be a +problem). +• Apply one or more suitable Refactoring Patterns to get rid of the bad code smells 1 . +Portfolio Work: +• Describe the code smell that triggered your refactoring, see Chapter 4 in [Ker05]. Describe +what you plan to change by refactoring. Describe the strategy of the refactorings. Which of +the refactorings from [Ker05] did you apply and what was the reasoning behind it? +• Remember to describe the strategies and purpose of the Refactorings. + +1 See http://refactoring.com/catalog/ + +1 + + [ActLab] +Actualization Lab +Jan Corfixen Sørensen +Introduction: The actualization phase consists of the implementation of the new functionality, +its incorporation into the old code, and change propagation that seeks out and updates all places +in the old code that require secondary modification. +Objectives: +• Understand and explain Clean Architecture in context of Actualization +• Understand and explain Clean Code Principles in context of Actualization +Portfolio Work: +• Provide examples of the SOLID principles in context of the CASE study. +• Explain Clean Architecture in context of the CASE Study. +• + +1 + + [ActLab] +Actualization Lab +Jan Corfixen Sørensen +Introduction: The actualization phase consists of the implementation of the new functionality, +its incorporation into the old code, and change propagation that seeks out and updates all places +in the old code that require secondary modification. +Objectives: +• Understand and explain Clean Architecture in context of Actualization +• Understand and explain Clean Code Principles in context of Actualization +Portfolio Work: +• Provide examples of the SOLID principles in context of the CASE study. +• Explain Clean Architecture in context of the CASE Study. +• + +1 + + [TestLab1] +Testing + +Introduction: In computer programming, unit testing is a software testing method by which +individual units of source code—sets of one or more computer program modules together with +associated control data, usage procedures, and operating procedures—are tested to determine +whether they are fit for use. Unit tests are typically automated tests written and run by software +developers to ensure that a section of an application (known as the ”unit”) meets its design and +behaves as intended. In procedural programming, a unit could be an entire module, but it is +more commonly an individual function or procedure. In object-oriented programming, a unit is +often an entire interface, such as a class, but could be an individual method. By writing tests +first for the smallest testable units, then the compound behaviors between those, one can build up +comprehensive tests for complex applications. +Objectives: +• Understand the importance of testing. +• Implement unit tests. +Classwork: +1. Add maven dependency to [JUnit4] if it is not already done. +2. Create JUnit 4 tests for most important domain logic methods of your feature. Note: Swing +and JUnit extensions often works best with JUnit 4. +3. Write JUnit tests for best case scenario +4. Write JUnit tests for identified boundary cases +(a) A unit test should test a single code-path through a single method. When the execution +of a method passes outside of that method, you have a dependency and should apply +mocks/stubs to avoid the dependency, see [mockito.org]. +5. Use JAVA Assertions to test invariants, see [JAVA Asserts]. +(a) Assertions should be used to check something that should never happen +(b) Note, an assertion should stop the program from running, but an exception should let +the program continue running. +Portfolio Work: +• At class level write unit tests of important business functionality of your selected Feature. +Document how you have verified your Feature. + +1 + + [TestLab2] +Behavior Driven Testing + +Introduction – User Stories and BBD +User stories are short and simple descriptions of capabilities written from the perspective of the +person who desires the new capability. “As a [user type], I want [some goal] so that +[some reason].” An alternative includes: “As a [user type], I want [some goal] + +because [why].” +Mapping User Stories to BDD: + +Figure 1: Example of how to map User Story to BDD scenario. + +Portfolio: +• Map your User Stories to BDD Given-When-Then Scenarios +• Use [JGiven] to automate your BDD Scenarios +• For domain specific assertions use the [AssertJ library]. +For Swing applications use the [AssertJ-swing] to automate the Scenarios. + +1 + + \ No newline at end of file diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/ImageFormatRegistryTest.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/ImageFormatRegistryTest.java index 83da0cbf5..5611bc73c 100644 --- a/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/ImageFormatRegistryTest.java +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/ImageFormatRegistryTest.java @@ -8,16 +8,51 @@ package org.jhotdraw.draw.io; import org.jhotdraw.draw.figure.ImageFigure; -import org.junit.Test; +import org.jhotdraw.draw.figure.ImageHolderFigure; +import org.junit.*; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import java.util.List; import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; /** - * Tests for the modular ImageFormatRegistry using JUnit 4 and AssertJ. + * Unit tests for ImageFormatRegistry - supports the user story: + * "As a user, I want to be able to open various formats (PNG, JPEG) + * so I can work on top of my previous work" + * + * Tests use JUnit 4, Mockito for mocking, AssertJ for assertions, + * and Java assertions for invariants. */ public class ImageFormatRegistryTest { + @Mock + private ImageHolderFigure mockPrototype; + + @Mock + private ImageFormatProvider mockProvider; + + private AutoCloseable mockCloseable; + + @BeforeClass + public static void setUpClass() { + // Enable Java assertions for invariant testing + ImageFormatRegistryTest.class.getClassLoader().setDefaultAssertionStatus(true); + } + + @Before + public void setUp() { + mockCloseable = MockitoAnnotations.openMocks(this); + } + + @After + public void tearDown() throws Exception { + mockCloseable.close(); + } + + // ==================== BEST CASE SCENARIO TESTS ==================== + @Test public void testPngFormatSupported() { assertThat(ImageFormatRegistry.isFormatSupported("png")) @@ -36,17 +71,13 @@ public void testJpegFormatSupported() { assertThat(ImageFormatRegistry.isFormatSupported("jpeg")) .as("JPEG format should be supported") .isTrue(); + assertThat(ImageFormatRegistry.isFormatSupported("JPEG")) + .as("JPEG format should be supported (uppercase)") + .isTrue(); } @Test - public void testUnsupportedFormat() { - assertThat(ImageFormatRegistry.isFormatSupported("xyz")) - .as("XYZ format should not be supported") - .isFalse(); - } - - @Test - public void testCreateInputFormats() { + public void testCreateInputFormatsWithRealPrototype() { ImageFigure prototype = new ImageFigure(); List formats = ImageFormatRegistry.createInputFormats(prototype); @@ -70,6 +101,32 @@ public void testCreateOutputFormats() { .hasSizeGreaterThanOrEqualTo(2); } + // ==================== BOUNDARY CASE TESTS ==================== + + @Test + public void testUnsupportedFormat() { + assertThat(ImageFormatRegistry.isFormatSupported("xyz")) + .as("XYZ format should not be supported") + .isFalse(); + } + + @Test + public void testEmptyExtension() { + assertThat(ImageFormatRegistry.isFormatSupported("")) + .as("Empty extension should not be supported") + .isFalse(); + } + + @Test + public void testCaseInsensitiveFormatCheck() { + assertThat(ImageFormatRegistry.isFormatSupported("PnG")) + .as("Format check should be case-insensitive") + .isTrue(); + assertThat(ImageFormatRegistry.isFormatSupported("JpEg")) + .as("Format check should be case-insensitive") + .isTrue(); + } + @Test public void testProviderCount() { List providers = ImageFormatRegistry.getProviders(); @@ -78,24 +135,144 @@ public void testProviderCount() { .as("Providers should not be null") .isNotNull(); assertThat(providers) - .as("Should have at least 2 providers") + .as("Should have at least 2 providers (PNG, JPEG)") .hasSizeGreaterThanOrEqualTo(2); } + // ==================== MOCKITO MOCK TESTS ==================== + @Test - public void testPngProvider() { + public void testCreateInputFormatWithMockedPrototype() { + when(mockPrototype.clone()).thenReturn(mockPrototype); + + List formats = ImageFormatRegistry.createInputFormats(mockPrototype); + + assertThat(formats) + .as("Should create input formats with mocked prototype") + .isNotEmpty(); + } + + @Test + public void testMockedProviderBehavior() { + when(mockProvider.getFormatName()).thenReturn("TEST"); + when(mockProvider.getFileExtensions()).thenReturn(new String[]{"test"}); + when(mockProvider.getMimeTypes()).thenReturn(new String[]{"image/test"}); + when(mockProvider.getDescription()).thenReturn("Test Format"); + + assertThat(mockProvider.getFormatName()).isEqualTo("TEST"); + assertThat(mockProvider.getFileExtensions()).containsExactly("test"); + + verify(mockProvider).getFormatName(); + verify(mockProvider).getFileExtensions(); + } + + @Test + public void testPngProviderCreatesValidInputFormat() { + PngFormatProvider provider = new PngFormatProvider(); + ImageFigure prototype = new ImageFigure(); + + InputFormat inputFormat = provider.createInputFormat(prototype); + + assertThat(inputFormat) + .as("PNG provider should create valid input format") + .isNotNull(); + } + + @Test + public void testJpegProviderCreatesValidInputFormat() { + JpegFormatProvider provider = new JpegFormatProvider(); + ImageFigure prototype = new ImageFigure(); + + InputFormat inputFormat = provider.createInputFormat(prototype); + + assertThat(inputFormat) + .as("JPEG provider should create valid input format") + .isNotNull(); + } + + // ==================== PROVIDER SPECIFIC TESTS ==================== + + @Test + public void testPngProviderProperties() { PngFormatProvider provider = new PngFormatProvider(); assertThat(provider.getFormatName()).isEqualTo("PNG"); - assertThat(provider.getFileExtensions()).isEqualTo(new String[]{"png"}); - assertThat(provider.getMimeTypes()).isEqualTo(new String[]{"image/png"}); + assertThat(provider.getFileExtensions()).containsExactly("png"); + assertThat(provider.getMimeTypes()).containsExactly("image/png"); + assertThat(provider.getDescription()).contains("PNG"); } @Test - public void testJpegProvider() { + public void testJpegProviderProperties() { JpegFormatProvider provider = new JpegFormatProvider(); assertThat(provider.getFormatName()).isEqualTo("JPEG"); - assertThat(provider.getFileExtensions()).isEqualTo(new String[]{"jpg", "jpeg"}); + assertThat(provider.getFileExtensions()).containsExactly("jpg", "jpeg"); + assertThat(provider.getDescription()).contains("JPEG"); + } + + @Test + public void testPngProviderCreatesOutputFormat() { + PngFormatProvider provider = new PngFormatProvider(); + + OutputFormat outputFormat = provider.createOutputFormat(); + + assertThat(outputFormat) + .as("PNG provider should create output format") + .isNotNull(); + } + + @Test + public void testJpegProviderCreatesOutputFormat() { + JpegFormatProvider provider = new JpegFormatProvider(); + + OutputFormat outputFormat = provider.createOutputFormat(); + + assertThat(outputFormat) + .as("JPEG provider should create output format") + .isNotNull(); + } + + // ==================== JAVA ASSERTIONS FOR INVARIANTS ==================== + + @Test + public void testProvidersListInvariant() { + List providers = ImageFormatRegistry.getProviders(); + + assert providers != null : "Providers list should never be null"; + assert !providers.isEmpty() : "Providers list should never be empty after initialization"; + } + + @Test + public void testInputFormatsInvariant() { + ImageFigure prototype = new ImageFigure(); + List formats = ImageFormatRegistry.createInputFormats(prototype); + + assert formats != null : "Input formats list should never be null"; + + for (InputFormat format : formats) { + assert format != null : "Individual input format should never be null"; + } + } + + @Test + public void testOutputFormatsInvariant() { + List formats = ImageFormatRegistry.createOutputFormats(); + + assert formats != null : "Output formats list should never be null"; + + for (OutputFormat format : formats) { + assert format != null : "Individual output format should never be null"; + } + } + + @Test + public void testProviderPropertiesInvariant() { + for (ImageFormatProvider provider : ImageFormatRegistry.getProviders()) { + assert provider.getFormatName() != null : "Format name should never be null"; + assert !provider.getFormatName().isEmpty() : "Format name should never be empty"; + assert provider.getFileExtensions() != null : "File extensions should never be null"; + assert provider.getFileExtensions().length > 0 : "File extensions should not be empty"; + } } } diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/GivenImageFormat.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/GivenImageFormat.java new file mode 100644 index 000000000..5b7f2a330 --- /dev/null +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/GivenImageFormat.java @@ -0,0 +1,49 @@ +package org.jhotdraw.draw.io.bdd; + +import com.tngtech.jgiven.Stage; +import com.tngtech.jgiven.annotation.ScenarioState; +import org.jhotdraw.draw.figure.ImageFigure; + +public class GivenImageFormat extends Stage { + + @ScenarioState + protected ImageFigure prototype; + + @ScenarioState + protected String fileExtension; + + public GivenImageFormat the_image_format_registry_is_initialized() { + prototype = new ImageFigure(); + return self(); + } + + public GivenImageFormat a_png_file_extension() { + fileExtension = "png"; + return self(); + } + + public GivenImageFormat a_jpeg_file_extension() { + fileExtension = "jpeg"; + return self(); + } + + public GivenImageFormat a_jpg_file_extension() { + fileExtension = "jpg"; + return self(); + } + + public GivenImageFormat an_unsupported_file_extension() { + fileExtension = "xyz"; + return self(); + } + + public GivenImageFormat an_uppercase_file_extension(String ext) { + fileExtension = ext.toUpperCase(); + return self(); + } + + public GivenImageFormat a_file_with_extension(String ext) { + fileExtension = ext; + return self(); + } +} diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/ImageFormatBDDTest.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/ImageFormatBDDTest.java new file mode 100644 index 000000000..23b6fb50f --- /dev/null +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/ImageFormatBDDTest.java @@ -0,0 +1,98 @@ +package org.jhotdraw.draw.io.bdd; + +import com.tngtech.jgiven.junit.ScenarioTest; +import org.junit.Test; + +/** + * BDD tests for the user story: + * "As a user, I want to be able to open various formats (PNG, JPEG) + * so I can work on top of my previous work" + */ +public class ImageFormatBDDTest extends ScenarioTest { + + @Test + public void user_can_open_png_image_to_work_on_previous_work() { + given().the_image_format_registry_is_initialized() + .and().a_png_file_extension(); + + when().the_user_opens_an_image_file(); + + then().the_format_should_be_supported() + .and().input_formats_should_be_available() + .and().the_user_can_work_on_the_image(); + } + + @Test + public void user_can_open_jpeg_image_to_work_on_previous_work() { + given().the_image_format_registry_is_initialized() + .and().a_jpeg_file_extension(); + + when().the_user_opens_an_image_file(); + + then().the_format_should_be_supported() + .and().input_formats_should_be_available() + .and().the_user_can_work_on_the_image(); + } + + @Test + public void user_can_open_jpg_image_to_work_on_previous_work() { + given().the_image_format_registry_is_initialized() + .and().a_jpg_file_extension(); + + when().the_user_opens_an_image_file(); + + then().the_format_should_be_supported() + .and().input_formats_should_be_available() + .and().the_user_can_work_on_the_image(); + } + + @Test + public void system_rejects_unsupported_image_format() { + given().the_image_format_registry_is_initialized() + .and().an_unsupported_file_extension(); + + when().the_user_checks_if_format_is_supported(); + + then().the_format_should_not_be_supported(); + } + + @Test + public void png_format_is_recognized_regardless_of_case() { + given().the_image_format_registry_is_initialized() + .and().an_uppercase_file_extension("png"); + + when().the_user_checks_if_format_is_supported(); + + then().the_format_should_be_supported(); + } + + @Test + public void jpeg_format_is_recognized_regardless_of_case() { + given().the_image_format_registry_is_initialized() + .and().an_uppercase_file_extension("jpeg"); + + when().the_user_checks_if_format_is_supported(); + + then().the_format_should_be_supported(); + } + + @Test + public void system_provides_input_formats_for_opening_images() { + given().the_image_format_registry_is_initialized(); + + when().the_user_requests_input_formats(); + + then().input_formats_should_be_available() + .and().at_least_$_input_formats_exist(2); + } + + @Test + public void system_provides_output_formats_for_saving_images() { + given().the_image_format_registry_is_initialized(); + + when().the_user_requests_output_formats(); + + then().output_formats_should_be_available() + .and().at_least_$_output_formats_exist(2); + } +} diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/ThenImageFormatResult.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/ThenImageFormatResult.java new file mode 100644 index 000000000..4b79f8f16 --- /dev/null +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/ThenImageFormatResult.java @@ -0,0 +1,77 @@ +package org.jhotdraw.draw.io.bdd; + +import com.tngtech.jgiven.Stage; +import com.tngtech.jgiven.annotation.ScenarioState; +import org.jhotdraw.draw.io.InputFormat; +import org.jhotdraw.draw.io.OutputFormat; +import java.util.List; + +import static org.assertj.core.api.Assertions.*; + +public class ThenImageFormatResult extends Stage { + + @ScenarioState + protected boolean formatSupported; + + @ScenarioState + protected List inputFormats; + + @ScenarioState + protected List outputFormats; + + public ThenImageFormatResult the_format_should_be_supported() { + assertThat(formatSupported) + .as("Format should be supported") + .isTrue(); + return self(); + } + + public ThenImageFormatResult the_format_should_not_be_supported() { + assertThat(formatSupported) + .as("Format should not be supported") + .isFalse(); + return self(); + } + + public ThenImageFormatResult input_formats_should_be_available() { + assertThat(inputFormats) + .as("Input formats should be available") + .isNotNull() + .isNotEmpty(); + return self(); + } + + public ThenImageFormatResult output_formats_should_be_available() { + assertThat(outputFormats) + .as("Output formats should be available") + .isNotNull() + .isNotEmpty(); + return self(); + } + + public ThenImageFormatResult at_least_$_input_formats_exist(int count) { + assertThat(inputFormats) + .as("Should have at least %d input formats", count) + .hasSizeGreaterThanOrEqualTo(count); + return self(); + } + + public ThenImageFormatResult at_least_$_output_formats_exist(int count) { + assertThat(outputFormats) + .as("Should have at least %d output formats", count) + .hasSizeGreaterThanOrEqualTo(count); + return self(); + } + + public ThenImageFormatResult the_user_can_work_on_the_image() { + assertThat(formatSupported) + .as("User should be able to work on supported format") + .isTrue(); + assertThat(inputFormats) + .as("Input formats should be available for editing") + .isNotNull() + .isNotEmpty(); + return self(); + } +} + diff --git a/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/WhenOpeningImage.java b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/WhenOpeningImage.java new file mode 100644 index 000000000..2ff49eaa4 --- /dev/null +++ b/jhotdraw-core/src/test/java/org/jhotdraw/draw/io/bdd/WhenOpeningImage.java @@ -0,0 +1,51 @@ +package org.jhotdraw.draw.io.bdd; + +import com.tngtech.jgiven.Stage; +import com.tngtech.jgiven.annotation.ScenarioState; +import org.jhotdraw.draw.figure.ImageFigure; +import org.jhotdraw.draw.io.ImageFormatRegistry; +import org.jhotdraw.draw.io.InputFormat; +import org.jhotdraw.draw.io.OutputFormat; +import java.util.List; + +public class WhenOpeningImage extends Stage { + + @ScenarioState + protected ImageFigure prototype; + + @ScenarioState + protected String fileExtension; + + @ScenarioState + protected boolean formatSupported; + + @ScenarioState + protected List inputFormats; + + @ScenarioState + protected List outputFormats; + + public WhenOpeningImage the_user_checks_if_format_is_supported() { + formatSupported = ImageFormatRegistry.isFormatSupported(fileExtension); + return self(); + } + + public WhenOpeningImage the_user_requests_input_formats() { + inputFormats = ImageFormatRegistry.createInputFormats(prototype); + return self(); + } + + public WhenOpeningImage the_user_requests_output_formats() { + outputFormats = ImageFormatRegistry.createOutputFormats(); + return self(); + } + + public WhenOpeningImage the_user_opens_an_image_file() { + formatSupported = ImageFormatRegistry.isFormatSupported(fileExtension); + if (formatSupported) { + inputFormats = ImageFormatRegistry.createInputFormats(prototype); + } + return self(); + } +} +