Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlexibleConfig #2757

Merged
merged 57 commits into from
Apr 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
8fe159f
Add FlexibleConfig, Setting, SettingValue
eviltak Jan 12, 2017
7165875
Add SettingValueValidator (with an impl) and tests
eviltak Jan 12, 2017
b4bc197
RangedNumberValueValidator can remove bounds
eviltak Jan 12, 2017
e1fb7c0
Make FlexibleConfig.get return generic Setting<T>
eviltak Jan 15, 2017
831892b
Add tests for Setting
eviltak Jan 15, 2017
772413a
Fix FlexibleConfig.get, Add FlexibleConfig tests
eviltak Jan 15, 2017
d3001c2
Make FlexibleConfig.Key and Setting use SimpleUri
eviltak Jan 19, 2017
5805d70
Rename SettingValueValidator.isValid to validate
eviltak Jan 19, 2017
fbb5594
Remove Setting setters except setValue
eviltak Jan 19, 2017
308e914
Use SimpleUri as the key type for FlexibleConfig
eviltak Jan 20, 2017
1c157ee
Log warnings when Setting can't be removed
eviltak Jan 20, 2017
1588ce7
Add ctor to Setting, rename to validator
eviltak Jan 20, 2017
3b6db40
Lazy create and delete Setting subscriber list
eviltak Jan 20, 2017
5493584
Fix Setting.hasSubscribers
eviltak Jan 20, 2017
05b3acd
Rename Setting.name to humanReadableName
eviltak Jan 22, 2017
9d7bdef
Rename RangedNumberValueValidator to RangedNumberValidator
eviltak Jan 22, 2017
9664a7f
Make RangedNumberValidator immutable
eviltak Jan 22, 2017
08eef0f
Rename RangedNumberValidator.low, high to min, max
eviltak Jan 22, 2017
60ee10f
Add separate minInclusive and maxInclusive
eviltak Jan 22, 2017
df0325b
Split Setting into interface and implementation
eviltak Jan 22, 2017
d599fea
Split FlexibleConfig into interface and implementation
eviltak Jan 22, 2017
3d580d6
Rename FlexibleConfig.has to contains
eviltak Jan 22, 2017
d1eca9d
Test RangedNumberValidator min and maxInclusive
eviltak Jan 22, 2017
1003fd1
Rename FlexibleConfigTest subclasses
eviltak Jan 24, 2017
a5b547e
Log warnings in FlexibleConfig.add
eviltak Jan 24, 2017
dde4600
Log warning when invalid value is passed to Setting
eviltak Jan 24, 2017
3796563
Add issueWarnings and validateWithWarnings
eviltak Jan 26, 2017
b1d6496
Document RangedValueValidator
eviltak Jan 26, 2017
7d21437
Document Setting
eviltak Jan 26, 2017
16770ee
Document SettingImpl
eviltak Jan 26, 2017
e0a0eae
Document FlexibleConfig, Make add non-generic
eviltak Jan 26, 2017
41fe079
Document FlexibleConfigImpl
eviltak Jan 26, 2017
66115e1
Update SettingImpl documentation
eviltak Jan 31, 2017
90f871a
Make SettingImpl.subscribers a Set
eviltak Jan 31, 2017
3b6946c
Fix Setting subscriber tests
eviltak Jan 31, 2017
a44e2c8
Update Setting documentation
eviltak Feb 18, 2017
f8055f9
Add resetValue method to Setting
eviltak Feb 18, 2017
76f069e
Refactor SettingValueValidator methods
eviltak Feb 18, 2017
aa2db9a
Check if validator is null in SettingImpl.setValue
eviltak Feb 18, 2017
ec49a6a
Make SettingValueValidator an abstract class
eviltak Feb 18, 2017
3a29fb1
Update SettingValueValidator Javadoc
eviltak Feb 18, 2017
e1537ef
Make RangedNumberValidator.issueWarnings protected
eviltak Feb 26, 2017
45207e6
Update FlexibleConfig Javadoc
eviltak Feb 26, 2017
f63cfa2
Update FlexibleConfig tests
eviltak Feb 26, 2017
6f003fa
Log warnings in constructor if SettingImpl default value is invalid
eviltak Mar 18, 2017
a004aa1
Make Setting.subscribe and unsubscribe return operation status
eviltak Mar 18, 2017
0ed410d
Make SettingImpl.id a final field
eviltak Mar 18, 2017
701316f
Add warningFormatString to SettingImpl
eviltak Mar 18, 2017
328e754
Update Setting documentation
eviltak Mar 26, 2017
c92f14f
Refactor Setting tests to improve readability
eviltak Mar 26, 2017
86b2237
Convert SettingValueValidator to interface
eviltak Apr 13, 2017
5038857
Merge branch 'develop' into flexible-config
eviltak Apr 13, 2017
57cf7ab
FlexibleConfigTest formatting improvements
eviltak Apr 13, 2017
f9b1959
Update RangedNumberValidatorTest
eviltak Apr 13, 2017
02132ca
Add newline at end of RangedValueValidatorTest.java
eviltak Apr 13, 2017
165e97d
Rename EPSILON to MAX_ALLOWED_ERROR
eviltak Apr 13, 2017
3090f48
# Executed last requested changes.
emanuele3d Apr 17, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* Copyright 2016 MovingBlocks
*
* 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.
*/
package org.terasology.config.flexible;

import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.terasology.engine.SimpleUri;

import static org.junit.Assert.*;

@RunWith(Enclosed.class)
public class FlexibleConfigTest {
private static final SimpleUri KEY_NON_EXISTENT = new SimpleUri("engine-tests:TestSettingX");

public static class Get {
private FlexibleConfig config;

@Before
public void setUp() throws Exception {
config = new FlexibleConfigImpl();
}

@Test
public void testGet() throws Exception {
SimpleUri id1 = new SimpleUri("engine-tests:TestSetting1");
SimpleUri id2 = new SimpleUri("engine-tests:TestSetting2");

Setting<Integer> expectedSetting1 = new MockSetting<>(id1);
config.add(expectedSetting1);

Setting<Double> expectedSetting2 = new MockSetting<>(id2);
config.add(expectedSetting2);

Setting<Integer> retrievedSetting1 = config.get(id1);
Setting<Double> retrievedSetting2 = config.get(id2);

// We need the references to be equal
assertEquals(expectedSetting1, retrievedSetting1);
assertEquals(expectedSetting2, retrievedSetting2);
}
}

public static class Contains {
private FlexibleConfig config;

@Before
public void setUp() throws Exception {
config = new FlexibleConfigImpl();
}

@Test
public void testContains() throws Exception {
SimpleUri id = new SimpleUri("engine-tests:TestSetting");
config.add(new MockSetting<Integer>(id));

assertTrue(config.contains(id));
}

@Test
public void testNotContains() throws Exception {
SimpleUri id = new SimpleUri("engine-tests:TestSetting");
config.add(new MockSetting<Integer>(id));

assertFalse(config.contains(KEY_NON_EXISTENT));
}
}

public static class Add {
private FlexibleConfig config;

@Before
public void setUp() throws Exception {
config = new FlexibleConfigImpl();
}

@Test
public void testAdd() throws Exception {
SimpleUri id = new SimpleUri("engine-tests:TestSetting");

assertTrue(config.add(new MockSetting(id)));
}

@Test
public void testAddExisting() throws Exception {
SimpleUri id = new SimpleUri("engine-tests:TestSetting");

assertTrue(config.add(new MockSetting<Integer>(id)));
assertFalse(config.add(new MockSetting<Double>(id)));
}
}

public static class Remove {
private FlexibleConfig config;

@Before
public void setUp() throws Exception {
config = new FlexibleConfigImpl();
}

@Test
public void testRemove() throws Exception {
SimpleUri id1 = new SimpleUri("engine-tests:TestSetting1");
SimpleUri id2 = new SimpleUri("engine-tests:TestSetting2");

config.add(new MockSetting(id1));
config.add(new MockSetting(id2));

assertTrue(config.remove(id1));
assertTrue(config.remove(id2));
}

@Test
public void testNonexistentRemove() throws Exception {
SimpleUri id = new SimpleUri("engine-tests:TestSetting");
config.add(new MockSetting(id));

assertFalse(config.remove(KEY_NON_EXISTENT));
}

@Test
public void testSubscribedRemove() throws Exception {
SimpleUri id = new SimpleUri("engine-tests:TestSetting");
Setting setting = new MockSetting(id);
config.add(setting);
setting.subscribe(propertyChangeEvent -> {});

assertFalse(config.remove(id));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2016 MovingBlocks
*
* 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.
*/
package org.terasology.config.flexible;

import org.terasology.config.flexible.validators.SettingValueValidator;
import org.terasology.engine.SimpleUri;

import java.beans.PropertyChangeListener;

class MockSetting<T> implements Setting<T> {
private final SimpleUri id;
private boolean isSubscribedTo = false;

MockSetting(SimpleUri id) {
this.id = id;
}

@Override
public boolean subscribe(PropertyChangeListener changeListener) {
isSubscribedTo = true;
return true;
}

@Override
public boolean unsubscribe(PropertyChangeListener changeListener) {
isSubscribedTo = false;
return false;
}

@Override
public SimpleUri getId() {
return id;
}

@Override
public SettingValueValidator<T> getValidator() {
return null;
}

@Override
public T getDefaultValue() {
return null;
}

@Override
public T getValue() {
return null;
}

@Override
public boolean setValue(T newValue) {
return false;
}

@Override
public String getHumanReadableName() {
return null;
}

@Override
public String getDescription() {
return null;
}

@Override
public boolean hasSubscribers() {
return isSubscribedTo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* Copyright 2016 MovingBlocks
*
* 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.
*/
package org.terasology.config.flexible;

import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.terasology.config.flexible.validators.RangedNumberValidator;
import org.terasology.engine.SimpleUri;
import org.terasology.utilities.random.FastRandom;
import org.terasology.utilities.random.Random;

import java.beans.PropertyChangeListener;

import static org.junit.Assert.*;

@RunWith(Enclosed.class)
public class SettingTest {
private static final SimpleUri SETTING_ID = new SimpleUri("engine-tests:TestSetting");

public static class SetValue {
private Setting<Integer> setting;

private int eventResult;

@Before
public void setUp() {
setting = new SettingImpl<>(SETTING_ID,
50, new RangedNumberValidator<>(0, 100, false, false));

eventResult = -1;

setting.subscribe(propertyChangeEvent -> eventResult = (int) propertyChangeEvent.getNewValue());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe this to me in plain english please? I don't see any flaw in it but I'm not agile with this newish syntax yet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lambdas are equivalent to new anonymous object (with a single method) creation statements, but are much cleaner.

propertyChangeEvent -> eventResult = (int) propertyChangeEvent.getNewValue() evaluates to

new PropertyChangeListener() {
   @Override
   void propertyChange(PropertyChangeEvent propertyChangeEvent) {
       eventResult = (int) propertyChangeEvent.getNewValue();
   }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood, thank you.

}

@Test
public void testSetsValue() {
assertTrue(setting.setValue(25));

assertEquals(25, eventResult);
}

@Test
public void testDoesNotSetValue() {
assertFalse(setting.setValue(101));

assertEquals(-1, eventResult);
}
}

public static class Subscribers {
private Setting<Integer> setting;

private PropertyChangeListener listener;

private int eventCallCount;

@Before
public void setUp() {
setting = new SettingImpl<>(SETTING_ID,
50, new RangedNumberValidator<>(0, 100, false, false));

eventCallCount = 0;

listener = propertyChangeEvent -> eventCallCount++;
}

@Test
public void testHasSubscribers() {
setting.subscribe(listener);

assertTrue(setting.hasSubscribers());

setting.unsubscribe(listener);

assertFalse(setting.hasSubscribers());
}

@Test
public void testSetEventCall() {
setting.subscribe(listener);

Random random = new FastRandom();

final int MAX_SET_VALUE_COUNT = 50;
int expectedEventCallCount = 0;

for (int i = 0; i < MAX_SET_VALUE_COUNT; i++) {
int randomInt = random.nextInt(-50, 150);
expectedEventCallCount += setting.setValue(randomInt) ? 1 : 0;
}

assertEquals(expectedEventCallCount, eventCallCount);
}

@Test
public void testSubscribe() {
final int SUBSCRIBER_COUNT = 10;

for (int i = 0; i < SUBSCRIBER_COUNT; i++) {
setting.subscribe(propertyChangeEvent -> eventCallCount++);
}

setting.setValue(30);

assertEquals(SUBSCRIBER_COUNT, eventCallCount);
}

@Test
public void testUnsubscribe() {
int subscriberCount = 10;

PropertyChangeListener[] listeners = new PropertyChangeListener[subscriberCount];

for (int i = 0; i < subscriberCount; i++) {
listeners[i] = propertyChangeEvent -> eventCallCount++;
setting.subscribe(listeners[i]);
}

for (int i = 0; i < new FastRandom().nextInt(subscriberCount / 2); i++) {
setting.unsubscribe(listeners[i]);
subscriberCount--;
}

setting.setValue(30);

assertEquals(subscriberCount, eventCallCount);
}
}
}
Loading